Android Automotive OS allows users to install apps in the car. In order to reach users on this platform, you need to distribute a driver-optimized app that is compatible with Android Automotive OS. You can re-use almost all of the code and resources in your Android Auto app, but you must create a separate build that meets the requirements on this page.
Development overview
Adding Android Automotive OS support is simple and only requires a few steps:
- Enable automotive features in Android Studio
- Create an automotive module
- Update your gradle dependencies
- Add settings or sign-in activities (Optional)
Design considerations
Android Automotive OS takes care of laying out the media content that it receives from your app's media browser service. This means that your app doesn't draw the UI and your app does not start any of your activities when a user triggers media playback.
If you are implementing Settings or Sign-in activities, these activities must be vehicle-optimized. You should refer to the Design guidelines for Android Automotive OS while designing those areas of your app.
Set up your project
You need to set up several different parts of your app's project to enable support for Android Automotive OS.
Enable automotive features in Android Studio
We recommend using Android Studio 3.6 Beta 1 or higher for building and testing your app on Android Automotive OS. All Automotive OS features are already enabled by default in Android Studio 3.6.
If you prefer to use Android Studio 3.5, follow these steps to enable Automotive OS features:
Be sure the file
studioFlags.xmlexists in one of the following locations, depending on your operating system:- Windows:
%USERPROFILE%\.AndroidStudio3.5\config\options - macOS:
~/Library/Preferences/AndroidStudio3.5/options - Linux:
~/.AndroidStudio3.5/config/options
- Windows:
Add the following entry to the
studioFlags.xmlfile:<application> <component name="StudioFlags"> <option name="data"> <map> <entry key="npw.templates.automotive" value="true" /> </map> </option> </component> </application>
Create an automotive module
Some components of Android Automotive OS, such as the manifest, have platform-specific requirements, so you need to create a module that can keep the code for these components separate from other code in your project, such as the code used for your phone app.
Follow these steps to add an automotive module to your project:
- In Android Studio, select File > New > New Module.
- Select Automotive Module, then click Next.
- Provide an Application/Library name. This is the name that users see for your app on Android Automotive OS.
- Provide a Module name.
- Adjust the Package name to match your app.
Select API 28:Android 9.0 (Pie) for the Minimum SDK, and then click Next.
All cars that support Android Automotive OS run on Android 9 (API level 28) or higher, so selecting this value targets 100% of cars that use Android Automotive OS.
Select Add No Activity, and click Finish.
After creating your module in Android Studio, open the AndroidManifest.xml in
your new automotive module:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.media">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme" />
<uses-feature
android:name="android.hardware.type.automotive"
android:required="true" />
</manifest>
You'll notice some standard app information in the <application>
element, but there's also a <uses-feature>
element that declares support for Android Automotive OS. Also note that there
are no activities declared in the manifest.
If you implement a Settings or Sign-in activities, add them here. These activities are triggered by the system using explicit intents and are the only activities that should be declared within the manifest for your Android Automotive OS app.
Intent filters
Android Automotive OS uses explicit intents to trigger activities in your media
app. The manifest file should not contain any activities that have
CATEGORY_LAUNCHER
or ACTION_MAIN intent
filters.
Activities like the one in the following example usually target a phone, or some other mobile device. These activities should be declared in the module that builds the phone app, not in the module that builds your Android Automotive OS app.
<activity android:name=".MyActivity">
<intent-filter>
<!-- You can't use either of these intents for Android Automotive OS -->
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<!--
In their place, you can include other intent filters for any activities
that your app needs for Android Automotive OS, such as settings or
sign-in activities.
-->
</intent-filter>
</activity>
Update your gradle dependencies
We recommend that you keep your media browser service in a separate module that you share between your phone app and your automotive module. If you're using this approach, you need to update your automotive module to include the shared module, as shown in the following snippet:
my-auto-module/build.gradle
buildscript {
...
dependencies {
...
implementation project(':shared_module_name')
}
}
Implement settings and sign-in activities
In addition to your media browser service, you can also provide vehicle-optimized Settings and Sign-in activities for your Android Automotive OS app. These activities allow you provide app functionality that isn't included in the Android Media APIs.
You should only implement these activities if your Automotive OS app needs to allow users to sign in or specify app settings. These activities aren't used by Android Auto.
Add a Settings activity
You can add a vehicle-optimized Settings activity so that users can configure settings for your app in their car. Your settings activity can also provide other workflows, like signing in or out of a user's account or switching user accounts. Remember that this activity is only triggered by an app running on Android Automotive OS. Phone apps connected to Android Auto do not use it.
Settings activity workflows
The Settings activity can provide the user with different workflows. The following diagram shows how a user interacts with your Settings activity using Android Automotive OS:
Figure 1. Settings activity workflows
Declare a Settings activity
You must declare your Settings activity in your app's manifest file, as shown in the following code snippet:
<application>
...
<activity android:name=".AppSettingsActivity"
android:exported="true"
android:theme="@style/SettingsActivity"
android:label="@string/app_settings_activity_title">
<intent-filter>
<action android:name="android.intent.action.APPLICATION_PREFERENCES"/>
</intent-filter>
</activity>
...
<application>
Implement your Settings activity
When a user launches your app, Android Automotive OS detects the
Settings activity that you declared and displays an affordance, such as an icon.
The user can tap or select this affordance using their car's display to navigate
to the activity. Android Automotive OS sends the ACTION_APPLICATION_PREFERENCES
intent that tells your app to start your settings activity.
Add a Sign-in activity
If your app requires a user to sign in before they can use your app, you can add a vehicle-optimized Sign-in activity that handles signing in and out of your app. You can also add sign-in and sign-out workflows to a Settings activity, but you should use a dedicated Sign-in activity if your app cannot be used until a user signs in. Remember that this activity is only triggered by an app running on Android Automotive OS. Phone apps connected to Android Auto do not use it.
Sign-in activity workflow
The following diagram shows how a user interacts with your Sign-in activity using Android Automotive OS:
Figure 2. Sign-in activity workflows
Require sign in at app start
To require a user to sign in before they can use your app, your media browser service must do the following things:
- In your service's
onLoadChildren()method, send a null result using thesendResult()method. - Set the media session's
PlaybackStatetoSTATE_ERRORusing thesetState()method. This tells Android Automotive OS that no other operations can be performed until the error has been resolved. - Set the media session's
PlaybackStateerror code toERROR_CODE_AUTHENTICATION_EXPIRED. This tells Android Automotive OS that the user needs to authenticate. - Set the media session's
PlaybackStateerror message using thesetErrorMessage()method. Because this error message is user-facing, the message must be localized for the user's current locale. Set the media session's
PlaybackStateextras using thesetExtras()method. Include the following two keys:android.media.extras.ERROR_RESOLUTION_ACTION_LABEL: A string that is displayed on the button that begins the sign-in workflow. Because this string is user-facing, it must be localized for the user's current locale.android.media.extras.ERROR_RESOLUTION_ACTION_INTENT: APendingIntentthat directs the user to your Sign-in activity when the user taps the button referred to by theandroid.media.extras.ERROR_RESOLUTION_ACTION_LABEL.
The following code snippet shows how your app can require the user to sign in before using your app:
Kotlin
val signInIntent = Intent(this, SignInActivity::class.java)
val signInActivityPendingIntent = PendingIntent.getActivity(this, 0,
signInIntent, 0)
val extras = Bundle().apply {
putString(
"android.media.extras.ERROR_RESOLUTION_ACTION_LABEL",
"Sign in"
)
putParcelable(
"android.media.extras.ERROR_RESOLUTION_ACTION_INTENT",
signInActivityPendingIntent
)
}
val playbackState = PlaybackStateCompat.Builder()
.setState(PlaybackStateCompat.STATE_ERROR, 0, 0f)
.setErrorMessage(
PlaybackStateCompat.ERROR_CODE_AUTHENTICATION_EXPIRED,
"Authentication required"
)
.setExtras(extras)
.build()
mediaSession.setPlaybackState(playbackState)
Java
Intent signInIntent = new Intent(this, SignInActivity.class);
PendingIntent signInActivityPendingIntent = PendingIntent.getActivity(this, 0,
signInIntent, 0);
Bundle extras = new Bundle();
extras.putString(
"android.media.extras.ERROR_RESOLUTION_ACTION_LABEL",
"Sign in");
extras.putParcelable(
"android.media.extras.ERROR_RESOLUTION_ACTION_INTENT",
signInActivityPendingIntent);
PlaybackStateCompat playbackState = new PlaybackStateCompat.Builder()
.setState(PlaybackStateCompat.STATE_ERROR, 0, 0f)
.setErrorMessage(
PlaybackStateCompat.ERROR_CODE_AUTHENTICATION_EXPIRED,
"Authentication required"
)
.setExtras(extras)
.build();
mediaSession.setPlaybackState(playbackState);
After the user has successfully authenticated, your app must set the PlaybackState
back to a state other than STATE_ERROR
and then take the user back to Android Automotive OS by calling the activity's finish()
method.
Implement your Sign-in activity
Google offers a variety of identity tools that you can use to help users sign in to your app in their cars. Some tools, such as Firebase Authentication, provide full-stack toolkits that can help you build customized authentication experiences. Other tools leverage a user's existing credentials or other technologies to help you build seamless sign-in experiences for users.
We recommend the following tools to help you build an easier sign-in experience for users that have previously signed in on another device:
- Google Sign-in: If you've already implemented Google Sign-in for other devices (such as your phone app), you should also implement Google Sign-in for your Android Automotive OS app to support existing Google Sign-in users.
- Autofill with Google: If users have opted into Autofill with Google on their other Android devices, their credentials are saved to the Google password manager. Then, when the user signs in to your Android Automotive OS app, Autofill with Google suggests relevant saved credentials. Using Autofill with Google requires no application development effort; however, application developers should optimize their apps for better quality results. Autofill with Google is supported by all devices running Android Oreo 8.0 (API level 26) or higher (including Android Automotive OS).
Handle sign-in protected actions
Some apps allow a user to access some actions anonymously, but require the user to sign in before they can perform other actions. For example, a user might be able to play music in an app before signing in, but they must sign in before they can skip a song.
In this case, when the user attempts to perform the restricted action (skipping a song), your app could suggest that user authenticate by issuing a non-fatal error. By using a non-fatal error, the system displays the message to the user without interrupting playback for the current media item. To implement non-fatal error handling, complete the following steps:
- Set the
errorCodefor the media session'sPlaybackStatetoERROR_CODE_AUTHENTICATION_EXPIRED. This tells Android Automotive OS that user needs to authenticate. - Keep the
statefor the media session'sPlaybackStateas is—don't set it toSTATE_ERROR. This is what tells the system that the error is non-fatal. Set the media session's
PlaybackStateextras using thesetExtras()method. Include the following two keys:android.media.extras.ERROR_RESOLUTION_ACTION_LABEL: A string that is displayed on the button that begins the sign-in workflow. Because this string is user-facing, it must be localized for the user's current locale.android.media.extras.ERROR_RESOLUTION_ACTION_INTENT: APendingIntentthat directs the user to your Sign-in activity when the user taps the button referred to by theandroid.media.extras.ERROR_RESOLUTION_ACTION_LABEL.
Retain the rest of the media session's
PlaybackStatestate as is. This allows playback for the current media item to continue while the user decides whether to sign in or not.

