Build templated messaging experiences for Android Auto

Templated messaging experiences are in beta
At this time, anyone can publish communication apps with templated messaging experiences to internal testing and closed testing tracks on the Play Store. Publishing to open testing and production tracks will be permitted at a later date.

In addition to the basic notification-powered messaging experience for reading and replying to messages, Android Auto supports richer messaging experiences built using the Android for Cars App Library.

Support notification-powered messaging experiences

All apps that support templated messaging experiences must also extend messaging notifications for Android Auto. This ensures that users are able to read and reply to messages without having to open the templated app.

Build a templated messaging experience

Follow the guidance in Use the Android for Cars App Library and Add support for Android Auto to your templated app to get started building your app's templated experience. Then, refer to the guidance on this page to understand the specific requirements for templated messaging apps.

Configure your app's manifest files

To inform Android Auto of your app's capabilities, your app must do the following:

Declare category support in your manifest

Your app needs to declare the androidx.car.app.category.MESSAGING car app category in the intent filter of its CarAppService.

<application>
    ...
   <service
       ...
        android:name=".MyCarAppService"
        android:exported="true">
      <intent-filter>
        <action android:name="androidx.car.app.CarAppService" />
        <category android:name="androidx.car.app.category.MESSAGING"/>
      </intent-filter>
    </service>
    ...
<application>

Set the minimum car app API level

Because the ConversationItem API is only supported on Car API 7 or higher, you should also set the minCarApiLevel metadata to that value. See Car App API Level for more information.

<application ...>
    ...
    <meta-data
        android:name="androidx.car.app.minCarApiLevel"
        android:value="7"/>
    ...
</application>

Declare Android Auto support

In the automotive_app_desc.xml file that you use to declare Android Auto support, ensure that both the notification and template capabilities are declared:

<automotiveApp>
    <uses name="notification" />
    <uses name="template" />
</automotiveApp>

If your app can be set as the default SMS handler, make sure to include the following <uses> element. If you don't, a default handler built-in to Android Auto will be used to handle incoming SMS/MMS messages, which can lead to duplicate notifications.

<automotiveApp>
    ...
    <uses name="sms" />
</automotiveApp>

Display conversations

To display an overview of a user's conversations, you can display a list of ConversationItem objects in a ListTemplate or SectionedItemTemplate.

For the best user experience, we recommend providing at most the 5-10 most recent or most important conversations, with no more than the 5 most recent messages for each conversation. This helps improve loading performance, ensures users see the most relevant content, and reduces interaction time.

class MyMessagingScreen() : Screen() {

    override fun onGetTemplate(): Template {
        val itemListBuilder = ItemList.Builder()
        val conversations: List<MyConversation> = // Retrieve conversations

        for (conversation: MyConversation in conversations) {
            val carMessages: List<CarMessage> = conversation.getMessages()
                .map { message ->
                    // CarMessage supports additional fields such as MIME type and URI,
                    // which you should set if available
                    CarMessage.Builder()
                        .setSender(message.sender)
                        .setBody(message.body)
                        .setReceivedTimeEpochMillis(message.receivedTimeEpochMillis)
                        .setRead(message.isRead)
                        .build()
                }

            itemListBuilder.addItem(
                ConversationItem.Builder()
                    .setConversationCallback { /* Implement your conversation callback logic here */ }
                    .setId(/* Set conversation ID */)
                    .setTitle(/* Set conversation title */)
                    .setIcon(/* Set conversation icon if available */)
                    .setMessages(carMessages)
                    /* When the sender of a CarMessage is equal to this Person,
                    message readout is adjusted to "you said" instead of "<person>
                    said" */
                    .setSelf(/* Set self-sender */)
                    .setGroupConversation(/* Set if the message contains more than 2 participants */)
                    .build()
            )
        }

        return ListTemplate.Builder()
            .setTitle("Conversations")
            .setHeaderAction(Action.APP_ICON)
            .setSingleList(itemListBuilder.build())
            .build()
    }
}

Each ConversationItem automatically displays actions for playing a message and marking it as read as and for replying. Those actions are handled by the ConversationCallbackDelegate you supply when building the ConversationItem.

If your app provides conversation shortcuts, ensure that the ID provided when building the ConversationItem is the same as the ID for that conversation's shortcut.

Update conversations

As users send and receive messages, you should refresh your app's screens to include the new messages by calling invalidate(). See Refresh the contents of a template.

For the best user experience, we recommend keeping refresh times to 500 milliseconds or fewer. If refreshing frequently takes longer, you can display a loading state while you load the incoming messages.

Set notification importance appropriately

To reduce distractions, your app should lower the importance of incoming notifications when a user is using your viewing a corresponding conversation so the notifications don't appear as heads up notifications (HUNs).

You can track if a conversation is visible by observing the lifecycle of the Screen that displays it. See The lifecycle of a screen.

To prevent a notification from appearing as a HUN, set the priority to IMPORTANCE_DEFAULT or lower.

Distribute templated messaging apps

Because apps that support templated messaging experiences can only be published to Internal Testing and Closed Testing tracks on Google Play, you shouldn't promote builds that include support to Open Testing or Production tracks, as submissions containing builds on those tracks will be rejected.