/aauto-sdk

Unofficial Android Auto SDK

aauto-sdk

This is an unofficial SDK for Android Auto.

Note

With great power comes great responsibility. Do not write apps that distract drivers. Distraction is dangerous.

Demo

Have a look at these example apps:

Usage

Add this to your main build.gradle:

allprojects {
    repositories {
        maven { url "https://jitpack.io" }
    }
}

and this to your app's build.gradle:

dependencies {
    compile 'com.github.martoreto:aauto-sdk:v4.0'
}

and this to your AndroidManifest.xml inside <application>:

<meta-data
    android:name="com.google.android.gms.car.application"
    android:resource="@xml/automotive_app_desc" />

and save this as res/xml/automotive_app_desc.xml:

<?xml version="1.0" encoding="utf-8"?>
<automotiveApp xmlns:tools="http://schemas.android.com/tools">
    <uses name="service" tools:ignore="InvalidUsesTagAttribute" />
    <uses name="projection" tools:ignore="InvalidUsesTagAttribute" />
    <uses name="notification" />
</automotiveApp>

API

There are no docs, but you can explore the API in Android Studio after switching to the Package view:

screenshot1

Then have a look in the following places under Libraries:

com.google.android.apps.auto.sdk
android.support.car
values/color.xml
values/dimens.xml
values/styles.xml

Actually, some version of android.support.car is open source and has docs in code.

OEM activities (right-most icon)

look like this in AndroidMainfest.xml:

<service
    android:name=".CarService"
    android:label="@string/car_service_name"
    tools:ignore="ExportedService">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="com.google.android.gms.car.category.CATEGORY_PROJECTION" />
        <category android:name="com.google.android.gms.car.category.CATEGORY_PROJECTION_OEM" />
    </intent-filter>
</service>

Accessing sensors

Here's some example code for reading sensor data provided by car.

This can be used in an Android Auto activity, or a background service.

Some documentation: CarSensorManager.java

import android.support.car.Car;
import android.support.car.CarConnectionCallback;
import android.support.car.hardware.CarSensorEvent;
import android.support.car.hardware.CarSensorManager;

@Override
public void onStart() {
    mCar = Car.createCar(this, mCarConnectionCallback);
    mCar.connect();
}

@Override
public void onStop() {
    try {
        mCar.disconnect();
    } catch (Exception e) {
        Log.w(TAG, "Error disconnecting from car", e);
    }
}

private final CarConnectionCallback mCarConnectionCallback = new CarConnectionCallback() {
    @Override
    public void onConnected(Car car) {
        try {
            Log.d(TAG, "Connected to car");
            CarSensorManager sensorManager = (CarSensorManager) car.getCarManager(Car.SENSOR_SERVICE);
            sensorManager.addListener(mSensorsListener, CarSensorManager.SENSOR_TYPE_DRIVING_STATUS,
                    CarSensorManager.SENSOR_RATE_NORMAL);
            CarSensorEvent ds = sensorManager.getLatestSensorEvent(CarSensorManager.SENSOR_TYPE_DRIVING_STATUS);
            if (ds != null) {
                mSensorsListener.onSensorChanged(sensorManager, ds);
            } else {
                Log.i(TAG, "Driving status unknown.");
            }
        } catch (Exception e) {
            Log.w(TAG, "Error setting up car connection", e);
        }
    }

    @Override
    public void onDisconnected(Car car) {
        Log.d(TAG, "Disconnected from car");
    }
};

private final CarSensorManager.OnSensorChangedListener mSensorsListener = new CarSensorManager.OnSensorChangedListener() {
    @Override
    public void onSensorChanged(CarSensorManager sensorManager, CarSensorEvent ev) {
        Log.v(TAG, "Sensor event: " + ev);
        CarSensorEvent.DrivingStatusData ds = ev.getDrivingStatusData();
        if (ds != null) {
            // Do something with this
        }
    }
};

Vendor channel

Android Auto protocol defines another communication method between the car and an app running on the phone, called vendor channel. It's basically a byte channel.

The protocol inside is vendor-specific:

Example use:

CarVendorExtensionManagerLoader vexLoader =
        (CarVendorExtensionManagerLoader)mCar.getCarManager(
                CarVendorExtensionManagerLoader.VENDOR_EXTENSION_LOADER_SERVICE);
mVexManager = vexLoader.getManager(getVendorChannelName());
if (mVexManager == null) {
    throw new RuntimeException("Vendor channel not available");
}
mVexManager.registerListener(new CarVendorExtensionManager.CarVendorExtensionListener() {
    @Override
    public void onData(CarVendorExtensionManager carVendorExtensionManager, byte[] bytes) {
        // Do something with data
    }
});
mVexManager.sendData(new byte[] { (byte) 1, (byte) 2, (byte) 3 });

In order to use the vendor channel:

  • the package name of the application must be on the list provided by the car (use this app to see the list),

  • the app must have

    <uses-permission android:name="com.google.android.gms.permission.CAR_VENDOR_EXTENSION"/>
    

    in its AndroidManifest.xml (and granted at runtime on Marshmallow or later).

Building

Usually, there's no need to build the SDK yourself. If you have a need, please share it by contributing pull requests. :)

To build the SDK yourself:

  1. Set ANDROID_HOME enviroment variable to point to the Android SDK folder.

  2. Do this:

    ./gradlew build

The result is build/aauto.aar.