为 Android Auto 构建模板化消息体验

模板化消息体验处于 Beta 版阶段
目前,任何人都可以将包含模板化消息体验的通信应用发布到 Play 商店的内部测试和封闭测试轨道。稍后将允许发布到开放测试和生产轨道。

除了用于阅读和回复消息的基本通知驱动消息体验之外,Android Auto 还支持使用 汽车版 Android 应用库 构建更丰富的消息体验。

支持通知驱动的消息体验

所有支持模板化消息体验的应用还必须 扩展 Android Auto 的消息通知。这可确保用户无需打开模板化应用即可阅读和回复消息。

构建模板化消息体验

请遵循 使用汽车版 Android 应用库向模板化应用添加对 Android Auto 的支持 中的指导,开始构建应用的模板化体验。然后,请参阅本页面上的指导,了解模板化消息应用的具体要求。

配置应用的清单文件

为了让 Android Auto 了解您的应用的功能,您的应用必须执行以下操作

在清单中声明类别支持

您的应用需要在其 CarAppService 的 Intent 过滤器中声明 androidx.car.app.category.MESSAGING 车载应用类别

<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>

设置最低车载应用 API 级别

由于 ConversationItem API 仅在车载 API 7 或更高版本上受支持,因此您还应将 minCarApiLevel 元数据设为该值。如需了解详情,请参阅 车载应用 API 级别

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

声明对 Android Auto 的支持

在用于 声明对 Android Auto 的支持automotive_app_desc.xml 文件中,请确保同时声明了 notificationtemplate 功能

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

如果您的应用可以设置为 默认短信处理程序,请务必包含以下 <uses> 元素。否则,Android Auto 内置的默认处理程序将用于处理传入的短信/彩信,这可能导致通知重复。

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

显示对话

要显示用户对话的概览,您可以在 ListTemplateSectionedItemTemplate 中显示一个 ConversationItem 对象列表。

为了提供最佳用户体验,我们建议您最多提供 5-10 个最新或最重要的对话,每个对话最多显示 5 条最新消息。这有助于提高加载性能,确保用户看到最相关的内容,并减少互动时间。

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()
    }
}

每个 ConversationItem 都会自动显示用于播放消息、将其标记为已读以及回复的操作。这些操作由您在构建 ConversationItem 时提供的 ConversationCallbackDelegate 处理。

如果您的应用提供 对话快捷方式,请确保构建 ConversationItem 时提供的 ID 与该对话快捷方式的 ID 相同。

更新对话

当用户发送和接收消息时,您应该通过调用 invalidate() 来刷新应用屏幕以显示新消息。请参阅 刷新模板内容

为了提供最佳用户体验,我们建议将刷新时间保持在 500 毫秒或更短。如果频繁刷新时间过长,您可以在加载传入消息时显示加载状态。

适当设置通知重要性

为了减少干扰,当用户正在查看相应的对话时,您的应用应降低传入通知的重要性,以便通知不会显示为浮动通知 (HUN)。

您可以通过观察显示对话的 Screen 的生命周期来跟踪对话是否可见。请参阅 屏幕的生命周期

为了防止通知显示为浮动通知,请将优先级设为 IMPORTANCE_DEFAULT 或更低。

分发模板化消息应用

由于支持模板化消息体验的应用只能发布到 Google Play 上的内部测试和封闭测试轨道,因此您不应将包含此支持的版本推广到开放测试或生产轨道,因为包含这些轨道版本的提交将被拒绝。