Develop an application for Automotive Grade Android


Introduction


This tutorial to get you started coding with the AGA Android SDK does not assume you have any particular development environments or tools. This tutorial exemplifies how to get started using either IntelliJ IDEA or Eclipse. This tutorial is valid when developing for a device running AGA Rom or an Android emulator running AGA.

Pre-requisites


To be able to develop an AGA Android application, the following is needed

Extract the zip file of choice and if you want add select folders to your PATH. In Windows e.g.

  • ANDROID_HOME is set to C:\opt\android-aga-sdk-windows
  • Path is appended with %ANDROID_HOME%\platform-tools;%ANDROID_HOME%\tools

In Linux, set/export the variables for your shell of choice.

Setup the AGA Android SDK


Important: the AGA SDK comes with addtional APIs to the SDK platform. It is important NOT to update the "Android x.y.z (API w)" but Tools and Extras may be required by both IDEs and some projects.

Example: Tools are okay to update.

Example: Extras are okay to update.

Setup the build environment using IntelliJ IDEA


  • Download and install IntelliJ IDEA
  • Update and restart

  • Before you create a new project. Go to Project defauls -> Project Structure and set the Android SDK Location to the AGA SDK. E.g. C:\opt\android-aga-sdk-windows
  • Create a new project

  • When IntelliJ IDEA has initialized the project, verify you see the following

Setup the build environment using Eclipse


  • Download Eclipse ADT on this page. Configure Eclipse to use the AGA SDK (Window -> Preferences -> Android -> SDK Location)

  • Create a new Android Application Project
  • Verify that the project is using the AGA SDK

Use the AGA APIs in either IntelliJ IDEA or Eclipse

After this you can add your automotive specific calls. The first thing to do is to get hold of the AutomotiveManager.

  final AutomotiveManager manager = (AutomotiveManager) getApplicationContext().getSystemService(Context.AUTOMOTIVE_SERVICE);

To get data from the vehicle three things are needed.

  1. Provide a data listener.
  2. Register for vehicle signal changes or request values.
  3. Add internet permission to AndroidManifest.xml (to talk to simulator)

Register the listener


  manager.setListener(new AutomotiveListener() {
  @Override
  public void timeout(final int signalId) {
      // Request did time out and no data was received
  Log.d(TAG, "timeout " + signalId);
  }
                   
    @Override
    public void receive(final AutomotiveSignal automotiveSignal) {
      // Incoming signal
      switch (automotiveSignal.getSignalId()) {
  case AutomotiveSignalId.FMS_WHEEL_BASED_SPEED:
        // Unsafe type cast. Could be made safe with automotiveSignal.getData().getDataType()
        Log.d(TAG, "FMS_WHEEL_BASED_SPEED: " + ((SCSFloat) automotiveSignal.getData()).getFloatValue() + " " + automotiveSignal.getUnit().toString());
        break;
      default:
        break;
      }
    }

    @Override
    public void notAllowed(final int signalId) {
      // Policy does not allow for this operation
      Log.d(TAG, "not allowed " + signalId);
    }
  });

Register for signal updates


All signal definitions can be found in the AutomotiveSignalId class.

  manager.register(AutomotiveSignalId.FMS_WHEEL_BASED_SPEED);

Get current value for signal


  manager.requestValue(AutomotiveSignalId.FMS_WHEEL_BASED_SPEED);

Set permissions


Add this to AndroidManifest.xml in the manifest tag (same level as uses-sdk).

Important:

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

Driver distraction


Driver distraction is handled in AGA using broadcast receivers. The application registers for changes to the driver distraction broadcast with the action in AutomotiveBroadcast.

  final BroadcastReceiver receiver = new BroadcastReceiver() {

    @Override
    public void onReceive(Context context, Intent intent) {
      final int level = intent.getIntExtra(AutomotiveBroadcast.EXTRA_DRIVER_DISTRACTION_LEVEL, 5);
        Log.i(TAG, "New broadcast " + level);
    }  
  };

  final IntentFilter intentFilter = new IntentFilter(AutomotiveBroadcast.ACTION_DRIVER_DISTRACTION_LEVEL_CHANGED);
  final Intent currentValue = getApplicationContext().registerReceiver(receiver, intentFilter);
  if (currentValue != null) {
  final int level = currentValue.getIntExtra(AutomotiveBroadcast.EXTRA_DRIVER_DISTRACTION_LEVEL, 5);
    Log.d(TAG, "Initial driver distraction value: " + level);
  }

Application unregisters receiver with this code.

  getApplicationContext().unregisterReceiver(receiver);

Just as with automotive signals the receiver needs permissions. Add this next to the other added permission.

Important:

<uses-permission android:name="android.permission.BROADCAST_STICKY"/>

​Display mode (New in 1.1)

It is possible to get information about different display modes in AGA. There are two different parameters present in this information:

  • Day or night mode
  • Stealth mode active or not

In day mode the display can be very bright and it would not distract the driver. However if the night mode is activated the dispaly should not show any bright content. When in stealth mode all non vital information should be suppressed.

final BroadcastReceiver receiver = new BroadcastReceiver() {

    @Override
    public void onReceive(Context context, Intent intent) {
      final int lightMode = intent.getIntExtra(AutomotiveBroadcast.EXTRA_LIGHT_MODE, AutomotiveBroadcast.DAY_MODE);
      final int stealthMode = intent.getIntExtra(AutomotiveBroadcast.EXTRA_STEALTH_MODE, AutomotiveBroadcast.NORMAL_MODE);
      ...
    }  
  };

  final IntentFilter intentFilter = new IntentFilter(AutomotiveBroadcast.ACTION_DISPLAY_MODE_CHANGED);
  final Intent currentValue = getApplicationContext().registerReceiver(receiver, intentFilter);
  if (currentValue != null) {
    final int lightMode = currentValue.getIntExtra(AutomotiveBroadcast.EXTRA_LIGHT_MODE, AutomotiveBroadcast.DAY_MODE);
    final int stealthMode = currentValue.getIntExtra(AutomotiveBroadcast.EXTRA_STEALTH_MODE, AutomotiveBroadcast.NORMAL_MODE);
    ...
  }

Application unregisters receiver with this code.

  getApplicationContext().unregisterReceiver(receiver);

Just as with automotive signals the receiver needs permissions. Add this next to the other added permission.

Important:

<uses-permission android:name="android.permission.BROADCAST_STICKY"/>