优化 Google 助理的上下文内容

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

用户可通过长按主屏幕按钮或说出一个启动指令来启用 Google 助理。 系统随即会打开一个顶级窗口,其中显示了与上下文相关的操作。

智能助理应用(例如 Google 助理)会通过一项名为“点按即时卡”的功能实现智能助理叠加窗口,该功能可与 Android 平台级功能配合使用。系统允许用户选择一款辅助应用,该应用会使用 Android 的 Assist API 从您的应用获取上下文信息。

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

使用 Google 助理

图 1 显示了用户通常与智能助理进行的一些互动。当用户长按主屏幕按钮时,系统会在来源应用中调用 Assist API 回调(第 1 步)。Google 助理渲染叠加窗口(第 2 步和第 3 步),然后由用户选择要执行的操作。Google 助理执行所选操作,例如触发一个包含指向(目标)餐厅应用的深层链接的 intent(第 4 步)。

图 1. Google 助理与 Google 应用的“点按即时卡”功能互动示例

用户可以依次选择设置 > 应用 > 默认应用 > 辅助和语音输入来配置智能助理。用户可以更改系统选项,例如获取屏幕上的文本内容和访问屏幕截图,如图 2 所示。

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

来源应用

为了确保您的应用与智能助理一起作为用户的信息来源,您只需遵循无障碍功能最佳做法。本部分介绍了如何提供更多信息以帮助改善 Google 助理的用户体验以及需要特殊处理的场景,例如自定义视图。

与智能助理分享更多信息

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

为了向智能助理提供其他信息,您的应用会通过注册应用监听器来提供全局应用上下文,并通过 Activity 回调提供特定于 Activity 的信息,如图 3 所示:

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

为了提供全局应用上下文,应用会创建 Application.OnProvideAssistDataListener 的实现,并使用 registerOnProvideAssistDataListener() 注册该实现。为了提供特定于 activity 的上下文信息,activity 会替换 onProvideAssistData()onProvideAssistContent()。 系统会在调用可选的全局回调之后调用这两个 activity 方法。由于回调在主线程上执行,因此它们应该立即完成。 只有在 Activity 运行时才会调用回调。

提供上下文

当用户激活 Google 助理时,系统会调用 onProvideAssistData() 以构建一个完整的 ACTION_ASSIST intent,并将当前应用的所有上下文表示为 AssistStructure 的实例。您可以替换此方法,将您所需的任何内容放入软件包中,使其显示在辅助 intent 的 EXTRA_ASSIST_CONTEXT 部分中。

描述内容

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

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) 向 Google 助理提供向用户显示的文本。

在大多数情况下,通过实现无障碍支持,智能助理能够获取所需信息。如需实现无障碍功能支持,请遵循使应用易于访问中所述的最佳实践,包括以下做法:

从 Google 助理中排除视图

如需处理敏感信息,您的应用可以通过设置 WindowManagerFLAG_SECURE 布局参数从智能助理中排除当前视图。您必须为 Activity 创建的每个窗口(包括对话框)明确设置 FLAG_SECURE。您的应用还可以使用 setSecure() 从智能助理中排除某个界面。没有全局(应用级)机制可以从智能助理中排除所有视图。请注意,FLAG_SECURE 不会导致 Assist API 回调停止触发。使用 FLAG_SECURE 的 activity 仍然可以使用本指南前面介绍的回调向助理应用明确提供信息。

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

语音互动

检测到启动指令时,系统也会调用 Assist API 回调。如需了解详情,请参阅语音操作文档。

Z 轴顺序注意事项

助理使用在当前 activity 之上显示的轻量级叠加窗口。由于用户可以随时激活智能助理,因此请不要创建干扰叠加窗口的永久性 系统提醒窗口,如图 4 所示。

图 4. 辅助层 Z 顺序

如果您的应用使用 系统提醒窗口,请立即将其移除,因为将它们留在屏幕上会影响用户体验。

目标应用

Google 助理应用通常会利用深层链接查找目标应用。如需使您的应用成为潜在的目标应用,请考虑添加深层链接支持。当前用户上下文与叠加层窗口中显示的深层链接或其他潜在操作(如图 1 的第 3 步所示)之间的匹配取决于 Google 助理的实现。例如,Google 助理应用使用深层链接和应用链接将流量引向目标应用。

实现您自己的智能助理

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