Guides Android Documentation Installation · Compiling with Gradle Introduction Each SDL Android...

Post on 16-Oct-2020

138 views 0 download

Transcript of Guides Android Documentation Installation · Compiling with Gradle Introduction Each SDL Android...

Guides Android DocumentationDocument current as of 02/20/2018 10:28 AM.

Installation

Download the latest release from GitHub

Extract the source code from the archive

Import the code in the top level sdl_android folder as a module in Android

Studio:

1. Click File -> New -> Import Module... -> Choose the location of

sdl_android as your Source Directory2. The module name will automatically be set to sdl_android, change this as

desired. Click Next and then Finish

The sdl_android library is now a module in your Android Studio project, but it

needs to be added as a dependency to your application. Add the following to

the gradle dependencies of your project:

SOURCE

dependencies { compile project(path: ':sdl_android')}

To compile with the a release of SDL Android, include the following in your app's

build.gradle file,

The list of releases can be found here.

Getting Started on Android

In this guide, we exclusively use Android Studio. We are going to set-up a bare-

bones application so you get started using SDL.

GRADLE

repositories { jcenter()}dependencies { compile 'com.smartdevicelink:sdl_android:4.+'}

N O T E

For more information, see the Compiling With Gradle guide.

Required System Permissions

In the AndroidManifest for our sample project we need to ensure we have the

following system permissions:

• Internet - Used by the mobile library to communicate with a SDL Server• Bluetooth - Primary transport for SDL communication between the device

and the vehicle's head-unit• Access Network State - Required to check if WiFi is enabled on the device

N O T E

The SDL Mobile library for supports Android 2.2.x (API Level 8) or

higher.

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.company.mySdlApplication">

...

<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.BLUETOOTH"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

...

</manifest>

SmartDeviceLink Service

A SmartDeviceLink Android Service should be created to manage the lifecycle

of an SDL Proxy. The SDL Service enables auto-start by creating the SDL Proxy,

which then waits for a connection from SDL. This file also sends and receives

messages to and from SDL after connected.

Create a new service and name it appropriately, for this guide we are going to

call it SdlService . This service must implement the IProxyListenerALM

interface:

The IProxyListenerALM interface has most of the callbacks you will receive

during the SDL proxy's lifecycle. This includes callbacks for RPC responses.

If you created the service using the Android Studio template then the service

should have been added to your AndroidManifest.xml otherwise the service

needs to be defined in the manifest:

public class SdlService extends Service implements IProxyListenerALM { // Inherited methods from IProxyListenerALM}

Implementing SDL Proxy Lifecycle

In order to correctly use a proxy developers need to implement methods for the

proper creation and disposing of an SDL Proxy in our SDLService.

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.company.mySdlApplication">

<application>

...

<service android:name=".SdlService" android:enabled="true"/>

</application>

...

</manifest>

N O T E

An instance of SdlProxy cannot be reused after it is closed and

properly disposed of. Instead, a new instance must be created.

Only one instance of SdlProxy should be in use at any given time.

public class SdlService extends Service implements IProxyListenerALM {

//The proxy handles communication between the application and SDL private SdlProxyALM proxy = null;

//...

@Override public int onStartCommand(Intent intent, int flags, int startId) { boolean forceConnect = intent !=null && intent.getBooleanExtra(TransportConstants.FORCE_TRANSPORT_CONNECTED, false); if (proxy == null) { try { //Create a new proxy using Bluetooth transport //The listener, app name, //whether or not it is a media app and the applicationId are supplied. proxy = new SdlProxyALM(this.getBaseContext(),this, "Hello SDL App", true, "8675309"); } catch (SdlException e) { //There was an error creating the proxy if (proxy == null) { //Stop the SdlService stopSelf(); } } }else if(forceConnect){ proxy.forceOnConnected(); }

//use START_STICKY because we want the SDLService to be explicitly started and stopped as needed. return START_STICKY; }

@Override public void onDestroy() { //Dispose of the proxy if (proxy != null) { try { proxy.dispose(); } catch (SdlException e) { e.printStackTrace(); } finally { proxy = null; } }

onProxyClosed() is called whenever the proxy detects some disconnect in the

connection, whether initiated by the app, by SDL, or by the device’s bluetooth

connection. As long as the exception does not equal Sdl_PROXY_CYCLED or

BLUETOOTH_DISABLED, the proxy would be reset for the exception

SDL_PROXY_DISPOSED.

SmartDeviceLink Router Service

The SdlRouterService will listen for a bluetooth connection with an SDL enabled

module. When a connection happens, it will alert all SDL enabled apps that a

connection has been established and they should start their SDL services.

We must implement a local copy of the SdlRouterService into our project. The

class doesn't need any modification, it's just important that we include it. We

super.onDestroy(); }

@Override public void onProxyClosed(String info, Exception e, SdlDisconnectedReason reason) { //Stop the service stopSelf(); }

//...

}

N O T E

We must properly dispose of our proxy in the onDestroy() method

because SDL will issue an error that it lost connection with the app

if the connection fails before calling proxy.dispose() .

will extend the com.smartdevicelink.transport.SdlRouterService in our class

named SdlRouterService :

N O T E

Do not include an import for

com.smartdevicelink.transport.SdlRouterService . Otherwise, we

will get an error for 'SdlRouterService' is already defined in this

compilation unit .

public class SdlRouterService extends com.smartdevicelink.transport.SdlRouterService {//Nothing to do here}

M U S T

The local extension of the

com.smartdevicelink.transport.SdlRouterService must be named

SdlRouterService .

M U S T

Make sure this local class (SdlRouterService.java) is in the same

package of SdlReceiver.java (described below)

If you created the service using the Android Studio template then the service

should have been added to your AndroidManifest.xml otherwise the service

needs to be added in the manifest. Because we want our service to be seen by

other SDL enabled apps, we need to set android:exported="true" . The system

may issue a lint warning because of this, so we can suppress that using

tools:ignore="ExportedService" . Once added, it should be defined like below:

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.company.mySdlApplication">

<application>

...

<service android:name="com.company.mySdlApplication.SdlRouterService" android:exported="true" android:process="com.smartdevicelink.router" tools:ignore="ExportedService"> </service>

</application>

...

</manifest>

M U S T

The SdlRouterService must be placed in a separate process with

the name com.smartdevicelink.router . If it is not in that process

during it's start up it will stop itself.

SmartDeviceLink Broadcast Receiver

The Android implementation of the SdlProxy relies heavily on the OS's

bluetooth intents. When the phone is connected to SDL, the app needs to

create a SdlProxy, which publishes an SDP record for SDL to connect to. As

mentioned previously, a SdlProxy cannot be re-used. When a disconnect

between the app and SDL occurs, the current proxy must be disposed of and a

new one created.

The SDL Android library has a custom broadcast receiver named

SdlBroadcastReceiver that should be used as the base for your

BroadcastReceiver. It is a child class of Android's BroadcastReceiver so all

normal flow and attributes will be available. Two abstract methods will be

automatically populate the class, we will fill them out soon.

Create a new SdlBroadcastReceiver and name it appropriately, for this guide we

are going to call it SdlReceiver :

public class SdlReceiver extends SdlBroadcastReceiver {

@Override public void onSdlEnabled(Context context, Intent intent) { //...

}

@Override public Class<? extends SdlRouterService> defineLocalSdlRouterClass() { //... }}

If you created the BroadcastReceiver using the Android Studio template then

the service should have been added to your AndroidManifest.xml otherwise

the receiver needs to be defined in the manifest. Regardless, the manifest

needs to be edited so that the SdlBroadcastReceiver needs to respond to the

following intents:

• android.bluetooth.device.action.ACL_CONNECTED• android.bluetooth.device.action.ACL_DISCONNECTED• android.bluetooth.adapter.action.STATE_CHANGED• android.media.AUDIO_BECOMING_NOISY• sdl.router.startservice

M U S T

SdlBroadcastReceiver must call super if onReceive is overridden

@Override public void onReceive(Context context, Intent intent) { super.onReceive(context, intent); //your code here }

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.company.mySdlApplication">

<application>

...

<receiver android:name=".SdlReceiver" android:exported="true" android:enabled="true">

<intent-filter> <action android:name="android.bluetooth.device.action.ACL_CONNECTED" /> <action android:name="android.bluetooth.device.action.ACL_DISCONNECTED"/> <action android:name="android.bluetooth.adapter.action.STATE_CHANGED"/> <action android:name="android.media.AUDIO_BECOMING_NOISY" /> <action android:name="sdl.router.startservice" /> </intent-filter>

</receiver>

</application>

...

</manifest>

N O T E

The intent sdl.router.startservice is a custom intent that will come

from the SdlRouterService to tell us that we have just connected to

an SDL enabled piece of hardware.

Next, we want to make sure we supply our instance of the SdlBroadcastService

with our local copy of the SdlRouterService. We do this by simply returning the

class object in the method defineLocalSdlRouterClass:

We want to start the SDL Proxy when an SDL connection is made via the

SdlRouterService . We do this by taking action in the onSdlEnabled method:

M U S T

SdlBroadcastReceiver has to be exported, or it will not work

correctly

public class SdlReceiver extends SdlBroadcastReceiver { @Override public void onSdlEnabled(Context context, Intent intent) { //.. }

@Override public Class<? extends SdlRouterService> defineLocalSdlRouterClass() { //Return a local copy of the SdlRouterService located in your project return com.company.mySdlApplication.SdlRouterService.class; }}

Main Activity

Now that the basic connection infrastructure is in place, we should add

methods to start the SdlService when our application starts. In onCreate() in

your main activity, you need to call a method that will check to see if there is

currently an SDL connection made. If there is one, the onSdlEnabled method

will be called and we will follow the flow we already set up. In our

MainActivity.java we need to check for an SDL connection:

public class SdlReceiver extends SdlBroadcastReceiver {

@Override public void onSdlEnabled(Context context, Intent intent) { //Use the provided intent but set the class to the SdlService intent.setClass(context, SdlService.class); context.startService(intent);

}

@Override public Class<? extends SdlRouterService> defineLocalSdlRouterClass() { //Return a local copy of the SdlRouterService located in your project return com.company.mySdlApplication.SdlRouterService.class; }}

N O T E

The onSdlEnabled method will be the main start point for our SDL

connection session. We define exactly what we want to happen

when we find out we are connected to SDL enabled hardware.

Implementing IProxyListenerALM Methods

In our SdlService , the onONHMIStatus() method is where you should control

your application with SDL various HMI Statuses. When you receive the first

HMI_FULL, you should initialize your app on SDL by subscribing to buttons,

registering addcommands, sending an initial show or speak command, etc.

public class MainActivity extends Activity {

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);

//If we are connected to a module we want to start our SdlService SdlReceiver.queryForConnectedService(this); }}

ONONHMISTATUS()

Compiling with Gradle

Introduction

Each SDL Android library release is published to JCenter. By adding a few lines

in their app's gradle script, developers can compile with the latest SDL Android

release.

To gain access to the JCenter repository, make sure your app's build.gradle file

includes the following:

@Overridepublic void onOnHMIStatus(OnHMIStatus notification) {

switch(notification.getHmiLevel()) { case HMI_FULL: //send welcome message, addcommands, subscribe to buttons ect break; case HMI_LIMITED: break; case HMI_BACKGROUND: break; case HMI_NONE: break; default: return; }}

repositories { jcenter()}

Gradle Build

To compile with the a release of SDL Android, include the following line in your

app's build.gradle file,

and replace {version} with the desired release version in format of x.x.x .

The list of releases can be found here.

Examples

To compile release 4.4.0, use the following line:

To compile the latest minor release of major version 4, use:

dependencies { compile 'com.smartdevicelink:sdl_android:{version}'}

dependencies { compile 'com.smartdevicelink:sdl_android:4.4.0'}

dependencies { compile 'com.smartdevicelink:sdl_android:4.+'}

Upgrading To Multiplexing

Upgrading apps to utilize the new multiplexing transport flow will require us to

do a few steps. This guide will assume the SDL library is already integrated into

the app.

We will make changes to:

• SdlService• SdlRouterService (new)• SdlBroadcastReceiver• MainActivity

SmartDeviceLink Service

The SmartDeviceLink proxy object instantiation needs to change to the new

constructor. We also need to check for a boolean extra supplied through the

intent that started the service.

The old instantiation should look similar to this:

The new constructor should look like this

proxy = new SdlProxyALM(this, APP_NAME, true, APP_ID);

Notice we now gather the extra boolean from the intent and add to our if-else

statement. If the proxy is not null, we need to check if the supplied boolean

extra is true and if so, take action.

public class SdlService extends Service implements IProxyListenerALM {

//...

@Override public int onStartCommand(Intent intent, int flags, int startId) { boolean forceConnect = intent !=null && intent.getBooleanExtra(TransportConstants.FORCE_TRANSPORT_CONNECTED, false); if (proxy == null) { try { //Create a new proxy using Bluetooth transport //The listener, app name, //whether or not it is a media app and the applicationId are supplied. proxy = new SdlProxyALM(this.getBaseContext(),this, APP_NAME, true, APP_ID); } catch (SdlException e) { //There was an error creating the proxy if (proxy == null) { //Stop the SdlService stopSelf(); } } }else if(forceConnect){ proxy.forceOnConnected(); }

//use START_STICKY because we want the SDLService to be explicitly started and stopped as needed. return START_STICKY; }

if (proxy == null) { //... }else if(forceConnect){ proxy.forceOnConnected(); }

SmartDeviceLink Router Service (New)

The SdlRouterService will listen for a bluetooth connection with an SDL enabled

module. When a connection happens, it will alert all SDL enabled apps that a

connection has been established and they should start their SDL services.

We must implement a local copy of the SdlRouterService into our project. The

class doesn't need any modification, it's just important that we include it. We

will extend the com.smartdevicelink.transport.SdlRouterService in our class

named SdlRouterService :

N O T E

Do not include an import for

com.smartdevicelink.transport.SdlRouterService . Otherwise, we

will get an error for 'SdlRouterService' is already defined in this

compilation unit .

public class SdlRouterService extends com.smartdevicelink.transport.SdlRouterService {//Nothing to do here}

If you created the service using the Android Studio template then the service

should have been added to your AndroidManifest.xml otherwise the service

needs to be added in the manifest. Because we want our service to be seen by

other SDL enabled apps, we need to set android:exported="true" . The system

may issue a lint warning because of this, so we can suppress that using

tools:ignore="ExportedService" . Once added, it should be defined like below:

M U S T

The local extension of the

com.smartdevicelink.transport.SdlRouterService must be named

SdlRouterService .

M U S T

Make sure this local class (SdlRouterService.java) is in the same

package of SdlReceiver.java (described below)

SmartDeviceLink Broadcast Receiver

The SmartDeviceLink Android Library now includes a base BroadcastReceiver

that needs to be used. It's called SdlBroadcastReceiver . Our old

BroadcastReceiver will just need to extend this class instead of the Android

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.company.mySdlApplication">

<application>

...

<service android:name="com.company.mySdlApplication.SdlRouterService" android:exported="true" android:process="com.smartdevicelink.router" tools:ignore="ExportedService"> </service>

</application>

...

</manifest>

M U S T

The SdlRouterService must be placed in a separate process with

the name com.smartdevicelink.router . If it is not in that process

during it's start up it will stop itself.

BroadcastReceiver. Two abstract methods will be automatically populate the

class, we will fill them out soon.

Next, we want to make sure we supply our instance of the SdlBroadcastService

with our local copy of the SdlRouterService. We do this by simply returning the

class object in the method defineLocalSdlRouterClass:

We want to start the SDL Proxy when an SDL connection is made via the

SdlRouterService . This is likely code included on the onReceive method call

previously. We do this by taking action in the onSdlEnabled method:

public class SdlReceiver extends SdlBroadcastReceiver {

@Override public void onSdlEnabled(Context context, Intent intent) {...}

@Override public Class<? extends SdlRouterService> defineLocalSdlRouterClass() {...}

}

public Class<? extends SdlRouterService> defineLocalSdlRouterClass() { //Return a local copy of the SdlRouterService located in your project return com.company.mySdlApplication.SdlRouterService.class; }

N O T E

The actual package definition for the SdlRouterService might be

different. Just make sure to return your local copy and not the class

object from the library itself.

public class SdlReceiver extends SdlBroadcastReceiver {

@Override public void onSdlEnabled(Context context, Intent intent) { //Use the provided intent but set the class to the SdlService intent.setClass(context, SdlService.class); context.startService(intent);

}

@Override public Class<? extends SdlRouterService> defineLocalSdlRouterClass() { //Return a local copy of the SdlRouterService located in your project. return com.company.mySdlApplication.SdlRouterService.class; }}

N O T E

The onSdlEnabled method will be the main start point for our SDL

connection session. We define exactly what we want to happen

when we find out we are connected to SDL enabled hardware.

Now we need to add two extra intent actions to or our intent filter for the

SdlBroadcastReceiver:

• android.bluetooth.adapter.action.STATE_CHANGED• sdl.router.startservice

M U S T

SdlBroadcastReceiver must call super if onReceive is overridden

@Override public void onReceive(Context context, Intent intent) { super.onReceive(context, intent); //your code here }

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.company.mySdlApplication">

<application>

...

<receiver android:name=".SdlReceiver" android:exported="true" android:enabled="true">

<intent-filter> <action android:name="android.bluetooth.device.action.ACL_CONNECTED" /> <action android:name="android.bluetooth.device.action.ACL_DISCONNECTED"/> <action android:name="android.bluetooth.adapter.action.STATE_CHANGED"/> <action android:name="android.media.AUDIO_BECOMING_NOISY" /> <action android:name="sdl.router.startservice" /> </intent-filter>

</receiver>

</application>

...

</manifest>

M U S T

SdlBroadcastReceiver has to be exported, or it will not work

correctly

Main Activity

Our previous MainActivity class probably looked similar to this:

However now instead of starting the service every time we launch the

application we can do a query that will let us know if we are connected to SDL

enabled hardware or not. If we are, the onSdlEnabled method in our

SdlBroadcastReceiver will be called and the proper flow should start. We do this

by removing the intent creation and startService call and instead replace them

with a single call to SdlReceiver.queryForConnectedService(Context) .

public class MainActivity extends Activity {

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);

// Start the SDLService Intent sdlServiceIntent = new Intent(this, SdlService.class); startService(sdlServiceIntent); }}

public class MainActivity extends Activity {

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);

//If we are connected to a module we want to start our SdlService SdlReceiver.queryForConnectedService(this); }}

Using Android Open Accessory Protocol

Incorporating AOA into an SDL-enabled app allows it to communicate to a

module over USB. This guide will assume the SDL library is already integrated

into the app. This guide also requires you to have implement a local

SdlBroadcastReceiver as outlined in the Bluetooth Multiplexing

documentation.

Prerequisites:

• SdlReceiver

We will add or make changes to:

• Android Manifest (of your app)• Accessory Filter (new)• SdlService

Prerequisites

If you have already implemented the Multiplexing guidelines in your project,

feel free to skip this section.

SdlReceiver

Create your own SdlReceiver that extends SdlBroadcastReceiver and

implement the following:

and add the Receiver to your app's Android Manifest with the following intent

filters:

public class SdlReceiver extends com.smartdevicelink.SdlBroadcastReceiver {

@Override public void onSdlEnabled(Context context, Intent intent) { //Use the provided intent but set the class to your SdlService intent.setClass(context, SdlService.class); context.startService(intent); }

@Override public Class<? extends SdlRouterService> defineLocalSdlRouterClass() { return null; //Since we use AOA, we will not be using multiplexing }

@Override public void onReceive(Context context, Intent intent){ super.onReceive(context, intent); //Your code }}

<receiver android:name="com.company.mySdlApplication.SdlReceiver" android:exported="true" android:enabled="true" >

<intent-filter> <action android:name="sdl.router.startservice" /> </intent-filter>

</receiver>

Android Manifest

To use the AOA protocol, you must specify so in your app's Manifest with:

The SDL Android library houses a USBAccessoryAttachmentActivity that you

need to add between your Manifest's <application>…</application> tags:

<uses-feature android:name="android.hardware.usb.accessory"/>

M U S T

This feature will not work without including this line!

<activity android:name="com.smartdevicelink.transport.USBAccessoryAttachmentActivity" android:launchMode="singleTop"> <intent-filter> <action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" /> </intent-filter>

<meta-data android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" android:resource="@xml/accessory_filter" /></activity>

For AOA, your project's local SdlReceiver needs an intent filter for

com.smartdevicelink.USB_ACCESSORY_ATTACHED .

Accessory Filter (New)

For security purposes, an accessory filter will limit accessory connections to

those included in the filter. Add the directory /res/xml to your project and

create a new XML file accessory_filter.xml inside of it. Add in the following to

accessory_filter.xml :

<receiver android:name="com.company.mySdlApplication.SdlReceiver" android:exported="true" android:enabled="true" > <intent-filter> <action android:name="com.smartdevicelink.USB_ACCESSORY_ATTACHED"/> <!--For AOA --> <action android:name="sdl.router.startservice" /> </intent-filter></receiver>

<?xml version="1.0" encoding="utf-8"?><resource> <usb-accessory manufacturer="SDL" model="Core" version="1.0"/></resource>

SmartDeviceLink Service

When using AOA, the USB Transport instantiation is dependent on an accessory

device actually being connected. The following changes need to be made in the

onStartCommand() function of your SdlService.

AOA is only supported on devices with API level 12 or higher. You can check for

this with:

You also need to check that the intent that started your service has an Extra

equal to UsbManager.EXTRA_ACCESSORY :

if(android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.HONEYCOMB){ // create USB transport}else{ Log.e("SdlService", "Unable to start proxy. Android OS version is too low"); // optional}

N O T E

It's recommended to either check for an API level 12 or higher here

or specify an API level 12 or higher in your app's Manifest.

Finally, we can create a new USBTransport with:

And our final result is:

if(android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.HONEYCOMB){ if(intent!=null && intent.hasExtra(UsbManager.EXTRA_ACCESSORY)) { // create USB transport }}else{ Log.e("SdlService", "Unable to start proxy. Android OS version is too low"); // optional}

transport = new USBTransportConfig(getBaseContext(), (UsbAccessory) intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY), false, false);

public int onStartCommand(Intent intent, int flags, int startId) { boolean forceConnect = intent !=null && intent.getBooleanExtra(TransportConstants.FORCE_TRANSPORT_CONNECTED, false); if (proxy == null) { try { BaseTransportConfig transport = null;

if(android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.HONEYCOMB){ if(intent!=null && intent.hasExtra(UsbManager.EXTRA_ACCESSORY)) { transport = new USBTransportConfig(getBaseContext(), (UsbAccessory) intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY), false, false); // create USB transport } }else{ Log.e("SdlService", "Unable to start proxy. Android OS version is too low"); // optional }

if(transport != null){ proxy = new SdlProxyALM(this, APP_NAME, true, APP_ID, transport); }

} catch (SdlException e) { //There was an error creating the proxy if (proxy == null) { //Stop the SdlService stopSelf(); } } }else if(forceConnect){ proxy.forceOnConnected(); }

//use START_STICKY because we want the SDLService to be explicitly started and stopped as needed. return START_STICKY;}

Hello SDL Android

Introduction

In this guide we take you through the steps to get our sample project, Hello Sdl

Android, running and connected to Sdl Core as well as showing up on the

generic HMI.

First, make sure you download or clone the latest release from GitHub.

Open the project in Android Studio. We will exclusively use Android Studio as it

is the current supported platform for Android development.

Getting Started

If you are not using a Ford TDK for development, we will assume that you have

SDL Core (We recommend Ubuntu 16.04) and an HMI set up prior to this point.

Most people getting started with this tutorial will not have a Ford TDK, so

sample outputs will be using Sdl Core and our Generic HMI.

If you don't want to set up a virtual machine for testing, we offer Manticore,

which is a free service that allows you to test your apps via TCP/IP in the cloud.

N O T E

The SDL Android Library is set up to use sdl_android with Gradle.

When you clone the repository, perform a Gradle sync.

Hello Sdl Android has been built with different build flavors.

To access the Build Variant menu to choose your flavor, click on the menu

Build then Select Build Variant . A small window will appear on the bottom

left of your IDE window that allows you to choose a flavor.

There are many flavors to choose from and for now we will only be concerned

with the debug versions.

Versions Include:

• lbt - Legacy Bluetooth• mbt - Multiplexing Bluetooth• tcp - Transmission Control Protocol• usb - Universal Serial Bus

We will mainly be dealing with mbt (if using a TDK) or tcp (if connecting to SDL

Core via a virtual machine or your localhost)

N O T E

Sdl Core and an HMI or Manticore are needed to run Hello Sdl

Android and to ensure that it connects

BUILD FLAVORS

Transports

If you aren't using a TDK or head unit, you can connect to SDL core via a virtual

machine or to your localhost. To do this we will use the flavor tcpDebug .

For TCP to work, you will have to know the IP address of your machine that is

running Sdl Core. If you don't know what it is, running ifconfig in a linux

terminal will usually let you see it for the interface you are connected with to

your network. We have to modify the IP address in Hello Sdl Android to let it

know where your instance of Sdl Core is running.

In the main Java folder of Hello Sdl Android, open up SdlService.java

In the top of this file, locate the variable declaration for

DEV_MACHINE_IP_ADDRESS . Change it to your Sdl Core's IP. Leave the

TCP_PORT set to 12345 .

CONFIGURE FOR TCP

// TCP/IP transport config private static final int TCP_PORT = 12345; private static final String DEV_MACHINE_IP_ADDRESS = "192.168.1.78"; // change to your IP

N O T E

if you do not change the target IP address, the application will not

connect to Sdl Core or show up on the HMI

Right out of the box, all you need to do to run bluetooth is to select the

mbt_offDebug (Multiplexing Bluetooth) build flavor.

To connect to an SDL Core instance or TDK via USB transport, select the

usbDebug build flavor. There is more information for USB transport under

Getting Started - Using AOA Protocol.

Building the Project

For TCP, you may use the built-in Android emulator or an Android phone on the

same network as Sdl Core. For Bluetooth, you will need an Android phone that

is paired to a TDK or head unit via Bluetooth.

Run the project in Android Studio, targeting the device you want Hello Sdl

Android installed on.

Hello Sdl Android should compile and launch on your device of choosing:

CONFIGURE FOR BLUETOOTH

CONFIGURE FOR USB (AOA)

M U S T

Make sure Sdl Core and the HMI are running prior to running Hello

Sdl Android

Following this, you should see an application appear on the TDK or HMI. In the

case of the Generic HMI (using TCP), you will see the following:

Click on the Hello Sdl icon in the HMI.

This is the main screen of the Hello Sdl App. If you get to this point, the project

is working.

On the device you are running the app on, a lock screen should now appear

once the app is opened on the HMI:

At this point Hello Sdl Android has been compiled and is running properly!

Continue reading through our guides to learn about all of the

RPCs (Remote Procedure Calls) that can be made with the library.

Troubleshooting

Sometimes things don't always go as planned, and so this section exists. If your

app compiles and does NOT show up on the HMI, there are a few things to

check out.

1. Make sure that you have changed the IP in SdlService.java to match the

machine running Sdl Core. Being on the same network is also important.2. If you are sure that the IP is correct and it is still not showing up, make

sure the Build Flavor that is running is tcpDebug.3. If the two above dont work, make sure there is no firewall blocking the

incoming port 12345 on the machine or VM running SDL Core. In the

same breath, make sure your firewall allows that outgoing port.

N O T E

Lock Screens are an important part of Sdl enabled applications. The

goal is to keep the driver's eyes forward and off of the device

TCP

4. There are different network configurations needed for different

virtualization software (virtualbox, vmware, etc). Make sure yours is set up

correctly. Or use Manticore.

1. Make sure the build flavor mbt_offDebug is selected. 2. Ensure your phone is properly paired with the TDK3. Make sure Bluetooth is turned on - on Both the TDK and your phone4. Make sure apps are enabled on the TDK (in settings)

Adding the Lock Screen

In order for your SDL application to be certified with most OEMs you will be

required to implement a lock screen on the mobile device. The lock screen will

disable user interactions with the application while they are using the head-unit

to control application functionality. The URL for the lock screen image to display

is send by the head-unit.

Lock Screen Activity

First, we need to create a new activity that will host our lock screen. In the

activity we add a simple BroadcastReceiver that listens for

BLUETOOTH

N O T E

This guide assumes that you have an SDL Service implemented as

defined in the Getting Started guide.

CLOSE_LOCK_SCREEN_ACTION intents. In the broadcast receiver we will then

call finish() in order to shutdown the activity. We also check for a Bitmap extra,

LOCKSCREEN_BITMAP_EXTRA , in the intent that started the activity:

public class LockScreenActivity extends Activity { public static final String LOCKSCREEN_BITMAP_EXTRA = "LOCKSCREEN_BITMAP_EXTRA"; public static final String CLOSE_LOCK_SCREEN_ACTION = "CLOSE_LOCK_SCREEN";

private final BroadcastReceiver closeLockScreenBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { finish(); } };

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);

registerReceiver(closeLockScreenBroadcastReceiver, new IntentFilter(CLOSE_LOCK_SCREEN_ACTION));

setContentView(R.layout.activity_lock_screen);

Intent intent = getIntent(); ImageView imageView = (ImageView) findViewById(R.id.lockscreen);

if(intent.hasExtra(LOCKSCREEN_BITMAP_EXTRA)){ Bitmap lockscreen = (Bitmap) intent.getParcelableExtra(LOCKSCREEN_BITMAP_EXTRA); if(lockscreen != null){ imageView.setImageBitmap(lockscreen); } } }

@Override protected void onDestroy() { unregisterReceiver(closeLockScreenBroadcastReceiver); super.onDestroy(); }}

When the activity is created it will generate a layout file to use. We updated

this layout to display a default sample image from res/drawable in the middle

of the screen:

In our AndroidManifest we need to define the style and launch mode for our

lock screen activity. The theme is set to @android:style/

Theme.Black.NoTitleBar.Fullscreen and the launch mode is set to

singleInstance:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:src="@drawable/sample_lock" <!-- Replace with your own default image --> android:id="@+id/lockscreen"/></LinearLayout>

Updating SDL Service

To fully implement a lock screen, you'll want to add a LockScreenManager as a

member of your Service.

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.livio.hellosdl">

<application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme">

...

<activity android:name=".LockScreenActivity" android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen" android:launchMode="singleInstance"/>

</application>

</manifest>

public class SdlService extends Service implements IProxyListenerALM{ //...

private LockScreenManager lockScreenManager = new LockScreenManager();

//...

The LockScreenManager can download and hold a lock screen Bitmap given a

URL and a class that implements its callbacks. You can create a class similar to

this:

You should prepare to accept and download the lock screen image from the URL

sent by the head-unit in the onOnSystemRequest callback.

Now that our lock screen activity and manager are setup, all we have to do is

handle starting and stopping the activity. In the onOnLockScreenNotification

we need to trigger the lock screen to be displayed with the HMI Level is set to

FULL and when the lock screen status is required. If available, we also need to

private class LockScreenDownloadedListener implements LockScreenManager.OnLockScreenIconDownloadedListener{

@Override public void onLockScreenIconDownloaded(Bitmap icon) { Log.i(TAG, "Lock screen icon downloaded successfully"); }

@Override public void onLockScreenIconDownloadError(Exception e) { Log.e(TAG, "Couldn't download lock screen icon, resorting to default."); }}

public void onOnSystemRequest(OnSystemRequest notification) { if(notification.getRequestType().equals(RequestType.LOCK_SCREEN_ICON_URL)){ if(notification.getUrl() != null && lockScreenManager.getLockScreenIcon() == null){ lockScreenManager.downloadLockScreenIcon(notification.getUrl(), new LockScreenDownloadedListener()); } } }

pass along the Bitmap for the lock screen image. To finish, we need to close the

lock screen when the the lock screen status is OFF:

Now when the HMI fully displays the application, the mobile device will display

the lock screen with an image provided by the head-unit.

Designing a User Interface

Designing for Different User Interfaces

Each car manufacturer has different user interface style guidelines, so the

number of lines of text, buttons, and images supported will vary between

different types of head units. After your app creates an SdlProxyALM object

(which sends a RegisterAppInterface RPC) and connects to Core, the object

@Overridepublic void onOnLockScreenNotification(OnLockScreenStatus notification) { if(notification.getHMILevel() == HMILevel.HMI_FULL && notification.getShowLockScreen() == LockScreenStatus.REQUIRED) { Intent showLockScreenIntent = new Intent(this, LockScreenActivity.class); showLockScreenIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); if(lockScreenManager.getLockScreenIcon() != null){ showLockScreenIntent.putExtra(LockScreenActivity.LOCKSCREEN_BITMAP_EXTRA, lockScreenManager.getLockScreenIcon()); } startActivity(showLockScreenIntent); }else if(notification.getShowLockScreen() == LockScreenStatus.OFF){ sendBroadcast(new Intent(LockScreenActivity.CLOSE_LOCK_SCREEN_ACTION)); }}

automatically holds information from the RegisterAppInterface Response. You

can use this information to determine how to layout the user interface.

SdlProxyALM Object

The RegisterAppInterface response contains information about the display

type, the type of images supported, the number of text fields supported, the

HMI display language, and a lot of other useful properties. This information is

stored in the SdlProxyALM object. The table below has a list of all possible

properties available in the SdlProxyALM object. Each property is optional, so

you may not get information for all the parameters in the table.

PA R A M E T E R S D E S C R I P T I O N N O T E S

SdlMsgVersion

Specifies the versionnumber of the SDL V4interface. This is used byboth the application andSDL to declare whatinterface version each isusing.

CheckSdlMsgVersion.java formore information

sdlLanguage

The currently active voice-recognition and text-to-speech language on thehead unit.

Check Language.java formore information

hmiDisplayLanguageThe currently activedisplay language on thehead unit.

Check Language.java formore information

displayCapabilities

Information about thehead unit display. Thisincludes informationabout available templates,whether or not graphicsare supported, and a listof all text fields and themax number of charactersallowed in each text field.

CheckDisplayCapabilities.javafor more information

buttonCapabilities

A list of available buttonsand whether the buttonssupport long, short andup-down presses.

CheckButtonCapabilities.javafor more information

softButtonCapabilities

A list of available softbuttons and whether thebutton support images.Also information aboutwhether the buttonsupports long, short andup-down presses.

CheckSoftButtonCapabilities.java for more information

presetBankCapabilitiesIf returned, the platformsupports custom on-screen presets.

CheckPresetBankCapabilities.java for more information

hmiZoneCapabilities

Specifies HMI Zones in thevehicle. There may be aHMI available for backseat passengers as well asfront seat passengers.

CheckHmiZoneCapabilities.java for more information

speechCapabilities

Contains informationabout TTS capabilities onthe SDL platform.Platforms may supporttext, SAPI phonemes, LHPLUS phonemes, pre-recorded speech, andsilence.

CheckSpeechCapabilities.javafor more information

prerecordedSpeech

A list of pre-recordedsounds you can use inyour app. Sounds mayinclude a help, initial,listen, positive, or anegative jingle.

CheckPrerecordedSpeech.javafor more information

vrCapabilities

The voice-recognitioncapabilities of theconnected SDL platform.The platform may be ableto recognize spoken textin the current language.

CheckVrCapabilities.java formore information

PA R A M E T E R S D E S C R I P T I O N N O T E S

Templates

Each car manufacturer supports a set of templates for the user interface. These

templates determine the position and size of the text, images, and buttons on

the screen. A list of supported templates is sent with RegisterAppInterface

response and stored in the SdlProxyALM objects.

To change a template at any time, send a SetDisplayLayout RPC to the SDL

Core. If you want to ensure that the new template is used, wait for a response

from the SDL Core before sending any more user interface RPCs.

audioPassThruCapabilities

Describes the samplingrate, bits per sample, andaudio types available.

CheckAudioPassThruCapabilities.java for moreinformation

vehicleTypeThe make, model, year,and the trim of thevehicle.

Check VehicleType.javafor more information

supportedDiagModes

Specifies the white-list ofsupported diagnosticmodes (0x00-0xFF)capable forDiagnosticMessagerequests. If a modeoutside this list isrequested, it will berejected.

List

hmiCapabilities

Returns whether or notthe app can support built-in navigation and phonecalls.

CheckHMICapabilities.java formore information

systemSoftwareVersion

The software version ofthe system thatimplements theSmartDeviceLink core

String

Available Templates

There are fifteen standard templates to choose from, however some head units

may only support a subset of these templates. Please check the

DisplayCapabilities object returned by SdlProxyALM.getDisplayCapabilities()

for the supported templates. The following examples show how templates will

appear on the generic head unit.

SetDisplayLayout setDisplayLayoutRequest = new SetDisplayLayout();setDisplayLayoutRequest.setDisplayLayout("GRAPHIC_WITH_TEXT");setDisplayLayoutRequest.setOnRPCResponseListener(new OnRPCResponseListener() { @Override public void onResponse(int correlationId, RPCResponse response) { if(((SetDisplayLayoutResponse) response).getSuccess()){ Log.i("SdlService", "Display layout set successfully."); // Proceed with more user interface RPCs }else{ Log.i("SdlService", "Display layout request rejected."); } }});

try{ proxy.sendRPCRequest(setDisplayLayoutRequest);}catch (SdlException e){ e.printStackTrace();}

N O T E

You will automatically be assigned the media template if you set

your configuration app type as MEDIA .

F O R D H M I

1. MEDIA - WITH AND WITHOUT PROGRESS BAR

2. NON-MEDIA - WITH AND WITHOUT SOFT BUTTONS

F O R D H M I

3. GRAPHIC_WITH_TEXT

F O R D H M I

F O R D H M I

4. TEXT_WITH_GRAPHIC

5. T ILES_ONLY

F O R D H M I

F O R D H M I

6. GRAPHIC_WITH_TILES

7. T ILES_WITH_GRAPHIC

F O R D H M I

F O R D H M I

8. GRAPHIC_WITH_TEXT_AND_SOFTBUTTONS

9. TEXT_AND_SOFTBUTTONS_WITH_GRAPHIC

F O R D H M I

F O R D H M I

10. GRAPHIC_WITH_TEXTBUTTONS

11. DOUBLE_GRAPHIC_SOFTBUTTONS

F O R D H M I

F O R D H M I

12. TEXTBUTTONS_WITH_GRAPHIC

13. TEXTBUTTONS_ONLY

F O R D H M I

F O R D H M I

14. LARGE_GRAPHIC_WITH_SOFTBUTTONS

15. LARGE_GRAPHIC_ONLY

F O R D H M I

Text, Images, and Buttons

All text, images, and buttons on the HMI screen must be sent as part of a

Show RPC. Subscribe buttons are sent as part of a SubscribeButton RPC.

Text

A maximum of four lines of text can be set in Show RPC, however, some

templates may only support 1, 2, or 3 lines of text. If all four lines of text are

set in the Show RPC, but the template only supports three lines of text, then

the fourth line will simply be ignored.

Images

The position and size of images on the screen is determined by the currently

set template. All images must first be uploaded to the remote system using the

PutFile RPC before being used in a Show RPC. Once the image has been

successfully uploaded, the app will be notified in the upload method's

completion handler. For information relating to how to upload images, go to the

Uploading Files and Graphics section.

Show show = new Show();show.setMainField1("Hello, this is MainField1.");show.setMainField2("Hello, this is MainField2.");show.setMainField3("Hello, this is MainField3.");show.setMainField4("Hello, this is MainField4.");show.setOnRPCResponseListener(new OnRPCResponseListener() { @Override public void onResponse(int correlationId, RPCResponse response) { if (((ShowResponse) response).getSuccess()) { Log.i("SdlService", "Successfully showed."); } else { Log.i("SdlService", "Show request was rejected."); } }});proxy.sendRPCRequest(show);

N O T E

Some head units you may be connected to may not support images

at all. Please consult the getGraphicSupported() method in the

DisplayCapabilities property available from the SdlProxyALM

object.

Once the image has been uploaded to the head unit, you can show the image

on the user interface. To send the image, create an Image

(com.smartdevicelink.rpc.Image) object, and send it using the Show RPC. The

Value property should be set to the same value used in the filename

property when it was previously uploaded. Since you have uploaded your own

image, the ImageType property should be set to ImageType.DYNAMIC .

Soft & Subscribe Buttons

Buttons on the HMI screen are referred to as soft buttons to distinguish them

from hard buttons, which are physical buttons on the head unit. Don’t confuse

soft buttons with subscribe buttons, which are buttons that can detect user

selection on hard buttons (or built-in soft buttons).

SHOW THE IMAGE ON A HEAD UNIT

Image image = new Image();image.setImageType(ImageType.DYNAMIC);image.setValue("appImage.jpeg"); // a previously uploaded filename using PutFile RPC

Show show = new Show();show.setGraphic(image);show.setCorrelationID(CorrelationIdGenerator.generateId());show.setOnRPCResponseListener(new OnRPCResponseListener() { @Override public void onResponse(int correlationId, RPCResponse response) { if (((ShowResponse) response).getSuccess()) { Log.i("SdlService", "Successfully showed."); } else { Log.i("SdlService", "Show request was rejected."); } }});proxy.sendRPCRequest(show);

Soft buttons can be created with text, images or both text and images. The

location, size, and number of soft buttons visible on the screen depends on the

template. If the button has an image, remember to upload the image first to

the head unit before setting the image in the SoftButton instance.

SOFT BUTTONS

N O T E

If a button type is set to SBT_IMAGE or SBT_BOTH but no image

is stored on the head unit, the button might not show up on the

HMI screen.

Subscribe buttons are used to detect changes to hard buttons. You can

subscribe to the following hard buttons:

Image cancelImage = new Image();cancelImage.setImageType(ImageType.DYNAMIC);cancelImage.setValue("cancel.jpeg");

List<SoftButton> softButtons = new ArrayList<>();

SoftButton yesButton = new SoftButton();yesButton.setType(SoftButtonType.SBT_TEXT);yesButton.setText("Yes");yesButton.setSoftButtonID(0);

SoftButton cancelButton = new SoftButton();cancelButton.setType(SoftButtonType.SBT_IMAGE);cancelButton.setImage(cancelImage);cancelButton.setSoftButtonID(1);

softButtons.add(yesButton);softButtons.add(cancelButton);

Show show = new Show();show.setSoftButtons(softButtons);show.setOnRPCResponseListener(new OnRPCResponseListener() { @Override public void onResponse(int correlationId, RPCResponse response) { if (((ShowResponse) response).getSuccess()) { Log.i("SdlService", "Successfully showed."); } else { Log.i("SdlService", "Show request was rejected."); } }});proxy.sendRPCRequest(show);

SUBSCRIBE BUTTONS

B U T T O N T E M P L AT E B U T T O N T Y P E

Audio buttons like the OK (i.e. the play/pause button), seek left, seek right,

tune up, and tune down buttons can only be used with a media template. The

OK, seek left, and seek right buttons will also show up on the screen in a

predefined location dictated by the media template on touchscreens. The app

will be notified when the user selects the subscribe button on the screen or

when the user manipulates the corresponding hard button.

You can subscribe to buttons using the SubscribeButton RPC.

Ok (play/pause) media template only soft button and hardbutton

Seek left media template only soft button and hardbutton

Seek right media template only soft button and hardbutton

Tune up media template only hard button

Tune down media template only hard button

Preset 0-9 any template hard button

Search any template hard button

Custom any template hard button

SubscribeButton subscribeButtonRequest = new SubscribeButton();subscribeButtonRequest.setButtonName(ButtonName.SEEKRIGHT);proxy.sendRPCRequest(subscribeButtonRequest);

Once you have successfully subscribed to buttons and/or added soft buttons

you will likely want to know when events happen to those buttons. These

events come through two callbacks from the IProxyListenerALM interface,

onOnButtonEvent and onOnButtonPress . Depending which type of event

you're looking for you can use that type of callback. The ButtonName enum

refers to which button the event happened to. SoftButton events will have the

ButtonName of CUSTOM_BUTTON .

N O T E

It is not required to manually subscribe to soft buttons. When soft

buttons are added, your app will automatically be subscribed for

their events

RECEIVING BUTTONS EVENTS

@Overridepublic void onOnButtonEvent(OnButtonEvent notification) { switch(notification.getButtonName()){ case CUSTOM_BUTTON: //Custom buttons are the soft buttons previously added. int ID = notification.getCustomButtonID(); Log.d("SdlService", "Button event received for button " + ID); break; case OK: break; case SEEKLEFT: break; case SEEKRIGHT: break; case TUNEUP: break; case TUNEDOWN: break; default: break; }}

@Overridepublic void onOnButtonPress(OnButtonPress notification) { switch(notification.getButtonName()){ case CUSTOM_BUTTON: //Custom buttons are the soft buttons previously added. int ID = notification.getCustomButtonName(); Log.d("SdlService", "Button press received for button " + ID); break; case OK: break; case SEEKLEFT: break; case SEEKRIGHT: break; case TUNEUP: break; case TUNEDOWN: break; default: break; }}

Menus

You have two different options when creating menus. One is to simply add

items to the default menu available in every template. The other is to create a

custom menu that pops up when needed.

Default Menu

F O R D H M I

Every template has a default menu button. The position of this button varies

between templates, and can not be removed from the template. The default

menu is initially empty except for an "Exit Your App Name" button. Items can be

added to the menu at the root level or to a submenu. It is important to note

that a submenu can only be one level deep.

Menu Structure

The AddCommand RPC can be used to add items to the root menu or to a

submenu. Each AddCommand RPC must be sent with a unique id, a voice-

recognition command, and a set of menu parameters. The menu parameters

include the menu name, the position of the item in the menu, and the id of the

menu item’s parent. If the menu item is being added to the root menu, then the

ADD MENU ITEMS

parent id is 0. If it is being added to a submenu, then the parent id is the

submenu’s id.

To create a submenu, first send an AddSubMenu RPC. When a response is

received from the SDL Core, check if the submenu was added successfully. If it

was, send an AddCommand RPC for each item in the submenu.

// Create the menu parameters// The parent id is 0 if adding to the root menu// If adding to a submenu, the parent id is the submenu's idMenuParams menuParams = new MenuParams();menuParams.setParentID(0);menuParams.setPosition(0);menuParams.setMenuName("Options");

AddCommand addCommand = new AddCommand();addCommand.setCmdID(0); // Ensure this is uniqueaddCommand.setMenuParams(menuParams); // Set the menu parameters

proxy.sendRPCRequest(addCommand);

ADD A SUBMENU

Use the cmdID of the menu item to tell the SDL Core which item to delete using

the DeleteCommand RPC.

int unique_id = 313;

AddSubMenu addSubMenu = new AddSubMenu();addSubMenu.setPosition(0);addSubMenu.setMenuID(unique_id);addSubMenu.setMenuName("SubMenu");addSubMenu.setOnRPCResponseListener(new OnRPCResponseListener() { @Override public void onResponse(int correlationId, RPCResponse response) { if(((AddSubMenuResponse) response).getSuccess()){ // The submenu was created successfully, start adding the submenu items // Use unique_id }else{ Log.i("SdlService", "AddSubMenu request rejected."); } }});

DELETE MENU ITEMS

int cmdID_to_delete = 1;

DeleteCommand deleteCommand = new DeleteCommand();deleteCommand.setCmdID(cmdID_to_delete);

proxy.sendRPCRequest(deleteCommand);

Use the menuID to tell the SDLCore which item to delete using the

DeleteSubMenu RPC.

Custom Menus

Custom menus, called perform interactions, are one level deep, however,

you can create submenus by triggering another perform interaction when the

user selects a row in a menu. Perform interactions can be set up to recognize

speech, so a user can select an item in the menu by speaking their preference

rather than physically selecting the item.

DELETE SUBMENUS

DeleteSubMenu deleteSubMenu = new DeleteSubMenu();deleteSubMenu.setMenuID(submenuID_to_delete); // Replace with submenu ID to delete

Perform interactions are created by sending two different RPCs. First a

CreateInteractionChoiceSet RPC must be sent. This RPC sends a list of items

that will show up in the menu. When the request has been registered

successfully, then a PerformInteraction RPC is sent. The PerformInteraction

RPC sends the formatting requirements, the voice-recognition commands, and

a timeout command.

Each menu item choice defined in Choice should be assigned a unique id. The

choice set in CreateInteractionChoiceSet should also have its own unique id.

CREATE A SET OF CUSTOM MENU ITEMS

CreateInteractionChoiceSet choiceSet = new CreateInteractionChoiceSet();

Choice choice = new Choice();choice.setChoiceID(uniqueChoiceID);choice.setMenuName("ChoiceA");choice.setVrCommands(Arrays.asList("ChoiceA"));

List<Choice> choiceList = new ArrayList<>();choiceList.add(choice);

choiceSet.setChoiceSet(choiceList);choiceSet.setInteractionChoiceSetID(uniqueIntChoiceSetID);choiceSet.setOnRPCResponseListener(new OnRPCResponseListener() {@Overridepublic void onResponse(int correlationId, RPCResponse response) { if(((CreateInteractionChoiceSetResponse) response).getSuccess()){ // The request was successful, now send the SDLPerformInteraction RPC }else{ // The request was unsuccessful }}});

proxy.sendRPCRequest(choiceSet);

Once the set of menu items has been sent to SDL Core, send a

PerformInteraction RPC to get the items to show up on the HMI screen.

The interaction mode specifies the way the user is prompted to make a section

and the way in which the user’s selection is recorded.

I N T E R A C T I O N M O D E D E S C R I P T I O N

FORMAT THE SET OF CUSTOM MENU ITEMS

List<Integer> interactionChoiceSetIDList = new ArrayList<>();interactionChoiceSetIDList.add(uniqueIntChoiceSetID);

PerformInteraction performInteraction = new PerformInteraction();performInteraction.setInitialText("Initial text.");performInteraction.setInteractionChoiceSetIDList(interactionChoiceSetIDList);

INTERACTION MODE

Manual only Interactions occur only through thedisplay

VR only Interactions occur only through text-to-speech and voice recognition

Both Interactions can occur both manually orthrough VR

F O R D H M I

performInteraction.setInteractionMode(InteractionMode.MANUAL_ONLY);

VR INTERACTION MODE

MANUAL INTERACTION MODE

F O R D H M I

The items in the perform interaction can be shown as a grid of buttons (with

optional images) or as a list of choices.

L AYO U T M O D E F O R M AT T I N G D E S C R I P T I O N

INTERACTION LAYOUT

Icon only A grid of buttons with images

Icon with search A grid of buttons with images along witha search field in the HMI

List only A vertical list of text

List with search A vertical list of text with a search field inthe HMI

Keyboard A keyboard shows up immediately in theHMI

F O R D H M I

N O T E

Keyboard is currently only supported for the navigation app type.

performInteraction.setInteractionLayout(LayoutMode.LIST_ONLY);

ICON ONLY INTERACTION LAYOUT

LIST ONLY INTERACTION LAYOUT

F O R D H M I

F O R D H M I

L IST WITH SEARCH INTERACTION LAYOUT

A text-to-speech chunk is a text phrase or prerecorded sound that will be

spoken by the head unit. The text parameter specifies the text to be spoken or

the name of the pre-recorded sound. Use the type parameter to define the type

of information in the text parameter. The PerformInteraction request can have

a initial, timeout, and a help prompt.

The timeout parameter defines the amount of time the menu will appear on the

screen before the menu is dismissed automatically by the HMI.

TEXT-TO-SPEECH (TTS)

performInteraction.setInitialPrompt( TTSChunkFactory.createSimpleTTSChunks("Hello, welcome."));

T IMEOUT

performInteraction.setTimeout(30000); // 30 seconds

If the information in the menu is dynamic, then the old interaction choice set

needs to be deleted with a DeleteInteractionChoiceSet RPC before the new

information can be added to the menu. Use the interaction choice set id to

delete the menu.

SEND THE REQUEST

performInteraction.setOnRPCResponseListener(new OnRPCResponseListener() { @Override public void onResponse(int correlationId, RPCResponse response) { PerformInteractionResponse piResponse = (PerformInteractionResponse) response; if(piResponse.getSuccess()){ // Successful request if(piResponse.getResultCode().equals(Result.TIMED_OUT)){ // Interaction timed out without user input }else if(piResponse.getResultCode().equals(Result.SUCCESS)){ Integer userChoice = piResponse.getChoiceID(); } }else{ // Unsuccessful request } }});

proxy.sendRPCRequest(performInteraction);

DELETE THE CUSTOM MENU

Alerts

An alert is a pop-up window with some lines of text and optional soft buttons.

When an alert is activated, it will abort any SDL operation that is in-progress,

except the already-in-progress alert. If an alert is issued while another alert is

still in progress, the newest alert will simply be ignored.

Alert UI

Depending the platform, an alert can have up to three lines of text, a progress

indicator (e.g. a spinning wheel or hourglass), and up to four soft buttons.

DeleteInteractionChoiceSet deleteInteractionChoiceSet = new DeleteInteractionChoiceSet();deleteInteractionChoiceSet.setInteractionChoiceSetID(interactionChoiceSetID_to_delete); // Replace with interaction choice set to delete

proxy.sendRPCRequest(deleteInteractionChoiceSet);

ALERT WITHOUT SOFT BUTTONS

F O R D H M I

F O R D H M I

Alert TTS

The alert can also be formatted to speak a prompt when the alert appears on

the screen. Do this by setting the ttsChunks parameter. To play the alert tone

before the text-to-speech is spoken, set playTone to true .

ALERT WITH SOFT BUTTONS

Example

Dismissing the Alert

The alert will persist on the screen until the timeout has elapsed, or the user

dismisses the alert by selecting a button. There is no way to dismiss the alert

programmatically other than to set the timeout length.

Alert alert = new Alert();alert.setAlertText1("Alert Text 1");alert.setAlertText2("Alert Text 2");alert.setAlertText3("Alert Text 3");

// Maximum time alert appears before being dismissed// Timeouts are must be between 3-10 seconds// Timeouts may not work when soft buttons are also used in the alertalert.setDuration(5000);

// A progress indicator (e.g. spinning wheel or hourglass)// Not all head units support the progress indicatoralert.setProgressIndicator(true);

//Text to speechalert.setTtsChunks(TTS_list); // TTS_list populated elsewhere

// Special tone played before the tts is spokenalert.setPlayTone(true);

// Soft buttonsalert.setSoftButtons(softButtons); // softButtons populated elsewhere

// Send alertproxy.sendRPCRequest(alert);

Uploading Files and Graphics

Graphics allow for you to better customize what you would like to have your

users see and provide a better User Interface.

When developing an application using SmartDeviceLink, two things must

always be remembered when using graphics:

1. You may be connected to a head unit that does not display graphics.2. You must upload them from your mobile device to Core before using them.

Detecting if Graphics are Supported

Being able to know if graphics are supported is a very important feature of your

application, as this avoids you uploading unneccessary images to the head

unit. In order to see if graphics are supported, use the getDisplayCapabilities()

method of a valid SdlProxyALM to find out the display capabilities of the head

unit.

Uploading a File using PutFile

To upload a file to Core, use the PutFile RPC. You can use the RPC response

callback to perform certain actions upon a successful or unsuccessful upload.

Here's an example that attempts to upload an image to Core and set's the

app's HMI icon upon a successful upload.

DisplayCapabilities displayCapabilities = proxy.getDisplayCapabilities();Boolean graphicsSupported = displayCapabilities.getGraphicSupported();

App icons and other images might be hardcoded into the app and getting their

raw data will be important. The following method will help get that data:

PutFile putFileRequest = new PutFile();putFileRequest.setSdlFileName("appIcon.jpeg");putFileRequest.setFileType(FileType.GRAPHIC_JPEG);putFileRequest.setPersistentFile(true);putFileRequest.setFileData(file_data); // can create file_data using helper method belowputFileRequest.setCorrelationID(CorrelationIdGenerator.generateId());putFileRequest.setOnRPCResponseListener(new OnRPCResponseListener() {

@Override public void onResponse(int correlationId, RPCResponse response) { setListenerType(UPDATE_LISTENER_TYPE_PUT_FILE); // necessary for PutFile requests

if(response.getSuccess()){ try { proxy.setappicon("appIcon.jpeg", CorrelationIdGenerator.generateId()); } catch (SdlException e) { e.printStackTrace(); } }else{ Log.i("SdlService", "Unsuccessful app icon upload."); } }});try { proxy.sendRPCRequest(putFileRequest);} catch (SdlException e) { e.printStackTrace();}

File Naming

The file name can only consist of letters (a-Z) and numbers (0-9), otherwise the

SDL Core may fail to find the uploaded file (even if it was uploaded

successfully).

/*** Helper method to take resource files and turn them into byte arrays* @param resource Resource file id.* @return Resulting byte array.*/private byte[] contentsOfResource(int resource) { InputStream is = null; try { is = getResources().openRawResource(resource); ByteArrayOutputStream os = new ByteArrayOutputStream(is.available()); final int bufferSize = 4096; final byte[] buffer = new byte[bufferSize]; int available; while ((available = is.read(buffer)) >= 0) { os.write(buffer, 0, available); } return os.toByteArray(); } catch (IOException e) { Log.w(TAG, "Can't read icon file", e); return null; } finally { if (is != null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } }}

File Persistance

PutFile supports uploading persistant images, i.e. images that do not become

deleted when your application disconnects. Persistance should be used for

images relating to your UI, and not for dynamic aspects, such as Album

Artwork.

This relates to the following line in the above example:

Overwrite Stored Files

If a file being uploaded has the same name as an already uploaded file, the

new file will overwrite the previous file.

Check if a File Has Already Been Uploaded

You can use the ListFiles RPC to check for the names of uploaded files to avoid

overwriting a file.

putFileRequest.setPersistentFile(true);

N O T E

Be aware that persistance will not work if space on the head unit is

limited.

Check the Amount of File Storage

To find the amount of file storage left on the head unit, use the the ListFiles

RPC in a similar fashion.

ListFiles listFiles = new ListFiles();listFiles.setCorrelationID(CorrelationIdGenerator.generateId());listFiles.setOnRPCResponseListener(new OnRPCResponseListener() { @Override public void onResponse(int correlationId, RPCResponse response) { if(response.getSuccess()){ List<String> filenames = ((ListFilesResponse) response).getFilenames(); if(filenames.contains("appIcon.jpeg")){ Log.i("SdlService", "App icon is already uploaded."); }else{ Log.i("SdlService", "App icon has not been uploaded."); } }else{ Log.i("SdlService", "Failed to request list of uploaded files."); } }});try{ proxy.sendRPCRequest(listFiles);} catch (SdlException e) { e.printStackTrace();}

Delete Stored Files

Use the DeleteFile RPC to delete a file associated with a file name.

ListFiles listFiles = new ListFiles();listFiles.setCorrelationID(CorrelationIdGenerator.generateId());listFiles.setOnRPCResponseListener(new OnRPCResponseListener() { @Override public void onResponse(int correlationId, RPCResponse response) { if(response.getSuccess()){ Integer spaceAvailable = ((ListFilesResponse) response).getSpaceAvailable(); Log.i("SdlService", "Space available on Core = " + spaceAvailable); }else{ Log.i("SdlService", "Failed to request list of uploaded files."); } }});try{ proxy.sendRPCRequest(listFiles);} catch (SdlException e) { e.printStackTrace();}

Image Specifics

Image File Type

Images may be formatted as PNG, JPEG, or BMP. Check the DisplayCapabilities

object provided by your SdlProxyALM to find out what image formats the head

unit supports.

Image Sizes

If an image is uploaded that is larger than the supported size, that image will

be scaled down to accomodate.

DeleteFile deleteFileRequest = new DeleteFile();deleteFileRequest.setSdlFileName("appIcon.jpeg");deleteFileRequest.setCorrelationID(CorrelationIdGenerator.generateId());deleteFileRequest.setOnRPCResponseListener(new OnRPCResponseListener() {

@Override public void onResponse(int correlationId, RPCResponse response) { if(response.getSuccess()){ Log.i("SdlService", "App icon deleted."); }else{ Log.i("SdlService", "Unable to delete app icon."); } }});try{ proxy.sendRPCRequest(deleteFileRequest);} catch (SdlException e) { e.printStackTrace();}

I M A G EN A M E

U S E D I NR P C

D E TA I L S H E I G H T W I D T H T Y P E

IMAGE SPECIF ICATIONS

softButtonImage

Show

Will beshown onsoftbuttons on thebasescreen

70px 70pxpng,jpg,bmp

choiceImage

CreateInteractionChoiceSet

Will beshown inthemanualpart of anperformInteractioneither big(ICON_ONLY) orsmall(LIST_ONLY)

70px 70pxpng,jpg,bmp

choiceSecondaryImage

CreateInteractionChoiceSet

Will beshown onthe rightside of anentry in(LIST_ONLY)performInteraction

35px 35pxpng,jpg,bmp

vrHelpItem

SetGlobalProperties

Will beshownduringvoiceinteraction

35px 35pxpng,jpg,bmp

menuIcon

SetGlobalProperties

Will beshown onthe“More…”button

35px 35pxpng,jpg,bmp

cmdIcon

AddCommand

Will beshown forcommands in the"More…"menu

35px 35pxpng,jpg,bmp

appIcon SetAppIcon

Will beshown asIcon inthe"MobileApps"menu

70px 70pxpng,jpg,bmp

graphic Show

Will beshown onthebasescreen ascover art

185px 185pxpng,jpg,bmp

Get Vehicle Data

Use the GetVehicleData RPC request to get vehicle data. The HMI level must be

FULL, LIMITED, or BACKGROUND in order to get data.

Each vehicle manufacturer decides which data it will expose. Please check the

OnPermissionsChange RPC notification to find out which data you will have

access to in your head unit.

N O T E

You may only ask for vehicle data that is available to your

appName & appId combination. These will be specified by each

OEM separately.

V E H I C L E D ATA PA R A M E T E R N A M E D E S C R I P T I O N

GPS gps

Longitude and latitude,current time in UTC,degree of precision,altitude, heading, speed,satellite data vs deadreckoning, andsupported dimensions ofthe GPS

Speed speed Speed in KPH

RPM rpmThe number ofrevolutions per minuteof the engine

Fuel level fuelLevel The fuel level in the tank(percentage)

Fuel level state fuelLevel_State

The fuel level state:unknown, normal, low,fault, alert, or notsupported

Instant fuel consumption instantFuelConsumptionThe instantaneous fuelconsumption inmicrolitres

External temperature externalTemperatureThe externaltemperature in degreescelsius

VIN vin The VehicleIdentification Number

PRNDL prndl

The selected gear thecar is in: park, reverse,neutral, drive, sport, lowgear, first, second, third,fourth, fifth, sixth,seventh or eighth gear,unknown, or fault

Tire pressure tirePressure

Tire status of eachwheel in the vehicle:normal, low, fault, alert,or not supported.Warning light status forthe tire pressure: off, on,flash, or not used

Odometer odometer Odometer reading in km

Belt status beltStatus

The status of each of theseat belts: no, yes, notsupported, fault, or noevent

Body information bodyInformation

Door ajar status for eachdoor. The Ignition status.The ignition stablestatus. The park brakeactive status.

V E H I C L E D ATA PA R A M E T E R N A M E D E S C R I P T I O N

Device status deviceStatus

Contains informationabout the smartphonedevice. Is voicerecognition on or off,has a bluetoothconnection beenestablished, is a callactive, is the phone inroaming mode, is a textmessage available, thebattery level, the statusof the mono and stereooutput channels, thesignal level, the primaryaudio source, whether ornot an emergency call iscurrently taking place

Driver braking driverBrakingThe status of the brakepedal: yes, no, no event,fault, not supported

Wiper status wiperStatus

The status of the wipers:off, automatic off, offmoving, manualinteraction off, manualinteraction on, manuallow, manual high,manual flick, wash,automatic low,automatic high, courtesywipe, automatic adjust,stalled, no data exists

Head lamp status headLampStatus

Status of the headlamps: whether or notthe low and high beamsare on or off. Theambient light sensorstatus: night, twilight 1,twilight 2, twilight 3,twilight 4, day,unknown, invalid

Engine torque engineTorqueTorque value for engine(in Nm) on non-dieselvariants

Acceleration pedalposition accPedalPosition

Accelerator pedalposition (percentagedepressed)

Steering wheel angle steeringWheelAngleCurrent angle of thesteering wheel (indegrees)

E-Call infomation eCallInfoInformation about thestatus of an emergencycall

Airbag status airbagStatus

Status of each of theairbags in the vehicle:yes, no, no event, notsupported, fault

V E H I C L E D ATA PA R A M E T E R N A M E D E S C R I P T I O N

Single Time Vehicle Data Retrieval

Using GetVehicleData , we can ask for vehicle data a single time, if needed.

Emergency event emergencyEvent

The type of emergency:frontal, side, rear,rollover, no event, notsupported, fault. Fuelcutoff status: normaloperation, fuel is cut off,fault. The roll overstatus: yes, no, noevent, not supported,fault. The maximumchange in velocity.Whether or not multipleemergency events haveoccurred

Cluster mode status clusterModeStatus

Whether or not thepower mode is active.The power modequalification status:power mode undefined,power mode evaluationin progress, not defined,power mode ok. The carmode status: normal,factory, transport, orcrash. The power modestatus: key out, keyrecently out, keyapproved, postaccessory, accessory,post ignition, ignition on,running, crank

My key myKey

Information aboutwhether or not theemergency 911 overridehas been activated

Subscribing to Vehicle Data

Subscribing to vehicle data allows you to get notified whenever we have new

data available. This data should not be relied upon being received in a

consistent manner. New vehicle data is available roughly every second.

First, send the Subscribe Vehicle Data Request

GetVehicleData vdRequest = new GetVehicleData();vdRequest.setPrndl(true);vdRequest.setOnRPCResponseListener(new OnRPCResponseListener() { @Override public void onResponse(int correlationId, RPCResponse response) { if(response.getSuccess()){ PRNDL prndl = ((GetVehicleDataResponse) response).getPrndl(); Log.i("SdlService", "PRNDL status: " + prndl.toString()); }else{ Log.i("SdlService", "GetVehicleData was rejected."); } }});try { proxy.sendRPCRequest(vdRequest);} catch (SdlException e) { e.printStackTrace();}

Then, you'll be able to observe the new data in the OnVehicleData

notification:

Unsubscribing from Vehicle Data

Sometimes you may not always need all of the vehicle data you are listening

to. We suggest that you only are subscribing when the vehicle data is needed.

To stop listening to specific vehicle data items, utilize UnsubscribeVehicleData

.

SubscribeVehicleData subscribeRequest = new SubscribeVehicleData();subscribeRequest.setPrndl(true);subscribeRequest.setOnRPCResponseListener(new OnRPCResponseListener() { @Override public void onResponse(int correlationId, RPCResponse response) { if(response.getSuccess()){ Log.i("SdlService", "Successfully subscribed to vehicle data."); }else{ Log.i("SdlService", "Request to subscribe to vehicle data was rejected."); } }});

try { proxy.sendRPCRequest(subscribeRequest);} catch (SdlException e) { e.printStackTrace();}

@Overridepublic void onOnVehicleData(OnVehicleData notification) { PRNDL prndl = notification.getPrndl(); Log.i("SdlService", "PRNDL status was updated to: " prndl.toString());}

Knowing the In-Car UI Status

Once your app is connected to Core, most of the interaction you will be doing

requires knowledge of the current In-Car UI, or HMI, Status. The HMI Status

informs you of where the user is within the head unit in a general sense.

Refer to the table below of all possible HMI States:

UnsubscribeVehicleData unsubscribeRequest = new UnsubscribeVehicleData();unsubscribeRequest.setPrndl(true); // unsubscribe to PRNDL dataunsubscribeRequest.setOnRPCResponseListener(new OnRPCResponseListener() { @Override public void onResponse(int correlationId, RPCResponse response) { if(response.getSuccess()){ Log.i("SdlService", "Successfully unsubscribed to vehicle data."); }else{ Log.i("SdlService", "Request to unsubscribe to vehicle data was rejected."); } }});

try { proxy.sendRPCRequest(unsubscribeRequest);} catch (SdlException e) { e.printStackTrace();}

H M I S TAT E W H AT D O E S T H I S M E A N ?

Monitoring HMI Status

Monitoring HMI Status is possible through an OnHMIStatus notification in the

onOnHMIStatus() callback in your app's SDL Service. It will give you

information relating to the previous and new HMI levels your app is progressing

through.

More Detailed HMI Information

When an interaction occurs relating to your application, there is some

additional pieces of information that can be observed that help figure out a

more descriptive picture of what is going on with the Head Unit.

NONEThe user has not been opened your app,or it has been Exited via the "Menu"button.

BACKGROUND

The user has opened your app, but iscurrently in another part of the HeadUnit. If you have a Media app, this meansthat another Media app has beenselected.

LIMITEDFor Media apps, this means that a userhas opened your app, but is in anotherpart of the Head Unit.

FULL Your app is currently in focus on thescreen.

public void onOnHMIStatus(OnHMIStatus notification) { // Check notification for various HMI info}

From the documentation, Audio Streaming State informs your app whether any

currently streaming audio is audible to user (AUDIBLE) or not (NOT_AUDIBLE). A

value of NOT_AUDIBLE means that either the application's audio will not be

audible to the user, or that the application's audio should not be audible to the

user (i.e. some other application on the mobile device may be streaming audio

and the application's audio would be blended with that other audio).

You will see this come in for things such as Alert, PerformAudioPassThru,

Speaks, etc.

AU D I O S T R E A M I N G S TAT E W H AT D O E S T H I S M E A N ?

System Context informs your app if there is potentially a blocking HMI

component while your app is still visible. An example of this would be if your

application is open, and you display an Alert. Your app will receive a System

Context of ALERT while it is presented on the screen, followed by MAIN when it

is dismissed.

AUDIO STREAMING STATE

AUDIBLE Any audio you are streaming will beaudible to the user.

ATTENUATED

Some kind of audio mixing is occuringbetween what you are streaming, ifanything, and some system level sound.This can be visible is displaying an Alertwith playTone set to true.

NOT_AUDIBLEYour streaming audio is not audible. Thiscould occur during a VRSESSSIONSystem Context.

SYSTEM CONTEXT

S Y S T E M C O N T E X T S TAT E W H AT D O E S T H I S M E A N ?

Monitoring Audio Streaming State and System

Context

Monitoring these two properties is quite easy using the OnHMIStatus

notification.

Setting the Navigation Destination

Setting a Navigation Destination allows you to send a GPS location that you

would like to prompt that user to navigate to using their embedded navigation.

MAIN No user interaction is in progress thatcould be blocking your app's visibility.

VRSESSION Voice Recognition is currently inprogress.

MENU A menu interaction is currently in-progress.

HMI_OBSCUREDThe app's display HMI is being blockedby either a system or other app's overlay(another app's Alert, for instance).

ALERT An alert that you have sent is currentlyvisible (Other apps will not receive this).

public void onOnHMIStatus(OnHMIStatus notification) { AudioStreamingState streamingState = notification.getAudioStreamingState(); SystemContext systemContext = notification.getSystemContext();}

When using the SendLocation RPC, you will not receive a callback about how

the user interacted with this location, only if it was successfully sent to Core

and received. It will be handled by Core from that point on using the embedded

navigation system.

Determining the Result of SendLocation

SendLocation has 3 possible results that you should expect:

1. SUCCESS - SendLocation was successfully sent.2. INVALID_DATA - The request you sent contains invalid data and was

rejected.3. DISALLOWED - Your app does not have permission to use SendLocation.

Detecting if SendLocation is Available

SendLocation is a newer RPC, so there is a possibility that not all head units

will support it, especially if you are connected to a head unit that does not have

an embedded navigation. To see if SendLocation is supported, you may look

N O T E

This currently is only supported for Embedded Navigation. This

does not work with Mobile Navigation Apps at this time.

N O T E

SendLocation is an RPC that is usually restricted by OEMs. As a

result, the OEM you are connecting to may limit app functionality if

not approved for usage.

at your SdlProxyALM object's getHmiCapabilities method after the

successfully creating the proxy.

Using SendLocation

To use SendLocation , you must at least include the Longitude and Latitude of

the location. You can also include an address, name, description, phone

number, and image.

if(proxy.getHmiCapabilities().isNavigationAvailable()){ // SendLocation supported}else{ // SendLocation is not supported}

SendLocation sendLocation = new SendLocation();sendLocation.setLatitudeDegrees(42.877737);sendLocation.setLongitudeDegrees(-97.380967);sendLocation.setLocationName("The Center");sendLocation.setLocationDescription("Center of the United States");

// Create AddressOasisAddress address = new OasisAddress();address.setSubThoroughfare("900");address.setThoroughfare("Whiting Dr");address.setLocality("Yankton");address.setAdministrativeArea("SD");address.setPostalCode("57078");address.setCountryCode("US-SD");address.setCountryName("United States");

sendLocation.setAddress(address);

// Monitor responsesendLocation.setOnRPCResponseListener(new OnRPCResponseListener() { @Override public void onResponse(int correlationId, RPCResponse response) { Result result = response.getResultCode(); if(result.equals(Result.SUCCESS)){ // SendLocation was successfully sent. }else if(result.equals(Result.INVALID_DATA)){ // The request you sent contains invalid data and was rejected. }else if(result.equals(Result.DISALLOWED)){ // Your app does not have permission to use SendLocation. } }});

proxy.sendRPCRequest(sendLocation);

Calling a Phone Number

Dialing a Phone Number allows you to send a phone number to dial on the

user's phone. Regardless of platform, you must be sure that a device is

connected via Bluetooth for this RPC to work. If it is not connected, you will

receive a REJECTED Result .

Determining the Result of DialNumber

DialNumber has 3 possible results that you should expect:

1. SUCCESS - DialNumber was successfully sent, and a phone call was

initiated by the user.2. REJECTED - DialNumber was sent, and a phone call was cancelled by the

user. Also, this could mean that there is no phone connected via

Bluetooth.3. DISALLOWED - Your app does not have permission to use DialNumber.

Detecting if DialNumber is Available

DialNumber is a newer RPC, so there is a possibility that not all head units will

support it. To see if DialNumber is supported, you may look at your

SdlProxyALM object's getHmiCapabilities method after the successfully creating

the proxy.

N O T E

DialNumber is an RPC that is usually restricted by OEMs. As a

result, the OEM you are connecting to may limit app functionality if

not approved for usage.

How to Use

if(proxy.getHmiCapabilities().isPhoneCallAvailable()){ // DialNumber supported}else{ // DialNumber is not supported}

N O T E

For DialNumber, all characters are stripped except for 0 - 9 , * ,

# , , , ; , and +

DialNumber dialNumber = new DialNumber();dialNumber.setNumber("1238675309");dialNumber.setOnRPCResponseListener(new OnRPCResponseListener() { @Override public void onResponse(int correlationId, RPCResponse response) { Result result = response.getResultCode(); if(result.equals(Result.SUCCESS)){ // `DialNumber` was successfully sent, and a phone call was initiated by the user. }else if(result.equals(Result.REJECTED)){ // `DialNumber` was sent, and a phone call was cancelled by the user. Also, this could mean that there is no phone connected via Bluetooth. }else if(result.equals(Result.DISALLOWED)){ // Your app does not have permission to use DialNumber. } }});

proxy.sendRPCRequest(dialNumber);

Getting In-Car Audio

Capturing in-car audio allows developers to interact with users via raw audio

data provided to them from the car's microphones. In order to gather the raw

audio from the vehicle, we must leverage the PerformAudioPassThru RPC.

Starting Audio Capture

To initiate audio capture, we must construct a PerformAudioPassThru object.

The properties we will set in this object's constructor relate to how we wish to

gather the audio data from the vehicle we are connected to.

N O T E

PerformAudioPassThru does not support automatic speech

cancellation detection, so if this feature is desired, it is up to the

developer to implement.

In order to know the currently supported audio capture capabilities of the

connected head unit, please refer to the SdlProxyALM object created when

your SDL Service starts. It contains a method getAudioPassThruCapabilities

that returns a list of AudioPassThruCapabilities that the head unit supports.

PerformAudioPassThru performAPT = new PerformAudioPassThru();performAPT.setAudioPassThruDisplayText1("Ask me \"What's the weather?\"");performAPT.setAudioPassThruDisplayText2("or \"What's 1 + 2?\"");

performAPT.setInitialPrompt(TTSChunkFactory .createSimpleTTSChunks("Ask me What's the weather? or What's 1 plus 2?"));performAPT.setSamplingRate(SamplingRate._22KHZ);performAPT.setMaxDuration(7000);performAPT.setBitsPerSample(BitsPerSample._16_BIT);performAPT.setAudioType(AudioType.PCM);performAPT.setMuteAudio(false);

proxy.sendRPCRequest(performAPT);

FORD HMI

Gathering Audio Data

SDL provides audio data as fast as it can gather it, and sends it to the

developer in chunks. In order to retrieve this audio data, observe the

OnAudioPassThru notification in the onOnAudioPassThru callback of your Sdl

Service:

N O T E

Currently, Ford's SYNC 3 vehicles only support a sampling rates of

16 khz and a bit rate of 16.

@Overridepublic void onOnAudioPassThru(OnAudioPassThru notification) {

byte[] dataRcvd; dataRcvd = notification.getAPTData();

processAPTData(dataRcvd); // Do something with audio data}

N O T E

This audio data is only the current audio data, so the developer

must be in charge of managing previously retrieved audio data.

Ending Audio Capture

AudioPassThru is a request that works in a different way when compared to

other RPCs. For most RPCs a request is followed by an immediate response that

informs the developer whether or not that RPC was successful. This RPC,

however, will only send out the response when the Perform Audio Pass Thru is

ended.

Audio Capture can be ended in 4 ways:

1. AudioPassThru has timed out.

If the audio passthrough has proceeded longer than the requested timeout

duration, Core will end this request and send a

PerformAudioPassThruResponse with a Result of SUCCESS . You should

expect to handle this audio passthrough as though it was successful.2. AudioPassThru was closed due to user pressing "Cancel".

If the audio passthrough was displayed, and the user pressed the "Cancel"

button, you will receive a PerformAudioPassThruResponse with a Result

of ABORTED . You should expect to ignore this audio pass through.3. AudioPassThru was closed due to user pressing "Done".

If the audio passthrough was displayed, and the user pressed the "Done"

button, you will receive a PerformAudioPassThruResponse with a Result

of SUCCESS . You should expect to handle this audio passthrough as

though it was successful.4. AudioPassThru was ended due to the developer ending the request.

If the audio passthrough was displayed, but you have established on your

own that you no longer need to capture audio data, you can send an

EndAudioPassThru RPC.

EndAudioPassThru endAPT = new EndAudioPassThru();proxy.sendRPCRequest(endAPT);

You will receive an EndAudioPassThruResponse and a

PerformAudioPassThruResponse with a Result of SUCCESS , and should

expect to handle this audio passthrough as though it was successful.

Handling the Response

To process the response that we received from an ended audio capture, we

monitor the PerformAudioPassThruResponse through the callback in the Sdl

Service. If the response has a successful Result , all of the audio data for the

passthrough has been received and is ready for processing.

Mobile Navigation

Mobile Navigation allows map partners to bring their applications into the car

and display their maps and turn by turn easily for the user. This feature has a

different behavior on the head unit than normal applications. The main

differences are:

• Navigation Apps don't use base screen templates. Their main view is the

video stream sent from the device

@Overridepublic void onPerformAudioPassThruResponse(PerformAudioPassThruResponse response) { Result result = response.getResultCode();

if(result.equals(Result.SUCCESS)){ // We can use the data }else{ // Cancel any usage of the data Log.e("SdlService", "Audio pass thru attempt failed."); }}

• Navigation Apps can send audio via a binary stream. This will attenuate

the current audio source and should be used for navigation commands• Navigation Apps can receive touch events from the video stream

Connecting an app

The basic connection is the similar for all apps. Please follow Getting Started >

Integration Basics for more information.

The first difference for a navigation app is the appHMIType of NAVIGATION

that has to be set in the creation of the SdlProxyALM . Navigation apps are also

non-media apps.

The second difference is a property called securityManagers that needs to be

set in the SdlProxyBuilder.Builder if connecting to a version of Core that

requires secure video & audio streaming. This property requires an array of

classes of Security Managers, which will extend the SdlSecurityBase class.

These security libraries are provided by the OEMs themselves, and will only

work for that OEM. There is not a general catch-all security library.

N O T E

In order to use SDL's Mobile Navigation feature, the app must have

a minimum requirement of Android 4.4 (SDK 19). This is due to

using Android's provided video encoder.

After being registered, the app will start receiving callbacks. One important

callback is onOnHMIStatus , which informs the app about the currently visible

application on the head unit. Right after registering, the hmiLevel will be

NONE or BACKGROUND . Streaming should commence once the hmiLevel

has been set to FULL by the head unit.

Video Streaming

In order to stream video from an SDL app, we only need to manage a few

things. For the most part, the library will handle the majority of logic needed to

perform video streaming.

SdlProxyBuilder.Builder builder = new SdlProxyBuilder.Builder(this,APP_ID, APP_NAME, false, getApplicationContext());

Vector<AppHMIType> hmiTypes = new Vector<AppHMIType>();hmiTypes.add(AppHMIType.NAVIGATION);builder.setVrAppHMITypes(hmiTypes);

List<? extends SdlSecurityBase> securityManagers = new ArrayList();securityManagers.add(OEMSecurityManager1.class);securityManagers.add(OEMSecurityManager1.class);builder.setSdlSecurity(securityManagers);

proxy = builder.build();

N O T E

When compiling, you must make sure to include all possible OEM's

security managers that you wish to support.

SDLProxyALM

It is important that we create our SDLProxyALM instance with the correct

settings in order to stream video. This was already covered in the Mobile

Navigation > Introduction.

SDL Remote Display

The SdlRemoteDisplay base class provides the easiest way to start streaming

using SDL. The SdlRemoteDisplay is extended from Android's Presentation

class with modifications to work with other aspects of the SDL Android library.

Extending this class gives developers a familiar, native experience to handling

layouts and events on screen.

N O T E

It is recommended that you extend this as a local class within the

service that you have the SDLProxyALM instance.

Managing the Stream

The only thing left to do to start the stream is combine the SDLProxyALM

instance and the extension of the SdlRemoteDisplay . This should happen

when your app receives its first HMI_FULL status in the onOnHMIStatus

(OnHMIStatus notification) callback. The method that needs to be called is

startRemoteDisplayStream(Context context, final Class<? extends

SdlRemoteDisplay> remoteDisplay, final VideoStreamingParameters

parameters, final boolean encrypted) from the SDLProxyALM .

public static class MyDisplay extends SdlRemoteDisplay{ public MyDisplay(Context context, Display display) { super(context, display); }

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);

setContentView(R.layout.sdl);

final Button button1 = (Button) findViewById(R.id.button_1);

button1.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { Log.d(TAG, "Received motion event for button1"); } }); }}

Ending the Stream

When the HMIStatus is back to HM_NONE it is time to stop the stream. This

is accomplished through a method stopRemoteDisplayStream() in the

SDLProxyALM .

Setting Security Level for Multiplexing

When connecting to Core via Multiplex Bluetooth transport, your SDL app will

use a Router Service housed within your app or another SDL enabled app.

To help ensure the validility of the Router Service, you can select the security

level explicity when you create your Multiplex Bluetooth transport in your app's

SdlService:

@Overridepublic void onOnHMIStatus(OnHMIStatus notification) { if(notification.getHmiLevel().equals(HMILevel.HMI_FULL)){ if (notification.getFirstRun()) { proxy.startRemoteDisplayStream(getApplicationContext(), MyDisplay.class, null, false); } }

}

int securityLevel = FLAG_MULTI_SECURITY_MED;

BaseTransport transport = MultiplexTransportConfig(context, appId, securityLevel);

If you create the transport without specifying the security level, it will be set to

FLAG_MULTI_SECURITY_MED by default.

Security Levels

S E C U R I T Y F L A G M E A N I N G

Applying to the Trusted Router ServiceList

To get your app onto the Trusted Router Service List, please contact the SDL

Android channel on Slack or email sdladmin@livio.io. We'll need to test and

review your app before approving it for the trusted list.

FLAG_MULTI_SECURITY_OFF Multiplexing security turned off. All routerservices are trusted.

FLAG_MULTI_SECURITY_LOW

Multiplexing security will be minimal.Only trusted router services will be used.Trusted router list will be obtained fromserver. List will be refreshed every 20days or during next connection session ifan SDL enabled app has been installed oruninstalled.

FLAG_MULTI_SECURITY_MED

Multiplexing security will be on at anormal level. Only trusted router serviceswill be used. Trusted router list will beobtained from server. List will berefreshed every 7 days or during nextconnection session if an SDL enabled apphas been installed or uninstalled.

FLAG_MULTI_SECURITY_HIGH

Multiplexing security will be very strict.Only trusted router services installedfrom trusted app stores will be used.Trusted router list will be obtained fromserver. List will be refreshed every 7 daysor during next connection session if anSDL enabled app has been installed oruninstalled.

Handling a Language Change

When a user changes the language on a head unit, the onProxyClosed()

callback will be called in your app's Sdl Service and your app will disconnect

from Core. In order for your app to automatically reconnect to the head unit,

there are a few changes to make in the following files:

• local Sdl Broadcast Receiver• local Sdl Service

Sdl Broadcast Receiver

When the Sdl Service's connection to core is closed, we want to tell our local

Sdl Broadcast Receiver to restart the Sdl Service. To do this, first add a public

String in your app's local Sdl Broadcast Receiver class that can be included as

an extra in a broadcast intent.

N O T E

This guide applies if your app uses the Multiplex Bluetooth

transport

N O T E

This guide assumes you have set your app up for Bluetooth

Multiplexing using the Upgrading to Multiplexing guide

public static final String RECONNECT_LANG_CHANGE =

"RECONNECT_LANG_CHANGE";

Then, override the onReceive() method of the local Sdl Broadcast Receiver to

call onSdlEnabled() when receiving that action:

@Overridepublic void onReceive(Context context, Intent intent) { super.onReceive(context, intent); // Required if overriding this method

if (intent != null) { String action = intent.getAction(); if (action != null){ if(action.equalsIgnoreCase(TransportConstants.START_ROUTER_SERVICE_ACTION)) { if (intent.getBooleanExtra(RECONNECT_LANG_CHANGE, false)) { onSdlEnabled(context, intent); } } } }}

M U S T

Be sure to call super.onReceive(context, intent); at the start of the

method!

N O T E

This guide also assumes your local Sdl Broadcast Receiver

implements the onSdlEnabled() method as follows:

Sdl Service

Without accounting for a language change, your Sdl Service's onProxyClosed()

method probably looked similar to this:

We want to tell our local Sdl Broadcast Receiver to restart the service when the

reason for closing is a language change. To do so, modify the method as

follows:

@Overridepublic void onSdlEnabled(Context context, Intent intent) { intent.setClass(context, SdlService.class); context.startService(intent);}

@Overridepublic void onProxyClosed(String info, Exception e, SdlDisconnectedReason reason) { stopSelf();}

System Capability Manager

The System Capability Manager is a central location to obtain capabilities about

the currently connected module. Specific capabilities will be returned for a

number of given keys (e.g. NAVIGATION , VIDEO_STREAMING ). It also

alleviates the need to individually cache results that come from the

RegisterAppInterface response or from the new SystemCapabilityQuery .

There are multiple capabilities that can be retrieved:

@Overridepublic void onProxyClosed(String info, Exception e, SdlDisconnectedReason reason) { stopSelf(); if(reason.equals(SdlDisconnectedReason.LANGUAGE_CHANGE)){ Intent intent = new Intent(TransportConstants.START_ROUTER_SERVICE_ACTION); intent.putExtra(SdlReceiver.RECONNECT_LANG_CHANGE, true); sendBroadcast(intent); }}

S U P P O RT E D C A PA B I L I T I E S

Querying Capabilities

Any point after receiving the first OnHMIStatus notification from the

connected module, you can access the SystemCapability manager and its

data. Your instance of SdlProxyALM will have convenience methods that tie

into the SystemCapabilityManager .

NAVIGATION

PHONE_CALL

VIDEO_STREAMING

REMOTE_CONTROL

HMI

DISPLAY

AUDIO_PASSTHROUGH

BUTTON

HMI_ZONE

PRESET_BANK

SOFTBUTTON

SPEECH

VOICE_RECOGNITION

For example (obtaining the head unit's NAVIGATION capability):

The returned capability needs to be casted into the capability type you

requested. From there you can determine whether or not the head unit that the

app is connected to can utilize a feature or not.

N O T E

It is important to query capabilities before you use them. Your app

may be used on a variety of head units across different

manufacturers and software versions. Never assume that a

capability exists.

// First you can check to see if the capability is supported on the module if (proxy.isCapabilitySupported(SystemCapabilityType.NAVIGATION){ // Since the module does support this capability we can query it for more information proxy.getCapability(SystemCapabilityType.NAVIGATION, new OnSystemCapabilityListener(){

@Override public void onCapabilityRetrieved(Object capability){ NavigationCapability navCapability = (NavigationCapability) capability; // Now it is possible to get details on how this capability // is supported using the navCapability object }

@Override public void onError(String info){ Log.i(TAG, "Capability could not be retrieved: "+ info); } }); }

Capability Lists

There are currently 3 responses that come back as Lists:

AUDIO_PASSTHROUGH , BUTTON , and SOFTBUTTON . We've created a

method in the SystemCapabilityManager to help cast these lists. Below is an

example of its usage:

This method prevents the developer from having to suppress a warning as well

as creates a safe way to cast the object to a list.

Asynchronous vs Synchronous Queries

Some capabilities will be instantly available after the first OnHMIStatus

notification. These are parsed from the RegisterAppInterface response.

However, some capabilities MUST be obtained asynchronously and therefore

require a callback to be obtained. If a capability can be retrieved synchronously

public void getCapabilities() {

proxy.getCapability(SystemCapabilityType.BUTTON, new OnSystemCapabilityListener(){

@Override public void onCapabilityRetrieved(Object capability){ List<ButtonCapabilities> buttonCapabilityList = SystemCapabilityManager.convertToList(capability, ButtonCapabilities.class);

}

@Override public void onError(String info){ Log.i(TAG, "Capability could not be retrieved: "+ info); } }); }

another method can be used via the SdlProxyALM object, proxy.getCapability

(SystemCapabilityType) .

C A PA B I L I T Y A S Y N C R E Q U I R E D

NAVIGATION Yes

PHONE_CALL Yes

VIDEO_STREAMING Yes

REMOTE_CONTROL Yes

HMI No

DISPLAY No

AUDIO_PASSTHROUGH No

BUTTON No

HMI_ZONE No

PRESET_BANK No

SOFTBUTTON No

SPEECH No

VOICE_RECOGNITION No

Remote Control

Remote Control provides a framework to allow apps to control certain safe

modules within a vehicle.

Consider the following scenarios:

• A radio application wants to use the in-vehicle radio tuner. It needs the

functionality to select the radio band (AM/FM/XM/HD/DAB), tune the radio

frequency or change the radio station, as well as obtain general radio

information for decision making.• A climate control application needs to turn on the AC, control the air

circulation mode, change the fan speed and set the desired cabin

temperature.• A user profile application wants to remember users' favorite settings and

apply it later automatically when the users get into the same/another

vehicle.

Currently, the Remote Control feature supports these modules:

N O T E

Not all vehicles have this functionality. Even if they support remote

control, you will likely need to request permission from the vehicle

manufacturer to use it.

WHY IS THIS HELPFUL?

S U P P O RT E D R C M O D U L E S

The following table lists what control items are in each control module.

Radio

Climate

R CM O D U L E

C O N T R O LI T E M

VA LU ER A N G E

T Y P EC O M M E NT S

Radio RadioEnabled true,false Get/Set/

Notification

read only,all otherradiocontrolitems needradioenabled towork

Radio Band AM,FM,XM Get/Set/Notification

RadioFrequency

Get/Set/Notification

valuerangedependson band

Radio RDSData

Get/Notification read only

Available HDChannel 1-3 Get/

Notification read only

Current HDChannel 1-3 Get/Set/

Notification

Radio SignalStrength

Get/Notification read only

SignalChangeThreshold

Get/Notification read only

Radio State

Acquiring,acquired,multicast,not_found

Get/Notification read only

ClimateCurrentCabinTemperature

Get/Notification

read only,valuerangedependson OEM

DesiredCabinTemperature

Get/Set/Notification

valuerangedependson OEM

AC Setting on, off Get/Set/Notification

AC MAXSetting on, off Get/Set/

Notification

AirRecirculationSetting

on, off Get/Set/Notification

Auto ACMode Setting on, off Get/Set/

Notification

Defrost ZoneSetting

front, rear,all, none

Get/Set/Notification

R CM O D U L E

C O N T R O LI T E M

VA LU ER A N G E

T Y P EC O M M E NT S

Remote Control can also allow mobile applications to send simulated button

press events for the following common buttons in the vehicle.

The system shall list all available buttons for Remote Control in the

RemoteControlCapabilities . The capability object will have a List of

ButtonCapabilities that can be obtained using getButtonCapabilities() .

Dual ModeSetting on, off Get/Set/

Notification

Fan SpeedSetting 0%-100% Get/Set/

Notification

VentilationMode Setting

upper, lower,both, none

Get/Set/Notification

R C M O D U L E C O N T R O L B U T T O N

Climate AC

AC MAX

RECIRCULATE

FAN UP

FAN DOWN

TEMPERATURE UP

TEMPERATURE DOWN

DEFROST

DEFROST REAR

DEFROST MAX

UPPER VENT

LOWER VENT

Radio VOLUME UP

VOLUME DOWN

EJECT

SOURCE

SHUFFLE

REPEAT

Integration

To check for this capability, use the following call:

N O T E

For Remote Control to work, the head unit must support SDL Core

Version 4.4 or newer

SYSTEM CAPABIL ITY

M U S T

Prior to using using any Remote Control RPCs, you must check that

the head unit has the Remote Control capability. As you may

encounter head units that do not support it, this check is important.

It is possible to retrieve current data relating to these Remote Control modules.

The data could be used to store the settings prior to setting them, saving user

preferences, etc. Following the check on the system's capability to support

Remote Control, we can actually retrieve the data. The following is an example

of getting data about the RADIO module. It also subscribes to updates to radio

data, which will be discussed later on in this guide.

// First you can check to see if the capability is supported on the module if (proxy.isCapabilitySupported(SystemCapabilityType.REMOTE_CONTROL){ // Since the module does support this capability we can query it for more information proxy.getCapability(SystemCapabilityType.REMOTE_CONTROL, new OnSystemCapabilityListener(){

@Override public void onCapabilityRetrieved(Object capability){ RemoteControlCapabilities remoteControlCapabilities = (RemoteControlCapabilities) capability; // Now it is possible to get details on how this capability // is supported using the remoteControlCapabilities object }

@Override public void onError(String info){ Log.i(TAG, "Capability could not be retrieved: "+ info); } }); }

GETTING DATA

Of course, the ability to set these modules is the point of Remote Control.

Setting data is similar to getting it. Below is an example of setting

ClimateControlData .

GetInteriorVehicleData interiorVehicleData = new GetInteriorVehicleData(); interiorVehicleData.setModuleType(ModuleType.RADIO); interiorVehicleData.setSubscribe(TRUE); interiorVehicleData.setOnRPCResponseListener(new OnRPCResponseListener() { @Override public void onResponse(int correlationId, RPCResponse response) { GetInteriorVehicleData getResponse = (GetInteriorVehicleData) response; //This can now be used to retrieve data } });

proxy.sendRPCRequest(interiorVehicleData);

SETTING DATA

It is likely that you will not need to set all the data as it is in the example, so if

there are settings you don't wish to modify, then you don't have to.

Another unique feature of Remote Control is the ability to send simulated

button presses to the associated modules, imitating a button press on the

hardware itself.

Simply specify the module, the button, and the type of press you would like:

Temperature temp = new Temperature(); temp.setUnit(TemperatureUnit.FAHRENHEIT); temp.setValue((float) 74.1);

ClimateControlData climateControlData = new ClimateControlData(); climateControlData.setAcEnable(TRUE); climateControlData.setAcMaxEnable(TRUE); climateControlData.setAutoModeEnable(FALSE); climateControlData.setCirculateAirEnable(TRUE); climateControlData.setCurrentTemperature(temp); climateControlData.setDefrostZone(DefrostZone.FRONT); climateControlData.setDualModeEnable(TRUE); climateControlData.setFanSpeed(2); climateControlData.setVentilationMode(VentilationMode.BOTH); climateControlData.setDesiredTemperature(temp);

ModuleData moduleData = new ModuleData(); moduleData.setModuleType(ModuleType.CLIMATE); moduleData.setClimateControlData(climateControlData);

SetInteriorVehicleData setInteriorVehicleData = new SetInteriorVehicleData(); setInteriorVehicleData.setModuleData(moduleData);

proxy.sendRPCRequest(setInteriorVehicleData);

BUTTON PRESSES

It is also possible to subscribe to changes in data associated with supported

modules.

To do so, during your GET request for data, simply add in setSubscribe

(Boolean) . To unsubscribe, send the request again with the boolean set to

False . A code sample for setting the subscription is in the GET example

above.

The response to a subscription will come in a form of a notification. You can

receive this notification through the IProxyListenerALM that was supplied to

the SdlProxyALM object; the method onOnInteriorVehicleData will be called

when the RPC is received.

U S I N G IPROXYLISTENERALM

ButtonPress buttonPress = new ButtonPress(); buttonPress.setModuleType(ModuleType.RADIO); buttonPress.setButtonName(ButtonName.EJECT); buttonPress.setButtonPressMode(ButtonPressMode.SHORT);

proxy.sendRPCRequest(buttonPress);

SUBSCRIBING TO CHANGES

@Override public void onOnInteriorVehicleData(OnInteriorVehicleData response) { //Perform action based on notification }

S E TT I N G N O T I F I C AT I O N L I S T E N E R

AddCommand

Adds a Command to the application's Command Menu.

A Command will be added to the end of the list of elements in the Command

Menu under the following conditions:

• When a Command is added with no MenuParams value provided• When a MenuParams value is provided with a MenuParam.position value

greater than or equal to the number of menu items currently defined in

the menu specified by the MenuParam.parentID value

The set of choices which the application builds using AddCommand can be a

mixture of:

• Choices having only VR synonym definitions, but no MenuParams

definitions• Choices having only MenuParams definitions, but no VR synonym

definitions• Choices having both MenuParams and VR synonym definitions

When a user initiates an interaction, the user may choose from whatever

choices are defined at that moment. It is up to the application to ensure that all

appropriate choices are defined before the user initiates an interaction.

proxy.addOnRPCNotificationListener(FunctionID.ON_INTERIOR_VEHICLE_DATA, new OnRPCNotificationListener() { @Override public void onNotified(RPCNotification notification) { OnInteriorVehicleData onInteriorVehicleData = (OnInteriorVehicleData)notification; //Perform action based on notification } });

Note: A consequence of this is that it is possible for the application to be in the

middle of adding commands (or submenu items) when the user presses the PTT

or Menu button and only the commands added up to that moment will be

available for the user to choose from (either by VR or Menu). It is possible in

this situation for the user to not have had all intended options available when

they started the interaction. The application will receive an OnHMIStatus with a

SystemContext value of VRSESSION or MENU indicating that such a user-

initiated interaction has begun. The application can make use of this

notification to know that, if it is still building a Command Menu using

AddCommand/AddSubMenu, the results of the interaction should be discarded.

This approach is necessary because there is no way to "cancel" an interaction

in progress (neither a user initiated interaction, nor an app-initiated

interaction).

Note: smartdevicelink™ batches together AddCommand and AddSubMenu

requests before making them available for selection by the user via PTT or the

menu. The end of a batch of successive AddCommand/AddSubMenu requests is

defined as 500 milliseconds passing with no further AddCommand/AddSubMenu

requests arriving at SDL®. When the batch of requests has ended, SDL® then

prepares these commands for use by the user. A command should be available

for use 1 second after the end of the batch in which that command was added

(timing based batch size).

Note: Commands should be “grouped” by using position id. If you are planning

to create child commands of a parent command to keep the commands

grouped together. Add the commands to the top level menu (basically the root);

you can pass in a 0 for the parentID. If you would like to add the commands to

a submenu, then the submenuID is passed in for the parentID.

The position ID can be used to sort the commands in the menu. However, the

logic isn't always straightforward. The position is relative to the commands that

are currently in existence. However, once commands are added, they drop the

Position parameter and the sync hardware just tracks their sequential order.

For example: send add: command1, Position 5 send add: command2, Position

10 send add: command3, Position 20

Results in on tdk: command1, command2, command3

If you then followed up with: send add: command4, Position 1

You get the following result on the TDK: command1, command4, command2,

command3

There are a few other noteworthy consequences of MenuParams for a given

command:

- Commands that do not have vrCommands associated with them will not be

accessible by voice commands (when the user hits push-to-talk).

- Commands that do not have menuParams associated with them will not be

accessible through the HMI application menu

HMI Status Requirements

HMILevel needs to be FULL, LIMITED, or BACKGROUND.

REQUEST

Parameter List

ParamName Type Descript

ion Req. Notes

VersionAvailable

cmdID Integer

unique IDof thecommandto add

Y

minvalue:0maxvalue:2000000000

SmartDeviceLink 1.0

menuParams

ButtonName

Name ofthebutton tounsubscribe.

YSmartDeviceLink 1.0

vrCommands String

An arrayof stringsto beused asVRsynonyms for thiscommand.If thisarray isprovided,it maynot beempty.

Nminsize:1maxsize:100

SmartDeviceLink 1.0

cmdIcon Image

Imagestructdeterminingwhetherstatic ordynamicicon.If omittedonsupporteddisplays,no (or thedefault ifapplicable) iconshall bedisplayed.

NSmartDeviceLink 1.0

RESPONSE

Indicates that the corresponding request has failed or succeeded, if the

response returns with a SUCCESS result code, this means a command was

added to the Command Menu successfully.

Non-default Result Codes:

• SUCCESS• INVALID_DATA• OUT_OF_MEMORY• TOO_MANY_PENDING_REQUESTS• APPLICATION_NOT_REGISTERED• GENERIC_ERROR• REJECTED• INVALID_ID• DUPLICATE_NAME• UNSUPPORTED_RESOURCE• DISALLOWED

Related Operations

• DeleteCommand• AddSubMenu• DeleteSubMenu

Example Function Call

commandReq = RPCRequestFactory.buildAddCommand(100, "Skip", new Vector<String>(Arrays.asList(new String[] {"Skip"})), autoIncCorrID++);_sdlProxy.sendRPCRequest(commandReq);

DeleteCommand

Removes a command from the Command Menu

For a discussion of conflict with user-initiated interaction, see AddCommand.

HMI Status Requirements

HMILevel needs to be FULL, LIMITED, or BACKGROUND.

REQUEST

Parameter List

Name Type Description Reg. Notes Versio

n

RESPONSE

Indicates that the corresponding request either failed or succeeded. If the

response returns with a SUCCESS result code, this means a command was

removed from the Command Menu successfully.

Non-default Result Codes:

• SUCCESS• INVALID_DATA• OUT_OF_MEMORY• TOO_MANY_PENDING_REQUESTS• APPLICATION_NOT_REGISTERED• GENERIC_ERROR• REJECTED• INVALID_ID• IN_USE

Related Operations

• AddCommand• AddSubMenu

cmdID Integer

Unique IDthatidentifiestheCommand to bedeletedfromCommand Menu

Y

MinValue: 0MaxValue:2000000000

SmartDeviceLink 1.0

• DeleteSubMenu

Example Function Call

AddSubMenu

Adds a SubMenu to the Command Menu A SubMenu can only be added to the

Top Level Menu (i.e. a SubMenu cannot be added to a SubMenu), and may only

contain commands as children.

For a discussion of conflict with user-initiated interaction, see AddCommand.

HMI Status Requirements

HMILevel needs to be FULL, LIMITED, or BACKGROUND.

REQUEST

Parameter List

DeleteCommand req;req = RPCRequestFactory.buildDeleteCommand(commandID, autoIncCorrID++);_sdlProxy.sendRPCRequest(req);

ParamName Type Descript

ion Req. Notes

VersionAvailable

menuID Integer

Unique IDthatidentifiesthis submenu.Thisvalue isused inAddCommand towhichSubMenuis theparent ofthecommandbeingadded.

YSmartDeviceLink 1.0

position Integer

Positionwithin theitems ofthe toplevelCommand Menu. 0will insertat thefront, 1will insertafter thefirstexistingelement,etc.Positionof anysubmenuwillalways belocatedbeforethe returnand exitoptions.

N

MinValue: 0 MaxValue:1000If positionis greateror equalthan thenumberof itemson toplevel, thesub menuwill beappendedby theend.If thisparameter isomitted,the entrywill beadded atthe endof the list.

SmartDeviceLink 1.0

menuName String

Textwhich isdisplayedrepresenting thissubmenuitem

Y maxlength:500

SmartDeviceLink 1.0

RESPONSE

Indicates that the corresponding request either failed or succeeded. If the

response returns with a SUCCESS result code, this means the SubMenu was

added to the Command Menu successfully

Non-default Result Codes:

Related Operations

- DeleteSubMenu

- AddCommand

- DeleteCommand

Example Function Call

- SUCCESS- INVALID_DATA- OUT_OF_MEMORY- TOO_MANY_PENDING_REQUESTS- APPLICATION_NOT_REGISTERED- GENERIC_ERROR- REJECTED - INVALID_ID- DUPLICATE_NAME

RPCMessage req;req = RPCRequestFactory.buildAddSubMenu(menuID, menuName,autoIncCorrID++);_sdlProxy.sendRPCRequest(req);

DeleteSubMenu

Deletes a submenu from the Command Menu.

For a discussion of conflict with user-initiated interaction, see AddCommand.

When an app deletes a submenu that has child commands, those child

commands are also deleted.

HMI Status Requirements

HMILevel needs to be FULL, LIMITED, or BACKGROUND.

REQUEST

Parameter List

Name Type Description Reg. Notes Versio

n

RESPONSE

Non-default Result Codes:

• SUCCESS• INVALID_DATA• OUT_OF_MEMORY• TOO_MANY_PENDING_REQUESTS• APPLICATION_NOT_REGISTERED• GENERIC_ERROR• REJECTED• INVALID_ID• IN_USE

Related Operations

• AddCommand• AddSubMenu• DeleteCommand

Example Function Call

menuID Integer

Unique IDthatidentifiestheSubMenuto bedelete

Y

MinValue: 0MaxValue:2000000000

SmartDeviceLink 1.0

RPCMessage req;req = RPCRequestFactory.buildDeleteSubMenu(menuID, autoIncCorrID++);_sdlProxy.sendRPCRequest(req);

Alert

Provides information to the user using either TTS, the Display or both and can

include a system-generated alert tone.

• The displayed portion of the Alert, if any, will persist until the specified

timeout has elapsed, or the Alert is preempted.• An Alert will preempt (abort) any smartdevicelink Operation that is in-

progress, except an already-in-progress Alert.• An Alert cannot be preempted by any smartdevicelink Operation.• An Alert can be preempted by a user action (button push).• An Alert will fail if it is issued while another Alert is in progress. Assuming

it's coming from the same app, the current Alert gets ABORTED and the

new Alert will get displayed/audible.• Although each Alert parameter is optional, in fact each Alert request must

supply at least one of the following parameters:• alertText1• alertText2• alertText3• ttsChunks

HMI Status Requirements

HMILevel needs to be FULL or LIMITED.

If the app has been granted function group Notification the HMILevel can also

be BACKGROUND

REQUEST

Name Type Description Req. Notes

VersionAvailable

alertText1 String

Text to bedisplayedin thefirst fieldof thedisplayduringthe Alert.

N

Length islimited towhat isindicatedinRegisterAppInterfaceresponse.Ifomitted,topdisplayline willbecleared.Text isalwayscentered

SmartDeviceLink 1.0

alertText2 String

Text to bedisplayedin thesecondfield ofthedisplayduringthe Alert.

N

Onlypermittedif HMIsupportsa seconddisplayline.Length islimited towhat isindicatedinRegisterAppInterfaceresponse.Ifomitted,seconddisplayline willbecleared.

SmartDeviceLink 1.0

alertText3 String

Text to bedisplayedin thethird fieldof thedisplayduringthe Alert.

N

Arraymusthave aleast oneelement.

SmartDeviceLink 1.0

ttsChunks

TTSChunk[]

Array oftypeTTSChunkwhich,takentogether,specifywhat is tobespoken tothe user.

N

Arraymusthave aleast oneelement.

SmartDeviceLink 1.0

duration Integer

Thedurationof thedisplayedportion ofthe alert,inmilliseconds.After thisamountof timehaspassed,thedisplayfieldsalertText1andalertText2will revertto whatwasdisplayedin thosefieldsbeforethe alertbegan.

N

MinValue:3000 MaxValue:10000Ifomitted,thedefault is5000milliseconds

SmartDeviceLink 1.0

playTone Boolean

Specifieswhetherthe alerttoneshould beplayedbeforethe TTS(if any) isspoken.

N

Ifomitted,default istrue.

SmartDeviceLink 1.0

softButtons

SoftButton[]

Specifiesthesoftbuttons, theappswants touse inthis alert.

If omittedonsupporteddisplays,the alertwill nothave anySoftButton.ArrayMin:0ArrayMax: 4

SmartDeviceLink 1.0

RESPONSE

If a resultCode of "SUCCESS" is returned, the request was accepted by SDL. By

the time the corresponding response is received, the Alert will have completed.

Non-default Result Codes:

progressIndicator

Boolean

Ifsupported on thegivenplatform,the alertGUI willincludesome sortofanimationindicatingthatloading ofa featureisprogressing. e.g. aspinningwheel orhourglass, etc.

NSmartDeviceLink 1.0

- SUCCESS- INVALID_DATA- OUT_OF_MEMORY- TOO_MANY_PENDING_REQUESTS- APPLICATION_NOT_REGISTERED- GENERIC_ERROR - REJECTED- ABORTED- DISALLOWED- USER_DISALLOWED- UNSUPPORTED_RESOURCE

Name Type Description Req. Notes

VersionAvailable

Related Operations

Show

Speak

tryAgainTime Integer

Amountof time(inseconds)that anapp mustwaitbeforeresendingan alert.

N

Ifprovided,anothersystemevent oroverlaycurrentlyhas ahigherprioritythan thisalert.An appmust notsend analertwithoutwaiting atleast theamountof timedictated.

smartdevicelink1.0

Example Function Call

CreateInteractionChoiceSet

Creates a Choice Set which can be used in subsequent PerformInteraction

Operations.

A Choice Set is a list of commands (menu or voice) that can be used in certain

operations to gain input from the user. Multiple Choices with the same id can be

added to SDL from one application.

HMI Status Requirements

HMILevel needs to be FULL, LIMITED, or BACKGROUND.

REQUEST

Alert req;req = RPCRequestFactory.buildAlert(ttsText, _mainInstance.logTag, alertText2, playTone, duration, autoIncCorrID++);_sdlProxy.sendRPCRequest(req);

Name Type Description Reg. Notes Versio

n

Note:

Second Utterance issue with CreateInteractionChoiceSet RPC.

Before a perform interaction

is sent you MUST wait for the success from the CreateInteractionChoiceSet RPC.

If you do not wait the system may not recognize the first utterance from the

user.

Response

Indicates that the corresponding request either failed or succeeded. If the

response returns with a SUCCESS result code, this means the Choice Set was

created.

Non-default Result Codes:

interactionChoiceSetID

Integer

A uniqueID thatidentifiestheChoiceSet

Y

MinValue: 0MaxValue:2000000000

SmartDeviceLink 1.0

choiceSet Choice[]

Array ofone ormoreelements.

Y

MinValue: 1MaxValue:100

SmartDeviceLink 1.0

Related Operations

DeleteInteractionChoiceSet

PerformInteraction

Example Function Call

DeleteInteractionChoiceSet

Deletes an existing Choice Set identified by the parameter

interactionChoiceSetID. If the specified interactionChoiceSetID is currently in

use by an active PerformInteraction, this call to delete the Choice Set will fail

returning an IN_USE resultCode.

- SUCCESS- INVALID_DATA- OUT_OF_MEMORY- TOO_MANY_PENDING_REQUESTS- APPLICATION_NOT_REGISTERED- GENERIC_ERROR- REJECTED- INVALID_ID- DUPLICATE_NAME- UNSUPPORTED_RESOURCE

RPCMessage req;req = RPCRequestFactory.buildCreateInteractionChoiceSet(_choiceSet, choiceSetID, autoIncCorrID++);_sdlProxy.sendRPCRequest(req);

HMI Status Requirements

HMILevel needs to be FULL, LIMITED, or BACKGROUND.

REQUEST

Name Type Description Reg. Notes Versio

n

interactionChoiceSetID

Integer

A uniqueID thatidentifiestheChoiceSet(specifiedin apreviouscall toCreateInteractionChoiceSet)

Y

MinValue: 0 MaxValue:2000000000

SmartDeviceLink 1.0

If a resultCode of "SUCCESS" is returned, the requested choice set has been

created and can now be referenced by the application using the value of

interactionChoiceSetID provided by the application.

Related Operations

CreateInteractionChoiceSet

PerformInteraction

RESPONSE

NON-DEFAULT RESULT CODES:

- SUCCESS- INVALID_DATA- OUT_OF_MEMORY- TOO_MANY_PENDING_REQUESTS- APPLICATION_NOT_REGISTERED- GENERIC_ERROR- REJECTED- INVALID_ID- IN_USE

Example Function Call

RegisterAppInterface

Registers the application's interface with SDL, declaring properties of the

registration, including the messaging interface version, the app name, etc. The

mobile application must establish its interface registration with SDL before any

other interaction with SDL can take place. The registration lasts until it is

terminated either by the application calling the UnregisterAppInterface method,

or by SDL sending an OnAppInterfaceUnregistered notification, or by loss of the

underlying transport connection, or closing of the underlying message

transmission protocol RPC session.

Until the application receives its first OnHMIStatus Notification, its HMI Status is

assumed to be: HMILevel=NONE, AudioStreamingState=NOT_AUDIBLE,

SystemContext=MAIN.

All SDL resources which the application creates or uses (e.g. Choice Sets,

Command Menu, etc.) are associated with the application's interface

registration. Therefore, when the interface registration ends, the SDL resources

associated with the application are disposed of. As a result, even though the

application itself may continue to run on its host platform (e.g. mobile device)

after the interface registration terminates, the application will not be able to

use the SDL HMI without first establishing a new interface registration and re-

creating its required SDL resources. That is, SDL resources created by (or on

RPCMessage req;req = RPCRequestFactory.buildDeleteInteractionChoiceSet(choiceSetID, autoIncCorrID++); _sdlProxy.sendRPCRequest(req);

behalf of) an application do not persist beyond the life span of the interface

registration.

Resources and settings whose lifespan is tied to the duration of an application's

interface registration:

- Choice Sets

- Command Menus (built by successive calls to AddCommand)

- Media clock timer display value

- Media track display value

- Button subscriptions

The autoActivateID is used to grant an application the HMILevel and

AudioStreamingState it had when it last disconnected.

Note: The autoActivateID parameter, and associated behavior, is currently

ignored by SDL.

When first calling this method (i.e. first time within life cycle of mobile app), an

autoActivateID should not be included. After successfully registering an

interface, an autoActivateID is returned to the mobile application for it to use in

subsequent connections. If the connection between SDL and the mobile

application is lost, such as the vehicle is turned off while the application is

running, the autoActivateID can then be passed in another call to

RegisterAppInterface to re-acquire HMILevel=FULL.

If the application intends to stream audio it is important to indicate so via the

isMediaApp parameter. When set to true, audio will reliably stream without any

configuration required by the user. When not set, audio may stream, depending

on what the user might have manually configured as a media source on SDL®.

There is no time limit for how long the autoActivateID is "valid" (i.e. would

confer focus and opt-in)

HMI Status Requirements

HMILevel is not defined before registering.

REQUEST

Name Type Description Reg. Notes Versio

n

MsgVersion

MsgVersion

Declareswhatversion ofthe SDLinterfacetheapplication expectsto usewith SDL

Y

To becompatible, appmsgmajorversionnumbermust beless thanor equalto SDLmajorversionnumber. If msgversionsareincompatible, apphas 20secondstoattemptsuccessfulRegisterAppInterface (w.r.t.msgversion)onunderlying protocolsession,else willbeterminated. Majorversionnumber isacompatibilitydeclaration. Minorversionnumberindicatesminorfunctionalvariations(e.g.features,capabilities, bugfixes)whensent fromSDL toapp (inRegisterAppInterfaceresponse).However,the minorversionnumbersent fromthe appto SDL (inRegisterAppInterface

SmartDeviceLink 1.0

appName String

Themobileapplication's name.Thisname isdisplayedin theSDLMobileApplications menu.It alsoserves astheuniqueidentifierof theapplication for SDL.

Y

- Must be1-100characters inlength.- Mustconsist offollowingcharacters: - May notbe thesame (bycaseinsensitivecomparison) asthe nameor anysynonymof anycurrently-registeredapplication.

SmartDeviceLink 1.0

ttsName TTSChunk

TTS stringfor VRrecognition of themobileapplication name.Meant toovercomeanyfailing onspeechengine inproperlypronouncing /understanding appname.

N

- Sizemust be1-100- Needsto beuniqueover allapplications- May notbe empty.- May notstart witha newlinecharacter.

SmartDeviceLink 2.0

ngnMediaScreenAppName

String

Providesanabbreviatedversion ofthe appname (ifnecessary) thatwill bedisplayedon theNGNmediascreen.

N

- Must be1-5characters- If notprovided,value willbederivedfromappNametruncatedto 5characters.

SmartDeviceLink 1.0

vrSynonyms String

An arrayof 1-100elements,eachelementcontaining a voice-recognitionsynonymby whichthis appcan becalledwhenbeingaddressed in themobileapplications menu.

N

- Each vrsynonymis limitedto 40characters, andthere canbe 1-100synonyms in array-May notbe thesame (bycaseinsensitivecomparison) asthe nameor anysynonymof anycurrently-registeredapplication.

SmartDeviceLink 1.0

isMediaApplication

Boolean

Indicatesthat theapplication will bestreaming audioto SDL(viaA2DP)that isaudibleoutside ofthe BTmediasource.

YSmartDeviceLink 1.0

languageDesired

Language

Anenumerationindicatingwhatlanguagetheapplication intendsto use foruserinteraction(Display,TTS andVR).

Y

- If thelanguageindicateddoes notmatchthe activelanguageon SDL,theinterfaceregistration will berejected.- If theuserchangesthe SDLlanguagewhile thisinterfaceregistration isactive,theinterfaceregistration will beterminated.

SmartDeviceLink 1.0

hmiDisplayLanguageDesired

Language

Anenumerationindicatingwhatlanguagetheapplication intendsto use foruserinteraction (Display).

YSmartDeviceLink 2.0

appHMIType

AppHMIType

List of allapplicable apptypesstatingwhichclassifications to begiven totheapp.e.g.forplatformsthis willdetermine which"corner(s)" theapp canpopulate

N

ArrayMinsize: 1ArrayMaxsize:100

SmartDeviceLink 2.0

hashID String

ID usedtouniquelyidentifycurrentstate ofall appdata thatcanpersistthroughconnection cycles(e.g.ignitioncycles).Thisregistered data(commands,submenus, choicesets, etc.)can bereestablishedwithoutneedingtoexplicitlyreregistereachpiece.Ifomitted,then thepreviousstate ofan app'scommands, etc. willnot berestored.WhensendinghashID,allRegisterAppInterfaceparameters shouldstill beprovided(e.g.ttsName,etc.).

N maxlength:100

SmartDeviceLink 2.3.1

deviceInfo

DeviceInfo

Variousinformation aboutconnecting device.

NSmartDeviceLink 2.3.1

appID String

ID usedtovalidateapp withpolicytableentries

Y Maxlength: 100

SmartDeviceLink 2.0

RESPONSE

The response message contains essential information about the SDL system

that the request was sent to. This information can be used by an application to

alter functionality depending on which type of SDL system it is running on. For

instance, an application can use the displayCapabilities parameter to see

whether the SDL HMI offers a touch screen, a two-line display, or a one-line

display.

The application could then use that information to make sure that the text

written to the screen is readable for the given platform. If a resultCode other

than SUCCESS is received, the application will have to send one or more

RegisterAppInterface Requests until one has a result code of SUCCESS;

otherwise, the application is not permitted to send any other Requests.

Non-default Result Codes:

Related Operations

UnregisterAppInterface

OnAppInterfaceUnregistered

- SUCCESS- INVALID_DATA- OUT_OF_MEMORY- TOO_MANY_PENDING_REQUESTS- GENERIC_ERROR- DUPLICATE_NAME- TOO_MANY_APPLICATIONS- APPLICATION_REGISTERED_ALREADY- UNSUPPORTED_VERSION- WRONG_LANGUAGE- DISALLOWED

Example Function Call

```java

RegisterAppInterface req;

req = RPCRequestFactory.buildRegisterAppInterface(_mainInstance.logTag,

false, null);

_sdlProxy.sendRPCRequest(req);

```

UnregisterAppInterface

Terminates an application's interface registration. This causes SDL to dispose of

all resources associated with the application's interface registration (e.g.

Command Menu items, Choice Sets, button subscriptions, etc.).

After the UnregisterAppInterface operation is performed, no other operations

can be performed until a new app interface registration is established by calling

RegisterAppInterface.

This operation will fail if no interface registration is currently in effect (i.e. no

RegisterAppInterface operation was performed prior to this call).

HMI Status Requirements

HMILevel can be FULL, LIMITED, BACKGROUND or NONE.

REQUEST

Name Type Description Reg. Notes

SmartDeviceLinkVersion

gps Boolean

GPS data.SeeGPSDatafor details

N Subscribable

SmartDeviceLink 2.0

speed Boolean

Thevehiclespeed inkilometers perhour

N Subscribable

SmartDeviceLink 2.0

rpm Boolean

Thenumberofrevolutions perminute oftheengine

N Subscribable

SmartDeviceLink 2.0

fuelLevel Boolean

The fuellevel inthe tank(percentage)

N Subscribable

SmartDeviceLink 2.0

fuelLevel_State Boolean

The fuellevelstate

N Subscribable

SmartDeviceLink 2.0

instantFuelConsumption

Boolean

Theinstantaneous fuelconsumption inmicrolitres

N Subscribable

SmartDeviceLink 2.0

externalTemperature

Boolean

Theexternaltemperature indegreescelsius

N Subscribable

SmartDeviceLink 2.0

prndl BooleanCurrentlyselectedgear.

N Subscribable

SmartDeviceLink 2.0

tirePressure Boolean

Tirepressurestatus

N Subscribable

SmartDeviceLink 2.0

odometer Boolean Odomete

r in km NMaxLength:500

SmartDeviceLink 2.0

beltStatus Boolean

Thestatus ofthe seatbelts

N Subscribable

SmartDeviceLink 2.0

bodyInformation

Boolean

The bodyinformationincludingignitionstatusandinternaltemp

N Subscribable

SmartDeviceLink 2.0

deviceStatus Boolean

Thedevicestatusincludingsignalandbatterystrength

N Subscribable

SmartDeviceLink 2.0

driverBraking Boolean

Thestatus ofthe brakepedal

N Subscribable

SmartDeviceLink 2.0

wiperStatus Boolean

Thestatus ofthewipers

N Subscribable

SmartDeviceLink 2.0

headLampStatus

BooleanStatus ofthe headlamps

N Subscribable

SmartDeviceLink 2.0

engineTorque Boolean

Torquevalue forengine (inNm) onnon-dieselvariants

N Subscribable

SmartDeviceLink 2.0

accPedalPosition

Boolean

Accelerator pedalposition(percentagedepressed)

N Subscribable

SmartDeviceLink 2.0

steeringWheelAngle

Boolean

Currentangle ofthesteeringwheel (indeg)

N Subscribable

SmartDeviceLink 2.0

eCallInfo Boolean

Emergency Callnotification andconfirmation data.

N Subscribable

SmartDeviceLink 2.0

airbagStatus Boolean

Thestatus ofthe airbags.

N Subscribable

SmartDeviceLink 2.0

emergencyEvent

Boolean

Informationrelated toanemergency event(and if itoccurred).

N Subscribable

SmartDeviceLink 2.0

clusterModeStatus

Boolean

Thestatusmodes oftheinstrument panelcluster.

N Subscribable

SmartDeviceLink 2.0

RESPONSE

Once this response is received, no other Operations will be accepted by SDL

and no Notifications will be sent by SDL.

Related Operations

RegisterAppInterface

OnAppInterfaceUnregistered

myKey Boolean

Informationrelated totheMyKeyfeature.

N Subscribable

SmartDeviceLink 2.0

NON-DEFAULT RESULT CODES:

- SUCCESS- INVALID_DATA- OUT_OF_MEMORY- TOO_MANY_PENDING_REQUESTS- APPLICATION_NOT_REGISTERED- GENERIC_ERROR

Example Function Call

Speak

Speaks a phrase over the vehicle’s audio system using SDL's TTS (text-to-

speech) engine. The provided text to be spoken can be simply a text phrase, or

it can consist of phoneme specifications to direct SDL's TTS engine to speak a

"speech-sculpted" phrase.

Receipt of the Response indicates the completion of the Speak operation,

regardless of how the Speak operation may have completed (i.e. successfully,

interrupted, terminated, etc.).

Requesting a new Speak operation while the application has another Speak

operation already in progress (i.e. no corresponding Response for that in-

progress Speak operation has been received yet) will terminate the in-progress

Speak operation (causing its corresponding Response to be sent by SDL) and

begin the requested Speak operation.

Requesting a new Speak operation while the application has an Alert operation

already in progress (i.e. no corresponding Response for that in-progress Alert

operation has been received yet) will result in the Alert operation being

canceled (indicated in the Response to the Request).

Requesting a new Alert operation while the application has a Speak operation

already in progress (i.e. no corresponding Response for that in-progress Speak

operation has been received yet) will terminate the in-progress Speak operation

RPCMessage req; req = RPCRequestFactory.buildUnregisterAppInterface(autoIncCorrID++); _sdlProxy.sendRPCRequest(req);

(causing its corresponding Response to be sent by SDL) and begin the

requested Alert operation.

Requesting a new Speak operation while the application has a

PerformInteraction operation already in progress (i.e. no corresponding

Response for that in-progress PerformInteraction operation has been received

yet) will result in the Speak operation request being rejected (indicated in the

Response to the Request).

Requesting a PerformInteraction operation while the application has a Speak

operation already in progress (i.e. no corresponding Response for that in-

progress Speak operation has been received yet) will terminate the in-progress

Speak operation (causing its corresponding Response to be sent by SDL) and

begin the requested PerformInteraction operation.

Note: Total character limit depends on platform. Chunks are limited to 500

characters; however, you can have multiple TTS chunks. This could vary

according to the VCA.

HMI Status Requirements

HMILevel:FULL, Limited

AudioStreamingState:Any

SystemContext:MAIN, MENU, VR

Note: When Alert is issued with MENU in effect, Alert is queued and "played"

when MENU interaction is completed (i.e. SystemContext reverts to MAIN).

When Alert is issued with VR in effect, Alert is queued and "played" when VR

interaction is completed (i.e. SystemContext reverts to MAIN).

Note: When both Alert and Speak are queued during MENU or VR, they are

"played" back in the order in which they were queued, with all existing rules for

"collisions" still in effect.

REQUEST

Name Type Description Reg. Notes

Ver.Available

RESPONSE

This Response notifies the application of the completion, interruption, or failure

of a Speak Request.

ttsChunks String

An arrayof 1-100TTSChunkstructswhich,takentogether,specifythephrase tobespoken.

Y

The arraymusthave1-100elements.The totallength ofthephrasecomposed fromthettsChunksprovidedmust beless than500characters or therequestwill berejected. Eachchunkcan be nomorethan 500characters.

SmartDeviceLink 1.0

Non-default Result Codes:

Related Operations

Alert

Example Function Call

ResetGlobalProperties

Resets the passed global properties to their default values as defined by SDL

- SUCCESS- INVALID_DATA- OUT_OF_MEMORY- TOO_MANY_PENDING_REQUESTS- APPLICATION_NOT_REGISTERED- GENERIC_ERROR- REJECTED- DISALLOWED- ABORTED

Speak req; req = RPCRequestFactory.buildSpeak(ttsText, autoCorrIncID++);_sdlProxy.sendRPCRequest(req);

The HELPPROMPT global property default value is generated by SDL consists of

the first vrCommand of each Command Menu item defined at the moment PTT

is pressed.

The TIMEOUTPROMPT global property default value is the same as the

HELPPROMPT global property default value.

HMI Status Requirements

HMILevel needs to be FULL, LIMITED, or BACKGROUND.

REQUEST

Parameter List

ParamName Type Descript

ion Req. Notes

VersionAvailable

RESPONSE

Indicates whether the Global Properties were successfully set to their default

values.

Non-default Result Codes:

• SUCCESS• INVALID_DATA• OUT_OF_MEMORY• TOO_MANY_PENDING_REQUESTS• APPLICATION_NOT_REGISTERED• GENERIC_ERROR• REJECTED• DISALLOWED

Related Operations

• SetGlobalProperties

properties

GlobalProperty

An arrayof one ormoreGlobalPropertyenumerationelementsindicatingwhichglobalproperties to resetto theirdefaultvalue.

Y

Arraymusthave atleast oneelement.minsize:1maxsize:100

SmartDeviceLink 1.0

Example Function Call

SetGlobalProperties

Sets value(s) for the specified global property(ies).

HMI Status Requirements

HMILevel needs to be FULL, LIMITED, or BACKGROUND.

ResetGlobalProperties req = new ResetGlobalProperties(); req.setCorrelationID(autoIncCorrID++); Vector<GlobalProperty> properties = new Vector<GlobalProperty>(); properties.add(HELPPROMPT): req.setProperties(properties);_sdlProxy.sendRPCRequest(req);

REQUEST

ParamName Type Descript

ion Req. Notes

VersionAvailable

helpPrompt TTSChunk

The helpprompt.An arrayof textchunks oftypeTTSChunk. SeeTTSChunk.Thearraymusthave atleast oneitem.

N

Arraymusthave atleast oneelement.OnlyoptionalittimeoutPrompt hasbeenspecified.minsize:1maxsize:100

SmartDeviceLink 1.0

timeoutPrompt TTSChunk

Array ofone ormoreTTSChunkelementsspecifying thehelppromptused inaninteraction startedby PTT.

N

Arraymusthave atleast oneelementOnlyoptionalithelpPrompt hasbeenspecifiedminsize:1maxsize:100

SmartDeviceLink 1.0

vrHelpTitle string

Text,which isshown astitle ofthe VRhelpscreenused inaninteraction startedby PTT.

N

If omittedonsupporteddisplays,thedefaultSDL helptitle willbe used. If omittedand oneor morevrHelpitems areprovided,therequestwill berejected. maxlength: 500

SmartDeviceLink 1.0

vrHelp VrHelep

Itemslisted inthe VRhelpscreenused inaninteraction startedby PTT.

N

If omittedonsupporteddisplays,thedefaultSDL VRhelp /What CanI Say?screenwill beusedIf the listof VRHelpItemscontainsnonsequentialpositions(e.g.[1,2,4]),the RPCwill berejected.If omittedand avrHelpTitle isprovided,therequestwill berejected.minsize:1maxsize:100

SmartDeviceLink 1.0

menuTitle

Optionaltext tolabel anappmenubutton(forcertaintouchscreenplatforms).

N maxlength: 500

SmartDeviceLink 1.0

menuIcon Image

Optionalicon todraw onan appmenubutton(forcertaintouchscreenplatforms).

NSmartDeviceLink 1.0

keyboardProperties

KeyboardProperties

On-screenkeybaordconfiguration (ifavailable).

NSmartDeviceLink 1.0

Note Your application shall send a SetGlobalProperties to establish an

advanced help prompt before sending any voice commands.

RESPONSE

Indicates whether the requested Global Properties were successfully set.

Non-default Result Codes:

• SUCCESS• INVALID_DATA• OUT_OF_MEMORY• TOO_MANY_PENDING_REQUESTS• APPLICATION_NOT_REGISTERED• GENERIC_ERROR• REJECTED • DISALLOWED

Related Operations

• ResetGlobalProperties• Example Function Call

RPCMessage req;req = RPCRequestFactory.buildSetGlobalProperties (helpText, timeoutText, autoIncCorrID++);_sdlProxy.sendRPCRequest(req);

SetMediaClockTimer

Sets the media clock/timer value and the update method (e.g. count-up,

countdown, etc.).

HMI Status Requirements

HMILevel needs to be FULL, LIMITED, or BACKGROUND.

REQUEST

ParamName Type Descript

ion Req. Notes

VersionAvailable

startTime StartTime

StartTimestructspecifying hour,minute,secondvalues towhichmediaclocktimer isset.

NSmartDeviceLink 1.0

endTime StartTime

EndTimecan beprovidedfor"COUNTUP" and"COUNTDOWN"; tobe usedtocalculateanyvisualprogressbar (if notprovided,thisfeature isignored)IfendTimeis greaterthenstartTimeforCOUNTDOWN orless thanstartTimeforCOUNTUP, thentherequestwill returnanINVALID_DATA.endTimewill beignoredfor"RESUME", and"CLEAR"endTimecan besent for"PAUSE",in whichcase itwillupdatethepausedendTime

N

Arraymusthave atleast oneelementOnlyoptionalithelpPrompt hasbeenspecifiedminsize:1maxsize:100

SmartDeviceLink 1.0

RESPONSE

Non-default Result Codes:

• SUCCESS• INVALID_DATA• OUT_OF_MEMORY• TOO_MANY_PENDING_REQUESTS• APPLICATION_NOT_REGISTERED• GENERIC_ERROR• REJECTED• IGNORED

Example Function Calls

updateMode

UpdateMode

Specifieshow themediaclock/timer isto beupdated(COUNTUP/COUNTDOWN/PAUSE/RESUME),based atthestartTime.

Y

If"updateMode" isCOUNTUPorCOUNTDOWN, thisparameter must beprovided. Will beignoredforPAUSE,RESUMEandCLEAR

SmartDeviceLink 1.0

RPCMessage req;req = RPCRequestFactory.buildSetMediaClockTimer (0,15,30, updateMode, autoIncCorrID++); _sdlProxy.sendRPCRequest(req);

Show

Updates the application's display text area, regardless of whether or not this

text area is visible to the user at the time of the request. The application's

display text area remains unchanged until updated by subsequent calls to

Show.

The content of the application's display text area is visible to the user when the

application's HMILevel is FULL or LIMITED, and the SystemContext=MAIN and

no Alert is in progress.

The Show operation cannot be used to create an animated scrolling screen. To

avoid distracting the driver, Show commands cannot be issued more than once

every 4 seconds. Requests made more frequently than this will be rejected.

HMI Status Requirements

HMILevel needs to be FULL, LIMITED, or BACKGROUND.

REQUEST

ParamName Type Descript

ion Req. Notes

VersionAvailable

mainField1 String

Text to bedisplayedin asingle-linedisplay,or in theupperdisplayline in atwo-linedisplay.

N

If thisparameter isomitted,the textofmainField1 doesnotchange. If thisparameter is anemptystring,the fieldwill becleared. Maxlength = 500

SmartDeviceLink 1.0

mainField2 String

Text to bedisplayedon theseconddisplayline of atwo-linedisplay.

N

If thisparameter isomitted,the textofmainField2 doesnotchange. If thisparameter is anemptystring,the fieldwill becleared.Ifprovidedand thedisplay isa single-linedisplay,theparameter isignored.Maxlength = 500

SmartDeviceLink 1.0

mainField3 String

Text to bedisplayedon thefirstdisplayline ofthesecondpage.

N

If thisparameter isomitted,the textofmainField3 doesnotchange. f thisparameter is anemptystring,the fieldwill becleared.Ifprovidedand thedisplay isa single-linedisplay,theparameter isignored.Maxlength = 500

SmartDeviceLink 2.0

mainField4 String

Text to bedisplayedon theseconddisplayline ofthesecondpage.

N

If thisparameter isomitted,the textofmainField4 doesnotchange. If thisparameter is anemptystring,the fieldwill becleared.Ifprovidedand thedisplay isa single-linedisplay,theparameter isignored.Maxlength = 500

SmartDeviceLink 2.0

alignment

TextAlignment

SpecifieshowmainField1 andmainField2 textshould bealignedondisplay.

N

Appliesonly tomainField1 andmainField2providedon thiscall, notto what isalreadyshowingin display.If thisparameter isomitted,text inbothmainField1 andmainField2 will becentered.Has noeffectwithnavigation display

SmartDeviceLink 1.0

statusBar String

The textis placedin thestatusbar area.

N

Note: Thestatusbar onlyexists onnavigation displaysIf thisparameter isomitted,the statusbar textwillremainunchanged.If thisparameter is anemptystring,the fieldwill becleared.Ifprovidedand thedisplayhas nostatusbar, thisparameter isignored.Maxlength = 500

SmartDeviceLink 1.0

mediaClock String

Textvalue forMediaClock field.Has to beproperlyformattedby MobileAppaccordingto SDLcapabilities.If thistext isset, anyautomatic mediaclockupdatespreviously set withSetMediaClockTimer will bestopped.

N

Must beproperlyformattedasdescribedin theMediaClockFormatenumeration. If a valueof fivespaces isprovided,this willclear thatfield onthedisplay(i.e. themediaclocktimerfield willnotdisplayanything)Maxlength = 500

SmartDeviceLink 1.0

mediaTrack String

Array ofone ormoreTTSChunkelementsspecifying thehelppromptused inaninteraction startedby PTT.

N

Ifparameter isomitted,the trackfieldremainsunchanged.If anemptystring isprovided,the fieldwill becleared.This fieldis onlyvalid formediaapplications onnavigationdisplays.Maxlength = 500

SmartDeviceLink 1.0

graphic Image

Image tobe shownonsupporteddisplays.

N

If omittedonsupporteddisplays,thedisplayedgraphicshall notchange.

SmartDeviceLink 2.0

secondaryGraphic

Image

Imagestructdeterminingwhetherstatic ordynamicsecondary imageto displayin app.If omittedonsupporteddisplays,thedisplayedsecondary graphicshall notchange.

NSmartDeviceLink 2.3.2

softButtons

SoftButton

Softbuttonsasdefinedby theApp

N

If omittedonsupporteddisplays,thecurrentlydisplayedSoftButton valueswill notchange.ArrayMinsize: 0ArrayMaxsize:8

SmartDeviceLink 2.0

customPresets String

Custompresetsasdefinedby theApp.

N

If omittedonsupporteddisplays,thepresetswill beshown asnotdefined.Minsize: 0Maxsize:6

SmartDeviceLink 2.0

RESPONSE

Related Operations

• Alert• SetMediaClockTimer

Example Function Call

NON-DEFAULT RESULT CODES:

- SUCCESS- INVALID_DATA- OUT_OF_MEMORY- TOO_MANY_PENDING_REQUESTS- APPLICATION_NOT_REGISTERED- GENERIC_ERROR- REJECTED- DISALLOWED - UNSUPPORTED_RESOURCE- ABORTED

Show req;req = RPCRequestFactory.buildShow(mainText1, mainText2, null, mediaClock, mediaTrack, alignment, autoIncCorrID++);_syncProxy.sendRPCRequest(req);

SubscribeButton

Establishes a subscription to button notifications for HMI buttons. Buttons are

not necessarily physical buttons, but can also be "soft" buttons on a touch

screen, depending on the display in the vehicle. Once subscribed to a particular

button, an application will receive both OnButtonEvent and OnButtonPress

notifications whenever that button is pressed. The application may also

unsubscribe from notifications for a button by invoking the UnsubscribeButton

operation.

When a button is depressed, an OnButtonEvent notification is sent to the

application with a ButtonEventMode of BUTTONDOWN. When that same button

is released, an OnButtonEvent notification is sent to the application with a

ButtonEventMode of BUTTONUP.

When the duration of a button depression (that is, time between depression

and release) is less than two seconds, an OnButtonPress notification is sent to

the application (at the moment the button is released) with a ButtonPressMode

of SHORT. When the duration is two or more seconds, an OnButtonPress

notification is sent to the application (at the moment the two seconds have

elapsed) with a ButtonPressMode of LONG.

The purpose of OnButtonPress notifications is to allow for programmatic

detection of long button presses similar to those used to store presets while

listening to the radio, for example.

When a button is depressed and released, the sequence in which notifications

will be sent to the application is as follows:

For short presses:

OnButtonEvent (ButtonEventMode = BUTTONDOWN)

OnButtonEvent (ButtonEventMode = BUTTONUP)

OnButtonPress (ButtonPressMode = SHORT)

For long presses:

OnButtonEvent (ButtonEventMode = BUTTONDOWN)

OnButtonPress (ButtonPressMode = LONG)

OnButtonEvent (ButtonEventMode = BUTTONUP)

HMI Status Requirements

HMILevel needs to be FULL, LIMITED, or BACKGROUND.

REQUEST

Name Type Description Reg. Notes Versio

n

RESPONSE

Non-default Result Codes:

Related Operations

• UnsubscribeButton

buttonName

ButtonName

Name ofthebutton tosubscribe.

YSmartDeviceLink 1.0

- SUCCESS- INVALID_DATA- OUT_OF_MEMORY- TOO_MANY_PENDING_REQUESTS- APPLICATION_NOT_REGISTERED- GENERIC_ERROR- UNSUPPORTED_RESOURCE- IGNORED- REJECTED

Example Function Call

UnSubscribeButton

Deletes a subscription to button notifications for the specified button. For more

information about button subscriptions, see SubscribeButton.

Application can unsubscribe from a button that is currently being pressed (i.e.

has not yet been released), but app will not get button event.

HMI Status Requirements

HMILevel needs to be FULL, LIMITED, or BACKGROUND.

REQUEST

ParamName Type Descript

ion Req. Notes

VersionAvailable

SubscribeButton buttonReq; buttonReq = RPCRequestFactory.buildSubscribeButton(ButtonName.OK, autoIncCorrID++);_sdlProxy.sendRPCRequest(buttonReq);

buttonName

ButtonName

Name ofthebutton tounsubscribe.

YSmartDeviceLink 1.0

Non-default Result Codes:

Related Operations

• SubscribeButton

Example Function Call

RESPONSE

- SUCCESS- INVALID_DATA- OUT_OF_MEMORY- TOO_MANY_PENDING_REQUESTS- APPLICATION_NOT_REGISTERED- GENERIC_ERROR- UNSUPPORTED_RESOURCE- IGNORED- REJECTED

RPCMessage req; req = RPCRequestFactory.buildUnsubscribeButton(ButtonName.OK, autoIncCorrID++); _sdlProxy.sendRPCRequest(req);

PerformInteraction

Performs an application-initiated interaction in which the user can select a

Choice from among the specified Choice Sets. For instance, an application may

use a PerformInteraction to ask a user to say the name of a song to play. The

user's response is only valid if it appears in the specified Choice Sets and is

recognized by SDL.

HMI Status Requirements

HMILevel needs to be FULL.

REQUEST

ParamName Type Descript

ion Req. Notes

VersionAvailable

initialText String

Displayedwhen theinteraction begins.This textmay beoverlaidby the"Listening" promptduringtheinteraction. Text isdisplayedon firstline ofmultilinedisplay,and iscentered.If textdoes notfit on line,it will betruncated

Y maxlength:500

SmartDeviceLink 1.0

initialPrompt TTSChunk

An arrayof one ormoreTTSChunks that,takentogether,specifywhat is tobespoken tothe userat thestart ofaninteraction.

Yminsize:1maxsize:100

SmartDeviceLink 1.0

interactionMode

InteractionMode

Indicateshow userselectsinteraction choice.User canchooseeither byvoice(VR_ONLY), byvisualselectionfrom themenu(MANUAL_ONLY),or byeithermode(BOTH).

YSmartDeviceLink 1.0

interactionChoiceSetIDList

Integer

Array ofone ormoreChoiceSet IDs.User canselectanychoicefrom anyof thespecifiedChoiceSets.

Y

minsize:0maxsize:100minvalue:0maxvalue:2000000000

SmartDeviceLink 1.0

helpPrompt TTSChunk

An arrayofTTSChunks which,takentogether,specifythe helpphrase tobespokenwhen theuser says"help"duringthe VRsession. If thisparameter isomitted,the helppromptwill beconstructed bySDL fromthe firstvrCommand ofeachchoice ofall theChoiceSetsspecifiedin theinteractionChoiceSetIDListparameter.

N

minsize:1maxsize:100

The

helpPro

mpt

specifie

d in

SetGlob

alPrope

rties is

not

used by

Perform

Interact

ion.

SmartDeviceLink 1.0

timeoutPrompt TTSChunk

An arrayofTTSChunks which,takentogether,specifythephrase tobespokenwhen thelistentimes outduringthe VRsession. If thisparameter isomitted,thetimeoutpromptwill bethe sameas thehelpprompt(seehelpPromptparameter).

N

ThetimeoutPromptspecifiedinSetGlobalProperties is notused byPerformInteraction.minsize:1maxsize:100

SmartDeviceLink 1.0

timeout Integer

Theamountof time,inmilliseconds, SDLwill waitfor theuser tomake achoice(VR orMenu). Ifthis timeelapseswithoutthe usermaking achoice,thetimeoutPrompt willbespoken.After thistimeoutvalue hasbeenreached,theinteraction willstop andasubsequentinteraction willtakeplaceafter SDLspeaksthetimeoutprompt. Ifthattimes outas well,theinteraction will endcompletely. Ifomitted,thedefault is10000ms.

N

minvalue:5000maxvalue:100000defvalue:10000

SmartDeviceLink 1.0

RESPONSE

Indicates that interaction is complete, or was rejected.

An interaction can complete when the user selects a choice, or when the

interaction times out (no user selection was made), or when the interaction was

interrupted by the user (pressing PTT or Menu button), or by system events

(e.g. phone call), etc.

This is sent to the mobile application after the user makes a choice from the

PerformInteraction Request; or if the user fails to make a selection and the

Request times out. Two additional parameters, cmdID and triggerSource, are

provided with this Response. The cmdID parameter represents the ID of the

Choice in the InteractionChoices that was selected by the user. The

vrHelp VrHelpItem

Ability tosendsuggested VR HelpItems todisplayon-screenduringPerformInteraction Ifomittedonsupporteddisplays,thedefaultSDLgenerated list ofsuggested choiceswill bedisplayed.

NMin = 1Max =100

SmartDeviceLink 2.0

interactionLayout

LayoutMode

SeeLayoutMode

NSmartDeviceLink 3.0

triggerSource parameter indicates where said Choice selection came from

(either Menu or VR).

Non-default Result Codes:

Related Operations

• CreateInteractionChoiceSet• DeleteInteractionChoiceSet

Example Function Call

- SUCCESS- INVALID_DATA- OUT_OF_MEMORY- TOO_MANY_PENDING_REQUESTS- APPLICATION_NOT_REGISTERED- GENERIC_ERROR- REJECTED- INVALID_ID- DUPLICATE_NAME- TIMED_OUT- ABORTED- UNSUPPORTED_RESOURCE- WARNINGS

RPCMessage req;req = RPCRequestFactory.buildPerformInteraction(initPrompt, displayText, interactionChoiceSetIDList, helpPrompt, timeoutPrompt, interactionMode, timeout, autoIncCorrID++);_sdlProxy.sendRPCRequest(req);

PerformAudioPassThru

This will open an audio pass thru session. By doing so the app can receive

audio data through the vehicle’s microphone.

HMI Status Requirements

HMILevel needs to be FULL or LIMITED.

REQUEST

Name Type Description Reg. Notes Versio

n

initialPrompt

TTSChunk[]

SDL willspeakthispromptbeforeopeningthe audiopass thrusession.

N

This is anarray oftextchunks oftypeTTSChunk. Thearraymusthave atleast oneitem Ifomitted,then noinitialprompt isspoken: ArrayMinsize: 1ArrayMaxsize:100

SmartDeviceLink 2.0

audioPassThruDisplayText1

String

First lineof textdisplayedduringaudiocapture.

N Maxlength = 500

SmartDeviceLink 2.0

samplingRate

SamplingRate

Thisvalueshall isallowedto be 8 or16 or 22or 44 khz.

YSmartDeviceLink 2.0

maxDuration Integer

Themaximumdurationof audiorecordinginmilliseconds.

Y

Minvalue:1Maxvalue:1000000

SmartDeviceLink 2.0

bitsPerSample

BitsPerSample

Specifiesthequalitythe audioisrecorded- 8 bit or16 bit.

YSmartDeviceLink 2.0

audioType

AudioType

Specifiesthe typeof audiodatabeingrequested.

YSmartDeviceLink 2.0

muteAudio Boolean N N

SmartDeviceLink 2.0

RESPONSE

Non-default Result Codes:

Related Operations

• EndAudioPassThru

EndAudioPassThru

When this request is invoked, the audio capture stops

HMI Status Requirements

HMILevel needs to be FULL or LIMITED.

- SUCCESS- INVALID_DATA- OUT_OF_MEMORY- TOO_MANY_PENDING_REQUESTS- APPLICATION_NOT_REGISTERED- GENERIC_ERROR- DISALLOWED- REJECTED- ABORTED- RETRY

REQUEST

No parameters.

RESPONSE

Non-default Result Codes:

Related Operations

PerformAudioPassThru

SubscribeVehicleData

Subscribes for specific published vehicle data items. The data will be only sent,

if it has changed.

The application will be notified by the onVehicleData notification whenever new

data is available. The update rate is very much dependent on sensors, vehicle

architecture and vehicle type. Be also prepared for the situation that a signal is

- SUCCESS- INVALID_DATA- OUT_OF_MEMORY- TOO_MANY_PENDING_REQUESTS- APPLICATION_NOT_REGISTERED- GENERIC_ERROR- REJECTED- DISALLOWED

not available on a vehicle.

To unsubscribe the notifications, use unsubscribe with the same

subscriptionType.

HMI Status Requirements

HMILevel needs to be FULL, LIMITED, or BACKGROUND.

REQUEST

Name Type Description Reg. Notes

SmartDeviceLinkVersion

gps Boolean GPS data. N Subscribable

SmartDeviceLink 2.0

speed Boolean

Thevehiclespeed inkilometers perhour

N Subscribable

SmartDeviceLink 2.0

rpm Boolean

Thenumberofrevolutions perminute oftheengine

N Subscribable

SmartDeviceLink 2.0

fuelLevel Boolean

The fuellevel inthe tank(percentage)

N Subscribable

SmartDeviceLink 2.0

fuelLevel_State Boolean

The fuellevelstate

N Subscribable

SmartDeviceLink 2.0

instantFuelConsumption

Boolean

Theinstantaneous fuelconsumption inmicrolitres

N Subscribable

SmartDeviceLink 2.0

externalTemperature

Boolean

Theexternaltemperature indegreescelsius

N Subscribable

SmartDeviceLink 2.0

prndl BooleanCurrentlyselectedgear.

N Subscribable

SmartDeviceLink 2.0

tirePressure Boolean

Tirepressurestatus

N Subscribable

SmartDeviceLink 2.0

odometer Boolean Odomete

r in km NMaxLength:500

SmartDeviceLink 2.0

beltStatus Boolean

Thestatus ofthe seatbelts

N Subscribable

SmartDeviceLink 2.0

bodyInformation

Boolean

The bodyinformationincludingignitionstatusandinternaltemp

N Subscribable

SmartDeviceLink 2.0

deviceStatus Boolean

Thedevicestatusincludingsignalandbatterystrength

N Subscribable

SmartDeviceLink 2.0

driverBraking Boolean

Thestatus ofthe brakepedal

N Subscribable

SmartDeviceLink 2.0

wiperStatus Boolean

Thestatus ofthewipers

N Subscribable

SmartDeviceLink 2.0

headLampStatus

BooleanStatus ofthe headlamps

N Subscribable

SmartDeviceLink 2.0

engineTorque Boolean

Torquevalue forengine (inNm) onnon-dieselvariants

N Subscribable

SmartDeviceLink 2.0

accPedalPosition

Boolean

Accelerator pedalposition(percentagedepressed)

N Subscribable

SmartDeviceLink 2.0

steeringWheelAngle

Boolean

Currentangle ofthesteeringwheel (indeg)

N Subscribable

SmartDeviceLink 2.0

eCallInfo Boolean

Emergency Callnotification andconfirmation data.

N Subscribable

SmartDeviceLink 2.0

airbagStatus Boolean

Thestatus ofthe airbags.

N Subscribable

SmartDeviceLink 2.0

emergencyEvent

Boolean

Informationrelated toanemergency event(and if itoccurred).

N Subscribable

SmartDeviceLink 2.0

clusterModeStatus

Boolean

Thestatusmodes oftheinstrument panelcluster.

N Subscribable

SmartDeviceLink 2.0

RESPONSE

Non-default Result Codes:

UnsubscribeVehicleData

This function is used to unsubscribe the notifications from the

subscribeVehicleData function.

HMI Status Requirements

HMILevel needs to be FULL, LIMITED, or BACKGROUND.

myKey Boolean

Informationrelated totheMyKeyfeature.

N Subscribable

SmartDeviceLink 2.0

- SUCCESS- WARNINGS- INVALID_DATA- OUT_OF_MEMORY- TOO_MANY_PENDING_REQUESTS- APPLICATION_NOT_REGISTERED- GENERIC_ERROR- IGNORED- DISALLOWED- USER_DISALLOWED

REQUEST

Name Type Description Reg. Notes Versio

n

gps Boolean

GPS data.See{@linkplainGPSdata}for details

N Subscribable

SmartDeviceLink 2.0

speed Boolean

Thevehiclespeed inkilometers perhour

N Subscribable

SmartDeviceLink 2.0

rpm Boolean

Thenumberofrevolutions perminute oftheengine

N Subscribable

SmartDeviceLink 2.0

fuelLevel Boolean

The fuellevel inthe tank(percentage)

N Subscribable

SmartDeviceLink 2.0

fuelLevel_State Boolean

The fuellevelstate

N Subscribable

SmartDeviceLink 2.0

instantFuelConsumption

Boolean

Theinstantaneous fuelconsumption inmicrolitres

N Subscribable

SmartDeviceLink 2.0

externalTemperature

Boolean

Theexternaltemperature indegreescelsius

N Subscribable

SmartDeviceLink 2.0

prndl BooleanCurrentlyselectedgear.

N Subscribable

SmartDeviceLink 2.0

tirePressure Boolean

Tirepressurestatus

N Subscribable

SmartDeviceLink 2.0

odometer Boolean Odomete

r in km NMaxLength:500

SmartDeviceLink 2.0

beltStatus Boolean

Thestatus ofthe seatbelts

N Subscribable

SmartDeviceLink 2.0

bodyInformation

Boolean

The bodyinformationincludingignitionstatusandinternaltemp

N Subscribable

SmartDeviceLink 2.0

deviceStatus Boolean

Thedevicestatusincludingsignalandbatterystrength

N Subscribable

SmartDeviceLink 2.0

driverBraking Boolean

Thestatus ofthe brakepedal

N Subscribable

SmartDeviceLink 2.0

wiperStatus Boolean

Thestatus ofthewipers

N Subscribable

SmartDeviceLink 2.0

headLampStatus

BooleanStatus ofthe headlamps

N Subscribable

SmartDeviceLink 2.0

engineTorque Boolean

Torquevalue forengine (inNm) onnon-dieselvariants

N Subscribable

SmartDeviceLink 2.0

accPedalPosition

Boolean

Accelerator pedalposition(percentagedepressed)

N Subscribable

SmartDeviceLink 2.0

steeringWheelAngle

Boolean

Currentangle ofthesteeringwheel (indeg)

N Subscribable

SmartDeviceLink 2.0

eCallInfo Boolean

Emergency Callnotification andconfirmation data.

N Subscribable

SmartDeviceLink 2.0

airbagStatus Boolean

Thestatus ofthe airbags.

N Subscribable

SmartDeviceLink 2.0

emergencyEvent

Boolean

Informationrelated toanemergency event(and if itoccurred).

N Subscribable

SmartDeviceLink 2.0

RESPONSE

Non-default Result Codes:

Related Operations

• SubscribeVehicleData• GetVehicleData

GetVehicleData

Non-periodic vehicle data read request.

clusterModeStatus

Boolean

Thestatusmodes oftheinstrument panelcluster.

N Subscribable

SmartDeviceLink 2.0

myKey Boolean

Informationrelated totheMyKeyfeature.

N Subscribable

SmartDeviceLink 2.0

- SUCCESS- WARNINGS- INVALID_DATA- OUT_OF_MEMORY- TOO_MANY_PENDING_REQUESTS- APPLICATION_NOT_REGISTERED- GENERIC_ERROR- IGNORED- DISALLOWED

HMI Status Requirements

HMILevel needs to be FULL, LIMITED, or BACKGROUND.

REQUEST

Name Type Description Reg. Notes Versio

n

gps Boolean

GPS data.See{@linkplain GPSdata }fordetails

N Subscribable

SmartDeviceLink 2.0

speed Boolean

Thevehiclespeed inkilometers perhour

N Subscribable

SmartDeviceLink 2.0

rpm Boolean

Thenumberofrevolutions perminute oftheengine

N Subscribable

SmartDeviceLink 2.0

fuelLevel Boolean

The fuellevel inthe tank(percentage)

N Subscribable

SmartDeviceLink 2.0

fuelLevel_State Boolean

The fuellevelstate

N Subscribable

SmartDeviceLink 2.0

instantFuelConsumption

Boolean

Theinstantaneous fuelconsumption inmicrolitres

N Subscribable

SmartDeviceLink 2.0

externalTemperature

Boolean

Theexternaltemperature indegreescelsius

N Subscribable

SmartDeviceLink 2.0

vin Boolean

Vehicleidentificationnumber

N Subscribable

SmartDeviceLink 2.0

prndl BooleanCurrentlyselectedgear.

N Subscribable

SmartDeviceLink 2.0

tirePressure Boolean

Tirepressurestatus

N Subscribable

SmartDeviceLink 2.0

odometer Boolean Odomete

r in km NMaxLength:500

SmartDeviceLink 2.0

beltStatus Boolean

Thestatus ofthe seatbelts

N Subscribable

SmartDeviceLink 2.0

RESPONSE

Non-default Result Codes:

• SUCCESS• INVALID_DATA• OUT_OF_MEMORY• TOO_MANY_PENDING_REQUESTS

bodyInformation

Boolean

The bodyinformationincludingignitionstatusandinternaltemp

N Subscribable

SmartDeviceLink 2.0

deviceStatus Boolean

Thedevicestatusincludingsignalandbatterystrength

N Subscribable

SmartDeviceLink 2.0

driverBraking Boolean

Thestatus ofthe brakepedal

N Subscribable

SmartDeviceLink 2.0

wiperStatus Boolean

Thestatus ofthewipers

N Subscribable

SmartDeviceLink 2.0

headLampStatus

BooleanStatus ofthe headlamps

N Subscribable

SmartDeviceLink 2.0

engineTorque Boolean

Torquevalue forengine (inNm) onnon-dieselvariants

N Subscribable

SmartDeviceLink 2.0

accPedalPosition

Boolean

Accelerator pedalposition(percentagedepressed)

N Subscribable

SmartDeviceLink 2.0

steeringWheelAngle

Boolean

Currentangle ofthesteeringwheel (indeg)

N Subscribable

SmartDeviceLink 2.0

• APPLICATION_NOT_REGISTERED• GENERIC_ERROR• REJECTED• VEHICLE_DATA_NOT_ALLOWED• VEHICLE_DATA_NOT_AVAILABLE• USER_DISALLOWED

ReadDID

Non-periodic vehicle data read request. This is an RPC to get diagnostics data

from certain vehicle modules. DIDs of a certain module might differ from

vehicle type to vehicle type.

HMI Status Requirements

HMILevel needs to be FULL, LIMITED, or BACKGROUND.

REQUEST

ParamName Type Descript

ion Req. Notes

VersionAvailable

ecuName Integer Name of

ECU. Y

Minvalue:0Maxvalue: 65535

SmartDeviceLink 2.0

didLocation Integer

Get rawdata fromvehicledata DIDlocation(s).

Y

Minvalue:0Maxvalue: 65535

SmartDeviceLink 2.0

appID Integer

ID of theapplication thatrequested thisRPC.

YSmartDeviceLink 2.0

RESPONSE

Non-default Result Codes:

GetDTCs

This RPC allows you to request diagnostic module trouble codes from a vehicle

module.

HMI Status Requirements

HMILevel needs to be FULL, LIMITED, or BACKGROUND.

REQUEST

- SUCCESS- INVALID_DATA- OUT_OF_MEMORY- TOO_MANY_PENDING_REQUESTS- APPLICATION_NOT_REGISTERED- GENERIC_ERROR- REJECTED - DISALLOWED- USER_DISALLOWED- TRUNCATED_DATA

Name Type Description Reg. Notes Versio

n

RESPONSE

Non-default Result Codes:

• SUCCESS• INVALID_DATA• OUT_OF_MEMORY• TOO_MANY_PENDING_REQUESTS• APPLICATION_NOT_REGISTERED• GENERIC_ERROR• REJECTED • DISALLOWED

ecuName Integer Name of

ECU. Y

MinValue: 0MaxValue:65535

SmartDeviceLink 2.0

dtcMask Integer

DTC MaskByte tobe sent indiagnostic requesttomodule.

N

MinValue: 0MaxValue:255

SmartDeviceLink 2.0

• USER_DISALLOWED• TRUNCATED_DATA

ScrollableMessage

Creates a full screen overlay containing a large block of formatted text that can

be scrolled with up to 8 SoftButtons defined.

HMI Status Requirements

HMILevel needs to be FULL.

REQUEST

Name Type Description Reg. Notes Versio

n

scrollableMessageBody

String

Body oftext thatcanincludenewlinesand tabs.

YSmartDeviceLink 1.0

timeout Integer

Appdefinedtimeout.Indicateshow longof atimeoutfrom thelastaction(i.e.scrollingmessageresetstimeout).

N

minvalue=1000maxvalue=65535defvalue=30000

SmartDeviceLink 1.0

softButtons

SoftButton

AppdefinedSoftButtons. Ifomittedonsupporteddisplays,only thesystemdefined"Close"SoftButton will bedisplayed.

N

minsize=0maxsize=8

SmartDeviceLink 1.0

RESPONSE

Non-default Result Codes:

Slider

Creates a full screen or pop-up overlay (depending on platform) with a single

user controlled slider.

HMI Status Requirements

HMILevel needs to be FULL.

- SUCCESS- INVALID_DATA- OUT_OF_MEMORY- CHAR_LIMIT_EXCEEDED- TOO_MANY_PENDING_REQUESTS- APPLICATION_NOT_REGISTERED- GENERIC_ERROR- DISALLOWED- UNSUPPORTED_RESOURCE- REJECTED- ABORTED

REQUEST

TODO

RESPONSE

Non-default Result Codes:

• SAVED• INVALID_DATA• OUT_OF_MEMORY• TOO_MANY_PENDING_REQUESTS• APPLICATION_NOT_REGISTERED• GENERIC_ERROR• DISALLOWED• UNSUPPORTED_RESOURCE• REJECTED• ABORTED• TIMED_OUT

ChangeRegistration

If the app recognizes during the app registration that the SDL HMI language

(voice/TTS and/or display) does not match the app language, the app will be

able (but does not need) to change this registration with changeRegistration

prior to app being brought into focus.

HMI Status Requirements

HMILevel any.

REQUEST

Name Type Description Req. Notes

VersionAvailable

Language Language

Requested SDLvoiceengine(VR+TTS)languageregistration.

YSmartDeviceLink 2.0

hmiDisplayLanguage

Language

Requestdisplaylanguageregistration.

Y

Minvalue=0 Maxvalue=2000000000

SmartDeviceLink 2.0

appName String

Requestnew appnameregistration

N maxlength:100

SmartDeviceLink 2.0

ttsName TTSChunk

RequestnewttsNameregistration

Nminsize:1maxsize:100

SmartDeviceLink 2.0

ngnMediaScreenAppName

String

Requestnew appshortnameregistration

N maxlength: 100

SmartDeviceLink 2.0

vrSynonyms String

Requestnew VRsynonymsregistration

N

maxlength: 40minsize:1maxsize:100

SmartDeviceLink 2.0

RESPONSE

Non-default Result Codes:

Related Operations

• RegisterAppInterface

GenericResponse

Generic Response is sent, when the name of a received msg cannot be

retrieved. Only used in case of an error. Currently, only resultCode

INVALID_DATA is used.

Related Operations

All functions.

- SUCCESS- INVALID_DATA- OUT_OF_MEMORY- TOO_MANY_PENDING_REQUESTS- APPLICATION_NOT_REGISTERED- GENERIC_ERROR- REJECTED - DISALLOWED

PutFile

Used to push a binary data onto the SDL module from a mobile device, such as

icons and album art.

REQUEST

Name Type Description Req. Notes

VersionAvailable

FileName String

Filereferencename.

Y Maxlength=500

SmartDeviceLink 2.0

fileType FileType Selectedfile type. Y

SmartDeviceLink 2.0

persistentFile Boolean

Indicatesif the fileis meantto persistbetweensessions /ignitioncycles.If set toTRUE,then thesystemwill aimto persistthis filethroughsession /cycles.Whilefiles withthisdesignation willhavepriorityoverothers,they aresubject todeletionby thesystem atany time.In theevent ofautomatic deletionby thesystem,the appwillreceive arejectionand haveto resendthe file.Ifomitted,the valuewill beset tofalse.

NSmartDeviceLink 2.0

RESPONSE

Response is sent, when the file data was copied (success case). Or when an

error occurred.

systemFile Boolean

Indicatesif the fileis meantto bepassedthru coretoelsewhere on thesystem. Ifset toTRUE,then thesystemwillinsteadpass thedata thruas itarrives toapredeterminedareaoutside ofcore. Ifomitted,the valuewill beset tofalse.

NSmartDeviceLink 2.3.2

offset Float

Optionaloffset inbytes forresumingpartialdatachunks

N

Minvalue=0 Maxvalue=100000000000

SmartDeviceLink 2.3.2

length Float

Optionallength inbytes forresumingpartialdatachunks. Ifoffset isset to 0,thenlength isthe totallength ofthe file tobedownloaded

N

Minvalue=0Maxvalue=100000000000

SmartDeviceLink 2.3.2

Non-default Result Codes:

• SUCCESS• INVALID_DATA• OUT_OF_MEMORY• TOO_MANY_PENDING_REQUESTS• APPLICATION_NOT_REGISTERED• GENERIC_ERROR• REJECTED

Related Operations

• DeleteFile• ListFiles

DeleteFile

Used to delete a file resident on the SDL module in the app's local cache.

Not supported on first generation SDL vehicles.

HMI Status Requirements

REQUEST

Name Type Description Reg. Notes

SmartDeviceLink2.0

RESPONSE

Non-default Result Codes:

• SUCCESS• INVALID_DATA• OUT_OF_MEMORY• TOO_MANY_PENDING_REQUESTS• APPLICATION_NOT_REGISTERED• GENERIC_ERROR• REJECTED

Related Operations

• PutFile• ListFiles

ListFiles

Requests the current list of resident filenames for the registered app.

SDLFileName String

Filereferencename.

Y maxlength:500

SmartDeviceLink 2.0

REQUEST

No parameters.

Returns the current list of resident filenames for the registered app along with

the current space available.

Non-default Result Codes:

SetAppIcon

Used to set existing local file on SDL as the app's icon. Not supported on first

generation SDL vehicles.

RESPONSE

- SUCCESS- INVALID_DATA- OUT_OF_MEMORY- TOO_MANY_PENDING_REQUESTS- APPLICATION_NOT_REGISTERED- GENERIC_ERROR- REJECTED

REQUEST

ParamName Type Descript

ion Req. Notes

VersionAvailable

RESPONSE

Non-default Result Codes:

SetDisplayLayout

Used to set an alternate display layout. If not sent, default screen for given

platform will be shown.

SDLFileName String

Filereferencename.

Y Maxlength=500

SmartDeviceLink 2.0

- SUCCESS- INVALID_DATA- OUT_OF_MEMORY- TOO_MANY_PENDING_REQUESTS- APPLICATION_NOT_REGISTERED- GENERIC_ERROR- REJECTED

REQUEST

ParamName Type Descript

ion Req. Notes

VersionAvailable

RESPONSE

Non-default Result Codes:

displayLayout string

Predefined ordynamicallycreatedscreenlayout.Currentlyonlypredefined screenlayoutsaredefined.Predefined layoutsinclude:"ONSCREEN_PRESETS"Customscreencontaining app-definedonscreenpresets.

Y maxlength: 500

SmartDeviceLink 2.0

- SUCCESS- INVALID_DATA- OUT_OF_MEMORY- TOO_MANY_PENDING_REQUESTS- APPLICATION_NOT_REGISTERED- GENERIC_ERROR- REJECTED