Android Automotive OS lets users install apps in the car. To reach users on this platform, you need to distribute a driver-optimized app that is compatible with Android Automotive OS. You can reuse almost all 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 only requires a few steps, as described in the sections that follow:
- Enable automotive features in Android Studio.
- Create an automotive module.
- Update your Gradle dependencies.
- Optionally, Implement settings and sign-in activities.
- Optionally, Read media host hints.
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 doesn't 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. 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 parts of your app's project to enable support for Android Automotive OS.
Enable automotive features in Android Studio
Use Android Studio 4.0 or higher to ensure that all Automotive OS features are enabled.
Create an automotive module
Some components of Android Automotive OS, such as the manifest, have platform-specific requirements. 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, click File > New > New Module.
- Select Automotive Module, then click Next.
- Enter an Application/Library name. This is the name that users see for your app on Android Automotive OS.
- Enter 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 all compatible cars.
Select No Activity, and then 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>
The <application> element has some standard app information as well as a
<uses-feature> element that declares support for Android Automotive OS.
Note that there are no activities declared in the manifest.
If you implement settings or sign-in activities, add them here. These activities are triggered by the system using explicit intents and are the only activities you declare within the manifest for your Android Automotive OS app.
After adding any settings or sign-in activities, complete your manifest file by
setting the <application> element's android:appCategory attribute to
"audio".
<application
...
android:appCategory="audio" />
Declare feature requirements
All apps built for Android Automotive OS must meet certain requirements to be distributed using Google Play. See Meet Google Play feature requirements for more information.
Declare media support for Android Automotive OS
Use the following manifest entry to declare that your app supports Android Automotive OS:
<application>
...
<meta-data android:name="com.android.automotive"
android:resource="@xml/automotive_app_desc"/>
...
</application>
This manifest entry refers to an XML file that declares the automotive capabilities that your app supports.
To indicate that you have a media app, add an
XML file named automotive_app_desc.xml to the res/xml/ directory in your
project. Include the following content in this file:
<automotiveApp>
<uses name="media"/>
</automotiveApp>
Intent filters
Android Automotive OS uses explicit intents to trigger activities in your media
app. Don't include any activities that have
CATEGORY_LAUNCHER
or ACTION_MAIN intent
filters in the manifest file.
Activities like the one in the following example usually target a phone or some other mobile device. Declare these activities 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
Groovy
buildscript { ... dependencies { ... implementation project(':shared_module_name') } }
Kotlin
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 let you provide app functionality that isn't included in the Android Media APIs.
Only implement these activities if your Android Automotive OS app needs to let users sign in or specify app settings. These activities aren't used by Android Auto.
Activity workflows
The following diagram shows how a user interacts with your settings and sign-in activities using Android Automotive OS:
Figure 1. Settings and sign-in activity workflows.
Discourage distractions in your settings and sign-in activities
To ensure your settings and sign-in activities are only available for use
while the user's vehicle is parked, verify that the <activity> element(s)
don't include the following <meta-data> element. Your app will be rejected
during review if such an element is present.
<!-- NOT ALLOWED -->
<meta-data
android:name="distractionOptimized"
android:value="true"/>
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 don't use it.
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.
The rest of this section shows how you can adapt code from the Universal Android Music Player (UAMP) sample app to implement a settings activity for your app.
To begin, download the sample code:
# Clone the UAMP repositorygit clone https://github.com/android/uamp.git# Fetch the appropriate pull request to your local repositorygit fetch origin pull/323/head:NEW_LOCAL_BRANCH_NAME# Switch to the new branchgit checkout NEW_LOCAL_BRANCH_NAME
To implement your activity, follow these steps:
- Copy the
automotive/automotive-libfolder into your automotive module. - Define a preferences tree as in
automotive/src/main/res/xml/preferences.xml. Implement a
PreferenceFragmentCompatthat your settings activity displays. See theSettingsFragment.ktandSettingsActivity.ktfiles in UAMP and the Android Settings guide for more information.
As you implement your settings activity, consider these best practices for using some of the components in the Preference library:
- Have no more than two levels of depth below the main view in your settings activity.
- Don't use a
DropDownPreference. Use aListPreferenceinstead. - Organizational components:
PreferenceScreen- This must be the top level of your preferences tree.
PreferenceCategory- Used to group
Preferenceobjects together. - Include a
title.
- Used to group
- Include a
keyandtitlein all the following components. You can also include asummary, anicon, or both:Preference- Customize the logic in the
onPreferenceTreeClick()callback of yourPreferenceFragmentCompatimplementation.
- Customize the logic in the
CheckBoxPreference- Can have
summaryOnorsummaryOffinstead ofsummaryfor conditional text.
- Can have
SwitchPreference- Can have
summaryOnorsummaryOffinstead ofsummaryfor conditional text. - Can have
switchTextOnorswitchTextOff.
- Can have
SeekBarPreference- Include a
min,max, anddefaultValue.
- Include a
EditTextPreference- Include
dialogTitle,positiveButtonText, andnegativeButtonText. - Can have one or both of
dialogMessageanddialogLayoutResource.
- Include
com.example.android.uamp.automotive.lib.ListPreference- Derives mostly from
ListPreference. - Used to display a single-choice list of
Preferenceobjects. - Must have an array of
entriesand correspondingentryValues.
- Derives mostly from
com.example.android.uamp.automotive.lib.MultiSelectListPreference- Derives mostly from
MultiSelectListPreference - Used to display a multiple-choice list of
Preferenceobjects. - Must have an array of
entriesand correspondingentryValues.
- Derives mostly from
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 use a dedicated sign-in activity if your app can't 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 don't use it.
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, sendnullresult using thesendResult()method. - Set the media session's
PlaybackStateCompattoSTATE_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
PlaybackStateCompaterror code toERROR_CODE_AUTHENTICATION_EXPIRED. This tells Android Automotive OS that the user needs to authenticate. - Set the media session's
PlaybackStateCompaterror message using thesetErrorMessage()method. Because this error message is user-facing, localize it for the user's current locale. Set the media session's
PlaybackStateCompatextras using thesetExtras()method. Include the following two or three keys:PLAYBACK_STATE_EXTRAS_KEY_ERROR_RESOLUTION_ACTION_LABEL: a string that is displayed on the button that begins the sign-in workflow. Because this string is user-facing, localize it for the user's current locale.PLAYBACK_STATE_EXTRAS_KEY_ERROR_RESOLUTION_ACTION_INTENT: aPendingIntentthat directs the user to your sign-in activity when the user taps the button referred to by thePLAYBACK_STATE_EXTRAS_KEY_ERROR_RESOLUTION_ACTION_LABEL.PLAYBACK_STATE_EXTRAS_KEY_ERROR_RESOLUTION_USING_CAR_APP_LIBRARY_INTENT: aPendingIntentthat directs the user to your Car App Library sign-in activity. Because the Car App Library host is driving-optimized, the intent automatically bypasses the error resolution screen and immediately displays your sign-in screen. If you set this extra, also set the previous two extras to ensure backwards compatibility with older vehicles.
The following code snippet shows how your app can require the user to sign in before using your app:
Kotlin
import androidx.media.utils.MediaConstants val signInIntent = Intent(this, SignInActivity::class.java) val signInActivityPendingIntent = PendingIntent.getActivity(this, 0, signInIntent, 0) val extras = Bundle().apply { putString( MediaConstants.PLAYBACK_STATE_EXTRAS_KEY_ERROR_RESOLUTION_ACTION_LABEL, "Sign in" ) putParcelable( MediaConstants.PLAYBACK_STATE_EXTRAS_KEY_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
import androidx.media.utils.MediaConstants; Intent signInIntent