Mobile SDK

iOS or Android

    SDK Features - Send Navigation

    Info: Stellantis Mobile SDK for ex Groupe PSA brands (Citroën, DS, Peugeot, Opel and Vauxhall) is not publicly available for now.

    Security: Send Navigation require the following security schemes to be valid

    Connectivity: this feature is available usingBluetooth connectivity

    • 👨‍❤️‍👨 The vehicle & the device must be paired with Bluetooth.
    • 🤳🏼 The user must stand inside or close to the vehicle.

    Stellantis Connected Vehicles mobile SDK for ex Groupe PSA brands (Citroën, DS, Peugeot, Opel and Vauxhall) has a dedicated feature to send a navigation to the vehicle from the mobile phone.

    navigation-system

    With this feature, a user of your app is able to send a navigation to the vehicle using Bluetooth connection. When the command is received, the vehicle infotainment system starts with this navigation.

    In order send a navigation to the vehicle, you should first implement the prerequisites:

    • 🔌 Connect the device (only for Android devices).
    • 🏁 Start the SendToNav service.
    • 🔔 Subscribe to Navigation events.

    You will then be able to send a navigation:

    • 📍 Using the coordinates of the destination.
    • 🔗 With a third party link from Apple Maps, Google Maps, Here WeGo (former Nokia maps), Waze & Whats3Words.

    Connect Device (Android) #

    On Android platform, you need first to listen to Bluetooth events in order to connect devices, this feature allows filtering authorized/unauthorized devices. You should create a broadcast receiver for the following values:

    • BluetoothDevice.ACTION_ACL_CONNECTED: if the device name is valid, you should connect the device using pims.vehicle.device with isConnected == true.
    • BluetoothDevice.ACTION_ACL_CONNECTED: if the device name is valid, you should disconnect the device using pims.vehicle.device with isConnected == false, then stop the service with pims.vehicle.service.

    On iOS, this feature does not exist and therefore is not required. You can directly start the service.

    1
    2
    3
    4
    5
    6
    
    pims.set("pims.vehicle.device",
      mapOf( /* parameters */
      Pair("isConnected", "true")
      )
    ) { message -> /* handle message */ }
    
    1
    2
    3
    4
    5
    6
    
    pims.set(api: "pims.vehicle.device", 
      parameters: [
      
      ]
    ) { (message) in /* handle message */ }
    
    1
    2
    3
    4
    5
    6
    
    // representation of the `succeeded` dictionary object message as JSON
    {
      "transactionId": "953cfefb-bc72",
      "status": "SUCCEEDED",
      "result": null
    }
    

    false

    Start Service #

    On Android & iOS, you must start sendToNav service. Without the service activated, it’s not possible to send a navigation to the vehicle:

    1
    2
    3
    4
    5
    6
    
    pims.set("pims.vehicle.service",
      mapOf( /* parameters */
      Pair("action", "start")
      )
    ) { message -> /* handle message */ }
    
    1
    2
    3
    4
    5
    6
    
    pims.set(api: "pims.vehicle.service", 
      parameters: [
      
      ]
    ) { (message) in /* handle message */ }
    
    1
    2
    3
    4
    5
    6
    
    // representation of the `succeeded` dictionary object message as JSON
    {
      "transactionId": "953cfefb-bc72",
      "status": "SUCCEEDED",
      "result": null
    }
    

    false

    When you don’t need the service anymore, you can disconnect the service using the same API with action param set to stop.

    Subscribe to Events #

    Then, you should subscribe to sendToNav events. Doing so, you will receive information cached navigations.

    Events are received in the following conditions:

    • ✅ When a navigation of the cache is successfully send to the vehicle.
    • ❌ When a navigation is deleted from cache.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    /* Subscribe, see unsubscribe below */
    pims.subscribe("pims.vehicle.event",
      mapOf( /* parameters */
      "actionType": "sendToNav"
      )
    ) { message -> /* handle message */ }
    
    /* Unsubscribe */
    pims.unsubscribe( "pims.vehicle.event" /* no params */ )
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    /* Subscribe, see unsubscribe below */
    pims.subscribe(api: "pims.vehicle.event", 
      parameters: [
      Pair("actionType", "sendToNav")
      ]
    ) { (message) in /* handle message */ }
    
    /* Unsubscribe */
    pims.unsubscribe( api: "pims.vehicle.event" /* no params */ )
    
    1
    2
    3
    4
    5
    6
    
    // representation of the `succeeded` dictionary object message as JSON
    {
      "transactionId": "953cfefb-bc72",
      "status": "SUCCEEDED",
      "result": null
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    
    // representation of the `result` dictionary object message as JSON
    {
      "transactionId": "953cfefb-bc72",
      "status": "RESULT",
      "result": {
        "vin": "VR1AB12C3D45678909",
        // If a navigation is successfully sent:
          "location": {
            "latitude": 48.77232,
            "longitude":  2.2151043,
            "address": "Rte de Gisy, 78140 Vélizy-Villacoublay"
          }
        "userid": "user@provider.tld"
        // If a navigation is deleted from cache:
        "message": "Some locations have been removed."
      }
    }
    

    false

    Send with Coordinates #

    To send a navigation to the vehicle using coordinates, you have to provide longitude and latitude in the request.

    If everything went fine, you would receive "status": "sent" in the response, otherwise check Vehicle Not Reachable.

    Info: sending a destination doesn’t work if the privacy of the vehicle is not open to geolocation (set to none), see pims.vehicle.privacy.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    pims.set("pims.vehicle.destination",
      mapOf( /* parameters */
      Pair("action", "coordinate"),
      Pair("vin", "VR1AB12C3D45678909"),
      Pair("preserve", true),
      Pair("location", mapOf( 
        Pair("latitude", "48.77232"),
        Pair("longitude", "2.2151043")
      )
      )
    ) { message -> /* handle message */ }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    pims.set(api: "pims.vehicle.destination", 
      parameters: [
      "action": "coordinate",
      "vin": "VR1AB12C3D45678909",
      "preserve": true,
      "location": [
        "latitude", "48.77232",
        "longitude", "2.2151043"
      ]
      ]
    ) { (message) in /* handle message */ }
    
    1
    2
    3
    4
    5
    6
    7
    8
    
    // representation of the `succeeded` dictionary object message as JSON
    {
      "transactionId": "953cfefb-bc72",
      "status": "SUCCEEDED",
      "result": {
        "status": "Sent"
      }
    }
    

    false

    You can also send a navigation to the vehicle using extension method, this feature allows sending a navigation using a third party application link.

    This feature is known as Share Intent for Android or Share Extension for iOS. Compatible third parties are Apple Maps, Google Maps, Here WeGo (former Nokia maps), Waze & Whats3Words.

    If everything went fine, you would receive "status": "sent" in the response, otherwise check Vehicle Not Reachable.

    Info: sending a destination doesn’t work if the privacy of the vehicle is not open to geolocation (set to none), see pims.vehicle.privacy.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    pims.set("pims.vehicle.destination",
      mapOf( /* parameters */
      Pair("action", "extension"),
      Pair("vin", "VR1AB12C3D45678909"),
      Pair("preserve", true),
      Pair("extensionInformation", "https://goo.gl/maps/8VPNW6yTfHgPPqb16")
      )
    ) { message -> /* handle message */ }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    pims.set(api: "pims.vehicle.destination", 
      parameters: [
      "action": "extension",
      "vin": "VR1AB12C3D45678909",
      "preserve": true,
      "extensionInformation": "https://goo.gl/maps/8VPNW6yTfHgPPqb16"
      ]
    ) { (message) in /* handle message */ }
    
    1
    2
    3
    4
    5
    6
    7
    8
    
    // representation of the `succeeded` dictionary object message as JSON
    {
      "transactionId": "953cfefb-bc72",
      "status": "SUCCEEDED",
      "result": {
        "status": "sent"
      }
    }
    

    false

    Sending Navigation Failed #

    When a navigation is not successfully started in the vehicle infotainment system, the error message looks like this:

    SET | pims.vehicle.destination
    1
    2
    3
    4
    5
    6
    
    pims.set("pims.vehicle.destination",
      mapOf( /* parameters */
      
      )
    ) { message -> /* handle message */ }
    
    1
    2
    3
    4
    5
    6
    
    pims.set(api: "pims.vehicle.destination", 
      parameters: [
      
      ]
    ) { (message) in /* handle message */ }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    // representation of the `succeeded` dictionary object message as JSON
    {
      "transactionId": "953cfefb-bc72",
      "status": "SUCCEEDED",
      "result": {
        "status": "stored"
        "reason": "GEOLOC_PRIVATE" /* or */ "FULL_PRIVATE"
      }
    }
    

    false

    The reason field will return the reason why the destination has not been sent to the vehicle.

    Depending on the query params preserve, the navigation could be sent again, see vehicle not reachable

    Vehicle Not Reachable #

    If a navigation can not be sent in the vehicle infotainment system, the SDK will react according to the value of parameter preserve of the query:

    • 💾 Cached: In case preserve == true, the navigation is stored during 24 hours in the SDK cache. Each time the device connects to the vehicle with Bluetooth, the SDK will attempt to re-send the navigation. After 24 hours, the navigation is removed from cache. You will be informed through pims.vehicle.event when the navigation is successfully sent or when it’s deleted from cache.
    • 🗑 Deleted: Otherwise, in case preserve == false, the navigation is deleted right away and never stored in cache.

    Only one destinsation is stored for one VIN. If a destination is already stored and a new destination can not be send, the second destination will replace the previous navigation.

    Retrieve Stored Destinations

    When you send a destination, but the vehicle is not reachable, the navigation is stored in cache. It’s possible to use the following API to retrieve a list of stored destinations.

    When a navigation is cached, it will be re-send again each time the device connects to the vehicle.

    1
    2
    3
    
    pims.get("pims.vehicle.destinations"
    ) { message -> /* handle message */ }
    
    1
    2
    3
    
    pims.get(api: "pims.vehicle.destinations"
    ) { (message) in /* handle message */ }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    
    // representation of the `succeeded` dictionary object message as JSON
    {
      "transactionId": "953cfefb-bc72",
      "status": "SUCCEEDED",
      "result": {
          "destination": [
            // First Destination
            {
              "vin": "VR1AB12C3D45678909",
              "userid": "user@provider.tld"
              "location": {
                "latitude": "trustedPhone",
                "longitude": "2.2151043",
                "address": "Rte de Gisy, 78140 Vélizy-Villacoublay"
              }
            },
            // Second Destination
            {
              "vin": "VR2AB12C3D45678909",
              "userid": "otheruser@provider.tld"
              "location": {
                "latitude": "37.32772",
                "longitude": "12.0432151",
                "address": "Rte de Gisy, 78140 Vélizy-Villacoublay"
              }
            },
          ]
        }
    }
    

    false

    Info: Destinations are only stored during 24 hours, then they are deleted.

    Receive Navigation deleted from cache

    After 24 hours a navigation in cache is deleted. If you had subscibed to [pims.vehicle.event - sendToNav] you’ll receive this kind of response:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    /* Subscribe, see unsubscribe below */
    pims.subscribe("pims.vehicle.event",
      mapOf( /* parameters */
      Pair("action", "sendToNav")
      )
    ) { message -> /* handle message */ }
    
    /* Unsubscribe */
    pims.unsubscribe( "pims.vehicle.event" /* no params */ )
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    /* Subscribe, see unsubscribe below */
    pims.subscribe(api: "pims.vehicle.event", 
      parameters: [
      "action": "sendToNav"
      ]
    ) { (message) in /* handle message */ }
    
    /* Unsubscribe */
    pims.unsubscribe( api: "pims.vehicle.event" /* no params */ )
    
    1
    2
    3
    4
    5
    6
    
    // representation of the `succeeded` dictionary object message as JSON
    {
      "transactionId": "953cfefb-bc72",
      "status": "SUCCEEDED",
      "result": null
    }
    
    1
    2
    3
    4
    5
    6
    
    // representation of the `result` dictionary object message as JSON
    {
      "transactionId": "953cfefb-bc72",
      "status": "RESULT",
      "result": 
    }
    

    false

    Extension to Coordinates #

    If you want to convert a third party link to coordinates, you can use the following API:

    1
    2
    3
    4
    5
    6
    
    pims.get("pims.vehicle.coordinate",
      mapOf( /* parameters */
      Pair("extensionInformation", "https://goo.gl/maps/8VPNW6yTfHgPPqb16 ")
      )
    ) { message -> /* handle message */ }
    
    1
    2
    3
    4
    5
    6
    
    pims.get(api: "pims.vehicle.coordinate", 
      parameters: [
      "extensionInformation": "https://goo.gl/maps/8VPNW6yTfHgPPqb16 "
      ]
    ) { (message) in /* handle message */ }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
    // representation of the `succeeded` dictionary object message as JSON
    {
      "transactionId": "953cfefb-bc72",
      "status": "SUCCEEDED",
      "result": {
        "location": {
            "latitude": 48.77232,
            "longitude":  2.2151043,
            // depending on the provided information
            // the response could also contain address
            "address": "Rte de Gisy, 78140 Vélizy-Villacoublay"
        }
      }
    }
    

    false