Car Messenger 可提供专为汽车设备设计的消息功能。与其他汽车应用一样,用户从启动器启动 Car Messenger。
Car Messenger 的新变化
借助全新的 Car Messenger 应用,驾驶员可以:
- 获享专属消息功能。
- 从启动器启动 Car Messenger。
- 浏览在开车前和开车期间收到的消息。
- 收听和回复消息。
- 忽略消息通知。
- 发起新对话。
术语
本页使用了以下术语:
未捆绑应用的优势
未捆绑应用(例如 Car Messenger)具有以下优势:
- 仅使用公共方法(不对隐藏 API 具有平台依赖性)
- 在 Android 平台之外开发应用
- 发布版本更频繁(用于发布新功能和修复问题)
- 通过 Google Play 更新应用
详细了解未捆绑应用。
技术详情
本部分介绍了 Car Messenger 的架构。如需了解详情,请参阅与 CarVoiceInteractionSession 集成。
基于电话的架构
通过蓝牙配对时,数据会从手机的电话数据库同步到汽车的电话数据库。 蓝牙断开连接后,系统会从汽车的电话数据库中删除已同步的数据。
Android 12 中引入了此功能。主要优势包括:
- 可以从数据库中检索批量用户消息。
- 支持之前驾车的消息。
- 在 Android 手机上使用类似的架构和 API 来存储和检索短信。
- 从 Android 平台完全解除捆绑。
具体流程如下:
图 1. 基于电话的数据传输。
以文字形式说明的传输过程:
1. Phone connects to car.
|
--> 2. SMS data transferred from phone's database to car database.
|
--> 3. Car Messenger retrieves data from telephony database to display on UI.
|
--> 4. User interactions prompt the voice assistant.
|
<-- 5. Car Messenger receives reply action from the voice assistant.
|
<-- 6. SMS is marked as read in car database.
|
7. Reply transmitted to recipients, phone database updated with reply and read status.
以下是我们对数据执行的操作:
图 2. Car Messenger 数据处理。
以文字形式说明的传输过程:
1. Phone connects to car.
|
--> 2. SMS data transferred from phone's database to car database.
|
--> 3. Phone disconnects from car.
|
--> 4. SMS data deleted from car telephony database.
- 连接后,系统会使用蓝牙 MAP 将数据从手机传输到汽车。
- 断开连接后,系统会从汽车的数据库中删除该手机的数据。
下载 Car Messenger
从 Google Git 获取最新的 Car Messenger 提交内容。
语音交互 API
Car Messenger 使用 CarVoiceInteractionSession API 与助理集成。下文将对这些元素进行描述。
PendingIntent 模型
这些 API 使用 PendingIntent
将已解析的助理查询传回给 Car Messenger。
以下是事件的顺序:
Car Messenger 通过调用
activity.showAssist(Bundle args)
启动助理。参数包含 API 操作及其必需参数,并根据需要包含一个待处理 intent。助理会根据需要检索用户输入,并将其与待处理 intent 打包在一起。
助理会将 intent 发回 Car Messenger。
Car Messenger 解析 API 操作。
标记为已读 API 操作
当助理朗读消息时,系统会将 PendingIntent
发送给 Car Messenger,并使用 VOICE_ACTION_READ_NOTIFICATION
或 VOICE_ACTION_READ_CONVERSATION
操作将消息标记为已读。
Direct Reply API 操作
当助理回复消息时,系统会将 PendingIntent
发送给 Car Messenger,并使用 VOICE_ACTION_REPLY_NOTIFICATION
或 VOICE_ACTION_REPLY_CONVERSATION
操作来回复对话。
Direct Send SMS API 操作
包含 VOICE_ACTION_SEND_SMS
操作的软件包会从 Car Messenger 发送到助理。
示例代码:
/**
* KEY_PHONE_NUMBER - Recipient’s phone number. If this and the recipients name are not
* provided by the application, assistant must do contact disambiguation but is not required
* to add the name to the PendingIntent.
*
* KEY_RECIPIENT_NAME - Recipient’s name. If this and the recipient phone number are not
* provided by the application, assistant must do contact disambiguation but is not required
* to add the name to the PendingIntent.
*
* KEY_RECIPIENT_UID - Recipient’s UID in the ContactProvider database. Optionally provided
* by the application. Not required to be sent back by the assistant.
*
* KEY_DEVICE_NAME - Friendly name of the device in which to send the message from. If not
* provided by the application, assistant must do device disambiguation but is not required
* to add it to PendingIntent. In V1 this is required to be sent by the application.
*
* KEY_DEVICE_ADDRESS - Bluetooth device address of the device in which to send the message
* from. If not provided by the application, assistant must do device disambiguation and add
* this to the PendingIntent. In V1 this is required to be sent by the application.
*
* KEY_SEND_PENDING_INTENT - @NotNull Will always be provided by the application. The
* application must preload the pending intent with any KEYs it provides the assistant that
* is also needed to send the message. (I.e if the application passes in the
* KEY_PHONE_NUMBER in the Bundle, the assistant can assume the application has already put
* this in the PendingIntent and may not re-add it to the PendingIntent).
*
*/
public static final String KEY_PHONE_NUMBER = “KEY_PHONE_NUMBER”;
public static final String KEY_RECIPIENT_NAME = “KEY_RECIPIENT_NAME”;
public static final String KEY_RECIPIENT_UID = “KEY_RECIPIENT_UID”;
public static final String KEY_DEVICE_NAME = “KEY_DEVICE_NAME”;
public static final String KEY_DEVICE_ADDRESS = “KEY_DEVICE_NAME”;
public static final String KEY_SEND_PENDING_INTENT =”KEY_SEND_PENDING_INTENT”;
下图展示了在选择接收人后撰写消息的过程:
图 3. 拨号器应用中的“通讯录”页面。
下图展示了在未选择接收人时使用新消息按钮撰写消息的情况:
图 4. Messenger 应用中的“新消息”按钮。
集成 Direct Send SMS 操作
以下是拨号器集成 VOICE_ACTION_SEND_SMS
的示例,提供了可选参数:
/**
* Build the {@link Bundle} to pass to assistant to send a sms.
*/
public Bundle buildDirectSendBundle(String number, String name, String uid,
BluetoothDevice device) {
Bundle bundle = new Bundle();
bundle.putString(CarVoiceInteractionSession.KEY_ACTION, VOICE_ACTION_SEND_SMS);
// start optional parameters
bundle.putString(CarVoiceInteractionSession.KEY_PHONE_NUMBER, number);
bundle.putString(CarVoiceInteractionSession.KEY_RECIPIENT_NAME, name);
bundle.putString(CarVoiceInteractionSession.KEY_RECIPIENT_UID, uid);
// end optional parameters
bundle.putString(CarVoiceInteractionSession.KEY_DEVICE_ADDRESS, device.getAddress());
bundle.putString(CarVoiceInteractionSession.KEY_DEVICE_NAME,
DialerUtils.getDeviceName(mContext, device));
Intent intent = new Intent(mContext, MessagingService.class)
.setAction(ACTION_DIRECT_SEND)
.setClass(mContext, MessagingService.class);
int requestCode = ACTION_DIRECT_SEND.hashCode();
PendingIntent pendingIntent = PendingIntent.getForegroundService(
mContext, requestCode, intent,
PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE);
bundle.putParcelable(KEY_SEND_PENDING_INTENT, pendingIntent);
return bundle;
}
增强 TTR 和直接回复
更新后的 API 现在使用功能多样的 Conversation
类,允许除通知领域之外的操作,并在应用的上下文中扩展功能。这取代了之前使用 StatusBarNotification
类的要求。
调试 Car Messenger
请参阅以下部分,详细了解如何调试 Car Messenger。
调试蓝牙连接
运行命令
dumpsys
:adb shell dumpsys bluetooth_manager
- 在 dumpsys 命令输出中搜索
MapClientService
。
Profile: MapClientService mCurrentDevice: 99:99 (Pixel XL) name=Mce state=Connected
- 在 dumpsys 命令输出中搜索
确认列出的设备正确无误。例如:
图 5. 设备列表。
如果未找到任何设备,请执行以下操作之一:
- 重新连接蓝牙。
OR
- 在蓝牙设置中,确认短信已开启。
OR
- 在手机上,确认已授予消息访问权限。
调试蓝牙数据库
Car Messenger 基于电话数据库构建而成。如需确定蓝牙是否正在填充该数据库,您可以使用表中的命令。
任务 | 命令 |
---|---|
对话 | adb shell content query--uri content://mms-sms/conversations?simple=true |
仅短信 | adb shell content query--uri content://sms |
彩信/短信 | adb shell content query--uri content://mms-sms/conversations |
仅彩信 | adb shell content query--uri content://mms |
仅彩信收件箱 | adb shell content query--uri content://mms/conversations/inbox |
仅发送的短信 | adb shell content query--uri content://sms/sent |
仅短信收件箱 | adb shell content query--uri content://sms/conversations/inbox |
彩信第 1 部分 (将 1 替换为彩信 ID) |
adb shell content query--uri content://mms/part/1 |
调试 Car Messenger 和语音助理查询
如果构建映像为 eng
或 userdebug
,则默认输出日志。否则,要为 Car Messenger 启用日志记录,请按以下步骤操作:
针对相关标记
adb shell setprop log.tag.<TAG> DEBUG
运行。为预加载的助理启用日志记录功能。
对于可重现率极高的 bug,请考虑通过 Android Studio 使用断点。