内嵌清单

为您的 Android 应用实现 App Actions 时,您可能会发现自己必须处理针对同一主题的不同变体请求。例如,假设您的健身应用实现了 START_EXERCISE 内置 intent (BII),让用户可以通过向 Assistant 说出“好的 Google,在 Example App 上开始跑步”之类的指令来开始各种锻炼。

实现此 intent 需要您的请求匹配逻辑处理每种锻炼类型,包括“慢跑”、“冲刺”或“比赛”等变体。随着支持的锻炼类型增多,此逻辑很快变得笨拙。

对于受支持的 BII(例如 START_EXERCISE),您可以使用内嵌清单避免这种复杂的匹配逻辑。内嵌清单是一组在 shortcuts.xml 中定义的静态 Android 快捷方式,表示您应用中的功能和内容。

每个快捷方式都包含一个 item 标识符和一个同义词列表,表示用户可能如何引用该 item 的各种变体。在调用期间,BII 会将用户提供的 BII 参数与同义词列表进行比较。找到匹配项后,BII 参数会更新为匹配快捷方式的 item 标识符。

内嵌清单让 Google Assistant 在 App Action 调用期间简化提供给您的应用的 BII 参数值。

内嵌清单就像 BII 参数的查找表,使用您定义的 item 标识符表达用户引用应用中功能或内容的多种方式。它们通过让您的 fulfillment 预测来自 BII 参数的 item 标识符来简化您应用的请求匹配逻辑。

Inline inventory user flow diagram
图 1. 使用内嵌清单解释用户提供的锻炼名称以便在应用中支持的锻炼类型下处理 START_EXERCISE 功能的流程图。

限制和替代方案

内嵌清单快捷方式有以下限制

  • 快捷方式限制:每个应用最多可定义 1000 个内嵌清单快捷方式。
  • 同义词限制:每个内嵌清单快捷方式最多可包含 20 个同义词值。
  • 静态定义:内嵌清单快捷方式在 shortcuts.xml 中静态声明,只能通过发布新版本的应用为您的用户更新。

鉴于静态配置的要求,内嵌清单最适合向 Assistant 扩展不常更改、非个性化的应用信息,例如菜单项、公交路线或饮品尺寸。对于其他类型的内容,请考虑以下替代方案

  • 网络清单:让 Assistant 在将用户查询与受支持的应用内容标识符匹配时查询公开网络内容。网络清单查询在调用期间实时发生,让您可以将产品目录、社交媒体帖子和其他频繁更新的内容扩展到 Assistant。

  • 动态快捷方式:将个性化应用内容的清单扩展到 Assistant。动态快捷方式让用户可以快速重放常见操作,例如在订餐应用中重新订购喜爱的饮品,或在笔记应用中调出购物清单。

创建内嵌清单

内嵌清单通过为 Assistant 提供一种便捷的方式,将用户请求应用内容和功能的不同方式转换为您的应用预期的可预测标识符,从而简化开发。例如,假设您的应用提供用户可以通过语音开始的不同锻炼,并且您的应用希望用户针对同一锻炼类型发出以下请求

  • 好的 Google,在 Example App 上开始跑步。
  • 好的 Google,在 Example App 上开始慢跑。

在内嵌清单快捷方式中,您将 shortcutId 设置为 "CARDIO_RUN",这是您的应用预期的锻炼标识符。然后,您指定“run”和“jog”作为与 shortcutId 关联的同义词。然后,当用户使用上述查询触发您的 App Action 时,Assistant 在生成 fulfillment intent 时会使用标识符 "CARDIO_RUN" 作为 BII 参数。

以下来自示例 app/res/shortcuts.xml 文件中的代码段实现了这种情况

<capability android:name="actions.intent.START_EXERCISE">
  <intent
    android:targetPackage="com.example.myapp"
    android:targetClass="com.example.myapp.ExerciseActivity">
    <parameter android:name="exercise.name" android:key="exercise" />
  </intent>
</capability>

<shortcut android:shortcutId="CARDIO_RUN">
  <capability-binding android:key="actions.intent.START_EXERCISE">
    <parameter-binding
      android:key="exercise.name"
      android:value="@array/run_names" />
    </capability-binding>
</shortcut>

在上述示例中,内嵌清单 shortcut<capability-binding> 元素内声明了 <parameter-binding> 标记,并将其绑定到在 <capability> 中定义的 exercise.name BII 参数。

字符串数组资源 @array/run_namesres/values/arrays.xml 中指定了一个同义词列表,Assistant 可以识别该列表并将其映射到 "CARDIO_RUN" item ID

<!-- Synonym values for "CARDIO_RUN" inline inventory -->
<resources>
  <string-array name="run_names">
    <item>Run</item>
    <item>Jog</item>
    <item>Sprint</item>
  </string-array>
</resources>

当为功能提供 <url-template> 时,匹配值的 shortcutId 会插入到生成的 URL 中参数对应的占位符处。以下来自示例 app/res/shortcuts.xml 文件中的代码实现了这种情况

<capability android:name="actions.intent.START_EXERCISE">
  <intent>
    <url-template android:value="myapp://workout{?exercise}" />
    <parameter android:name="exercise.name" android:key="exercise" />
  </intent>
</capability>

<shortcut android:shortcutId="CARDIO_RUN">
  <capability-binding android:key="actions.intent.START_EXERCISE">
    <parameter-binding
      android:key="exercise.name"
      android:value="@array/run_names" />
  </capability-binding>
</shortcut>

在上述示例中,Assistant 生成了 fulfillment deep link myapp://workout?exercise=CARDIO_RUN

使用快捷方式 intent 进行 fulfillment

默认情况下,快捷方式会将匹配的内嵌清单值的 shortcutId 提供给快捷方式绑定到的 capabilityintent,如快捷方式的 <capability-binding> 标记中所声明。您可以通过向 capability 添加 <shortcut-fulfillment> 标记,来指定使用快捷方式本身定义的 intent 进行 fulfillment。

以下来自示例 app/res/shortcuts.xml 文件中的代码实现了快捷方式 fulfillment

<capability android:name="actions.intent.START_EXERCISE">
  <shortcut-fulfillment>
    <parameter android:name="exercise.name"/>
  </shortcut-fulfillment>
</capability>

<shortcut android:shortcutId="CARDIO_RUN">
  <capability-binding android:key="actions.intent.START_EXERCISE">
    <parameter-binding
      android:key="exercise.name"
      android:value="@array/run_names" />
  </capability-binding>
  <intent android:targetPackage="com.example.myapp"
    android:targetClass="com.example.myapp.ExerciseActivity">
    <parameter android:name="exercise.name" android:key="exercise" />
  </intent>
</shortcut>

在上述示例中,如果用户查询与 exercise.name 参数的内嵌清单值匹配,则 <shortcut-fulfillment> 标记指定使用绑定快捷方式的 intent 进行 fulfillment。

用于打开应用功能 BII 的内嵌清单

尽管内嵌清单对于支持它的 BII 通常是可选功能,但对于某些 BII 它是必需的,例如 OPEN_APP_FEATURE。这种常用的 BII 允许用户使用 Assistant 深层链接到特定的应用功能。打开应用功能 BII 需要应用功能名称的内嵌清单,以便在用户深层链接到您的应用之前验证用户请求的功能是否存在。

以下来自示例 app/res/shortcuts.xml 文件中的代码使用代表应用订单状态功能的单个快捷方式实现了此 BII

<capability android:name="actions.intent.OPEN_APP_FEATURE">
  <intent
    android:targetPackage="com.example.myapp"
    android:targetClass="com.example.myapp.MyClass">
    <parameter
       android:name="feature"
       android:key="featureParam" />
  </intent>
  <!-- Required fallback fulfillment to handle when parameters are missing from user query. -->
  <intent
    android:targetPackage="com.example.myapp"
    android:targetClass="com.example.myapp.MyClass">
    <parameter
       android:name="HOME_SCREEN"
       android:key="featureParam" />
  </intent>
</capability>

<!-- Inline inventory for OPEN_APP_FEATURE. -->

<shortcut android:shortcutId="ORDER_STATUS">
  <capability-binding android:key="actions.intent.OPEN_APP_FEATURE">
    <parameter-binding
      android:key="feature"
      android:value="@array/order_status_names" />
    </capability-binding>
</shortcut>

res/values/arrays.xml 中的字符串数组资源 @array/order_status_names 指定了此功能的同义词列表

<resources>
  <string-array name="order_status_names">
    <item>Order status</item>
    <item>Orders</item>
    <item>Order history</item>
  </string-array>
</resources>

在上述功能到位后,Assistant 可以针对同一功能处理各种短语

  • “好的 Google,在 Example App 上显示我的订单状态。”
  • “好的 Google,在 Example App 上显示我的订单。”
  • “好的 Google,在 Example App 上显示我的订单历史记录。”

测试内嵌清单

通过检查 Assistant 在处理相关 App Action 功能时提供给您的应用的 BII 参数值来测试您的清单。内嵌清单的工作原理是将清单绑定 BII 参数的用户提供值替换为匹配的内嵌清单快捷方式的 shortcutId

例如,START_EXERCISE BII 功能可以使用内嵌清单将用户提供的 BII 参数“run”转换为其对应的锻炼 ID "CARDIO_RUN"

Google Assistant 插件允许您在测试设备上通过 Assistant 预览内嵌清单 App Actions。使用该插件测试您的清单,请按照以下步骤操作

  1. 配置您的 BII 功能的清单绑定参数,为其关联内嵌清单的同义词值。
  2. 从插件触发 BII,在您的测试设备上调用它。
  3. 检查 Assistant 在 App Action fulfillment 期间提供给您的应用的最终参数值。