为助理优化上下文内容

Android 6.0 Marshmallow 引入了一种新的方式,让用户可以通过助理应用(例如 Google 助理)与应用互动。助理是一个顶级窗口,用户可以通过它查看当前活动的相关操作。这些操作可能包括指向设备上其他应用的深层链接。

用户可以通过长按主页按钮或说出 关键词 来激活助理。作为响应,系统会打开一个顶级窗口,显示相关操作。

助理应用(例如 Google 助理)通过名为“Now on Tap”的功能实现助理叠加窗口,该功能与 Android 平台级功能协同工作。系统允许用户选择一个助理应用,该应用使用 Android 的 Assist API 从您的应用获取上下文信息。

本指南介绍了 Android 应用如何使用 Android 的 Assist API 来改善助理用户体验。要了解如何创建媒体应用,以便助理可以启动和控制,请参阅 Google 助理和媒体应用

使用助理

图 1 说明了用户与助理的典型互动。当用户长按主页按钮时,Assist API 回调会在应用中被调用(步骤 1)。助理呈现叠加窗口(步骤 2 和 3),然后用户选择要执行的操作。助理执行所选操作,例如使用指向(目标)餐厅应用的深层链接触发意图(步骤 4)。

图 1. 助理与 Google 应用的“Now on Tap”功能交互示例

用户可以通过选择设置 > 应用 > 默认应用 > 助理和语音输入来配置助理。用户可以更改系统选项,例如以文本形式访问屏幕内容和访问屏幕截图,如图 2 所示。

图 2. 助理和语音输入设置

源应用

为了确保您的应用能够作为用户的信息源与助理配合使用,您只需遵循 辅助功能最佳实践即可。本部分介绍了如何提供其他信息以帮助改善助理用户体验,以及需要特殊处理的场景,例如自定义 View。

与助理共享其他信息

除了文本和屏幕截图之外,您的应用还可以与助理共享其他信息。例如,您的音乐应用可以选择传递当前专辑信息,以便助理可以根据当前活动建议更智能的操作。请注意,Assist API 不提供媒体控件。要添加媒体控件,请参阅 Google 助理和媒体应用

要向助理提供其他信息,您的应用通过注册应用侦听器并使用活动回调提供特定于活动的的信息来提供全局应用上下文,如图 3 所示

图 3. Assist API 生命周期序列图

要提供全局应用上下文,应用会创建 Application.OnProvideAssistDataListener 的实现,并使用 registerOnProvideAssistDataListener() 注册它。要提供特定于活动的上下文信息,活动会覆盖 onProvideAssistData()onProvideAssistContent()。这两个活动方法是在可选的全局回调被调用之后调用的。由于回调在主线程上执行,因此它们应快速完成。仅当活动正在运行时才会调用回调。

提供上下文

当用户激活助理时,会调用 onProvideAssistData() 以构建一个完整的 ACTION_ASSIST 意图,其中所有当前应用的上下文都表示为 AssistStructure 的实例。您可以覆盖此方法,将您想要的任何内容放入 bundle 中,以显示在 assist 意图的 EXTRA_ASSIST_CONTEXT 部分。

描述内容

您的应用可以实现 onProvideAssistContent(),通过提供与当前活动相关的内容相关参考来改善助理用户体验。您可以使用 Schema.org 定义的通用词汇表通过 JSON-LD 对象来描述应用内容。在下面的示例中,音乐应用提供了结构化数据来描述用户当前正在查看的音乐专辑

Kotlin

override fun onProvideAssistContent(assistContent: AssistContent) {
    super.onProvideAssistContent(assistContent)

    val structuredJson: String = JSONObject()
            .put("@type", "MusicRecording")
            .put("@id", "https://example.com/music/recording")
            .put("name", "Album Title")
            .toString()

    assistContent.structuredData = structuredJson
}

Java

@Override
public void onProvideAssistContent(AssistContent assistContent) {
  super.onProvideAssistContent(assistContent);

  String structuredJson = new JSONObject()
       .put("@type", "MusicRecording")
       .put("@id", "https://example.com/music/recording")
       .put("name", "Album Title")
       .toString();

  assistContent.setStructuredData(structuredJson);
}

您还可以通过自定义实现 onProvideAssistContent() 来改善用户体验,这可以带来以下好处

注意:使用自定义文本选择实现的应用可能需要实现 onProvideAssistContent() 并调用 setClipData()

默认实现

如果既未实现 onProvideAssistData() 也未实现 onProvideAssistContent() 回调,系统仍会继续并将自动收集的信息传递给助手,除非当前窗口被标记为 安全。如图 3 所示,系统使用 onProvideStructure()onProvideVirtualStructure() 的默认实现来收集文本和视图层次结构信息。如果您的视图实现了自定义文本绘制,请覆盖 onProvideStructure() 以通过调用 setText(CharSequence) 为助手提供显示给用户的文本。

在大多数情况下,实现辅助功能支持可以让助手获取所需的信息。 要实现辅助功能支持,请遵循 使应用程序可访问 中描述的最佳实践,包括以下内容

从助手排除视图

为了处理敏感信息,您的应用可以通过设置 FLAG_SECURE 布局参数(WindowManager)来将当前视图从助手排除。您必须为活动创建的每个窗口(包括对话框)显式设置 FLAG_SECURE。您的应用还可以使用 setSecure() 将表面从助手排除。没有全局(应用级别)机制可以将所有视图从助手排除。请注意,FLAG_SECURE 不会导致 Assist API 回调停止触发。使用 FLAG_SECURE 的活动仍然可以使用本指南前面介绍的回调显式地向助手应用提供信息。

注意:对于企业帐户(Android for Work),管理员可以使用 setScreenCaptureDisabled() 方法(DevicePolicyManager API)禁用工作资料的助手数据收集。

语音交互

关键词检测 时也会调用 Assist API 回调。有关更多信息,请参阅 语音操作 文档。

Z 轴顺序注意事项

助手使用一个轻量级叠加窗口,显示在当前活动之上。由于用户可以随时激活助手,因此请勿创建与叠加窗口冲突的永久性 系统警报 窗口,如图 4 所示。

图 4. 助手图层 Z 轴顺序

如果您的应用使用 系统警报 窗口,请立即将其移除,因为将其保留在屏幕上会降低用户体验。

目标应用

助手应用通常利用深度链接来查找目标应用。要使您的应用成为潜在的目标应用,请考虑添加 深度链接 支持。当前用户上下文与叠加窗口中显示的深度链接或其他潜在操作之间的匹配特定于 Google 助理的实现。例如,Google 助理应用使用深度链接和 应用链接 来将流量引导至目标应用。

实现您自己的助手

您可能希望实现您自己的助手。如图 2 所示,用户可以选择活动的助手应用。助手应用必须提供 VoiceInteractionSessionServiceVoiceInteractionSession 的实现,如 VoiceInteraction 示例 中所示。它还需要 BIND_VOICE_INTERACTION 权限。然后,助手可以在 onHandleAssist() 中接收表示为 AssistStructure 实例的文本和视图层次结构。它通过 onHandleScreenshot() 接收屏幕截图。