本指南介绍了将操作从 actions.xml
文件迁移到 shortcuts.xml
文件时可以采取的基本步骤。您可以参照本指南,并配合使用与应用有关的 Action 的 actions.xml 到 shortcuts.xml 转换实用程序,以简化迁移到 shortcuts.xml
格式的过程。
actions.xml 与 shortcuts.xml 之间的差异
actions.xml
与 shortcuts.xml
文件之间存在一些重大差异:
您使用用于定义应用语音 capability 的同一文件(通常是应用项目中的
res/xml/shortcuts.xml
)来定义 Android 快捷方式。如果您之前为应用实现了静态 Android 快捷方式,请将操作从actions.xml
迁移到这个现有文件。entity 集已不再存在,而是改为使用
shortcut
元素来定义 entity。深层链接仍然受支持,但不是执行方式的核心方法;而是改为使用显式 Android intent。
前提条件
如需支持 shortcuts.xml
中的属性使用的 app
命名空间,您必须在应用中添加 Android Jetpack Core 库 1.6.0 或更高版本。本页面上的示例演示了何时需要使用 app
命名空间。
设置 shortcuts.xml
如果您之前为应用实现了 Android 快捷方式,请使用该文件来设置您的 capability。
如果 shortcuts.xml
文件不存在,请按以下步骤操作:
在应用项目的
res/xml
目录中,创建shortcuts.xml
文件。移除
AndroidManifest.xml
文件中引用actions.xml
的<meta-data>
标记。使用 activity 中同时具有针对
MAIN
和LAUNCHER
的 intent 过滤器的<meta-data>
标记,在AndroidManifest.xml
中添加对shortcuts.xml
的引用。有关此过程的详细信息,请参阅创建快捷方式概览。在
shortcuts.xml
中,定义shortcuts
元素,如以下示例所示:<?xml version="1.0" encoding="utf-8"?> <shortcuts xmlns:android="http://schemas.android.com/apk/res/android"> </shortcuts>
设置 capability
将操作从 actions.xml
文件迁移到 shortcuts.xml
文件时,您必须设置 capability
元素。capability
可标识应用希望识别的与应用有关的 Action intent。若要进行迁移,必须将 actions.xml
中的每个操作都转换成 shortcuts.xml
中的 capability。
如果您有与操作关联的 entity 集,请完成此流程以添加 capability,然后设置快捷方式来代表 entity 集。
如需详细了解如何设置 capability,请参阅创建 shortcuts.xml
。
如需将操作迁移到 capability,请按以下步骤操作:
在
shortcuts.xml
的shortcuts
元素中,定义capability
元素:<?xml version="1.0" encoding="utf-8"?> <shortcuts xmlns:android="http://schemas.android.com/apk/res/android"> <capability> </capability> </shortcuts>
将
capability
的android:name
属性设为相应操作使用的 BII。在actions.xml
中,该值就位于action
元素的intentName
属性中。如果您的操作使用自定义 intent,您还必须添加
app:queryPatterns
属性。在actions.xml
中,该值就位于action
元素的queryPatterns
属性中。举例来说,假设您的操作调用
actions.intent.RECORD_FOOD_OBSERVATION
intent,如以下示例actions.xml
中所示:内置 intent
<?xml version="1.0" encoding="utf-8"?> <actions> <action intentName="actions.intent.RECORD_FOOD_OBSERVATION"> ... </action> </actions>
在此示例的
shortcuts.xml
中,您将capability
的android:name
属性设置为actions.intent.RECORD_FOOD_OBSERVATION
:<shortcuts xmlns:android="http://schemas.android.com/apk/res/android"> <capability android:name="actions.intent.RECORD_FOOD_OBSERVATION"> </capability> </shortcuts>
自定义 intent
<?xml version="1.0" encoding="utf-8"?> <actions> <action intentName="custom.actions.intent.RECORD_FOOD_OBSERVATION" queryPatterns="@array/foodObservationQueries"> ... </action> </actions>
在此示例的
shortcuts.xml
中,您将capability
的android:name
属性设为actions.intent.RECORD_FOOD_OBSERVATION
,将app:queryPatterns
设为@array/foodObservationQueries
:<?xml version="1.0" encoding="utf-8"?> <shortcuts xmlns:android="http://schemas.android.com/apk/res/android"> <capability android:name="custom.actions.intent.RECORD_FOOD_OBSERVATION" app:queryPatterns="@array/foodObservationQueries"> </capability> </shortcuts>
在
capability
中,为操作中定义的每个fulfillment
创建intent
或slice
。只有在fulfillment
的fulfillmentMode
属性设为actions.fulfillment.SLICE
时,才需要添加slice
元素。否则,请创建intent
元素。 详见下例shortcuts.xml
:深层链接(默认)
<?xml version="1.0" encoding="utf-8"?> <shortcuts xmlns:android="http://schemas.android.com/apk/res/android"> <capability android:name="actions.intent.RECORD_FOOD_OBSERVATION"> <intent> </intent> </capability> </shortcuts>
Slice
<?xml version="1.0" encoding="utf-8"?> <shortcuts xmlns:android="http://schemas.android.com/apk/res/android"> <capability android:name="actions.intent.RECORD_FOOD_OBSERVATION"> <slice> </slice> </capability> </shortcuts>
针对在上一步创建的每个元素,定义
url-template
元素,并将android:value
属性设为fulfillment
元素中url-template
属性所使用的相同值。举例来说,假设您的操作在
actions.xml
中使用以下网址模板:<?xml version="1.0" encoding="utf-8"?> <actions> <action intentName="actions.intent.RECORD_FOOD_OBSERVATION"> ... <fulfillment urlTemplate="myfoodapp://record{?food,meal}"> ... </fulfillment> </action> </actions>
在此示例的
shortcuts.xml
中,您将url-template
元素的android:value
属性设置为myfoodapp://record{?food,meal}
:深层链接(默认)
<?xml version="1.0" encoding="utf-8"?> <shortcuts xmlns:android="http://schemas.android.com/apk/res/android"> <capability android:name="actions.intent.RECORD_FOOD_OBSERVATION"> <intent> <url-template android:value="myfoodapp://record{?food,meal}" /> </intent> </capability> </shortcuts>
Slice
<?xml version="1.0" encoding="utf-8"?> <shortcuts xmlns:android="http://schemas.android.com/apk/res/android"> <capability android:name="actions.intent.RECORD_FOOD_OBSERVATION"> <slice> <url-template android:value="myfoodapp://record{?food,meal}" /> </slice> </capability> </shortcuts>
针对操作网址模板的每个
parameter-mapping
元素,定义parameter
元素,并设置android:name
和android:key
属性的值。将
android:name
设为与parameter-mapping
元素的intentParameter
属性相同的值。将
android:key
设为与parameter-mapping
元素的urlParameter
属性相同的值。
如果需要一个或多个参数,则将
parameter
的android:required
属性设为true
。举例来说,假设您的操作在
actions.xml
中包含以下针对网址模板的参数映射:<?xml version="1.0" encoding="utf-8"?> <actions> <action intentName="actions.intent.RECORD_FOOD_OBSERVATION"> ... <fulfillment urlTemplate="myfoodapp://record{?food,meal}"> ... <parameter-mapping intentParameter="foodObservation.forMeal" urlParameter="meal" entityMatchRequired="true" /> <parameter-mapping intentParameter="foodObservation.aboutFood.name" urlParameter="food" /> </fulfillment> </action> </actions>
在此示例中,您将在
shortcuts.xml
中创建以下parameter
元素:深层链接(默认)
<?xml version="1.0" encoding="utf-8"?> <shortcuts xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <capability android:name="actions.intent.RECORD_FOOD_OBSERVATION"> <intent> <url-template android:value="myfoodapp://record{?food,meal}" /> <parameter android:name="foodObservation.forMeal" android:key="meal" android:required="true" app:shortcutMatchRequired="true" /> <parameter android:name="foodObservation.aboutFood.name" android:key="food" /> </intent> </capability> </shortcuts>
Slice
<?xml version="1.0" encoding="utf-8"?> <shortcuts xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <capability android:name="actions.intent.RECORD_FOOD_OBSERVATION"> <slice> <url-template android:value="myfoodapp://record{?food,meal}" /> <parameter android:name="foodObservation.forMeal" android:key="meal" android:required="true" /> <parameter android:name="foodObservation.aboutFood.name" android:key="food" /> </slice> </capability> </shortcuts>
设置快捷方式
在 shortcuts.xml
中,entity 会以快捷方式的形式表示。如果您尚未将各项操作迁移到对应 capability,就必须先为每项操作设置 capability。从 actions.xml
迁移到 shortcuts.xml
时,如果您的操作包含 entity 集,您必须为每个 entity 都创建一个 shortcut
。
以下示例演示了迁移步骤。
假设在 actions.xml
中您的原始操作如下所示:
<?xml version="1.0" encoding="utf-8"?>
<actions>
<action intentName="actions.intent.RECORD_FOOD_OBSERVATION">
<parameter name="foodObservation.forMeal">
<entity-set-reference entitySetId="MealEntitySet"/>
</parameter>
<fulfillment urlTemplate="myfoodapp://record{?food,meal}">
<parameter-mapping
intentParameter="foodObservation.forMeal"
urlParameter="meal"
entityMatchRequired="true" />
<parameter-mapping
intentParameter="foodObservation.aboutFood.name"
urlParameter="food" />
</fulfillment>
</action>
<entity-set entitySetId="MealEntitySet">
<entity
sameAs="http://schema.googleapis.com/MealTypeBreakfast"
identifier="1" />
<entity
sameAs="http://schema.googleapis.com/MealTypeLunch"
identifier="2" />
<entity
sameAs="http://schema.googleapis.com/MealTypeDinner"
identifier="3" />
</entity-set>
</actions>
在此示例中,假设您已在 shortcuts.xml
中定义相应 capability,包括 intent 和参数:
<?xml version="1.0" encoding="utf-8"?>
<shortcuts
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<capability android:name="actions.intent.RECORD_FOOD_OBSERVATION">
<intent>
<url-template android:value="myfoodapp://record{?food,meal}" />
<parameter
android:name="foodObservation.forMeal"
android:key="meal"
android:required="true" />
<parameter
android:name="foodObservation.aboutFood.name"
android:key="food" />
</intent>
</capability>
</shortcuts>
如需为 entity 设置快捷方式,请按以下步骤操作:
在
shortcuts
元素中,为每个参数和 entity 定义shortcut
元素,并设置android:shortcutId
属性的值。android:shortcutId
的值必须与对应 entity 的identifier
属性相同。在此示例中,您将为
MealEntitySet
entity 集中的每个 entity 创建快捷方式,以下示例shortcuts.xml
中所示:<?xml version="1.0" encoding="utf-8"?> <shortcuts> <capability android:name="actions.intent.RECORD_FOOD_OBSERVATION"> ... </capability> <shortcut android:shortcutId="1"> </shortcut> <shortcut android:shortcutId="2"> </shortcut> <shortcut android:shortcutId="3"> </shortcut> </shortcuts>
为每个快捷方式都定义一个
capability-binding
元素。将android:key
属性设为 capability 中的内置 intent 或自定义 intent:... <shortcut android:shortcutId="1"> <capability-binding android:key="actions.intent.RECORD_FOOD_OBSERVATION"> </capability-binding> </shortcut> <shortcut android:shortcutId="2"> <capability-binding android:key="actions.intent.RECORD_FOOD_OBSERVATION"> </capability-binding> </shortcut> <shortcut android:shortcutId="3"> <capability-binding android:key="actions.intent.RECORD_FOOD_OBSERVATION"> </capability-binding> </shortcut> ...
在每个
capability-binding
中,定义parameter-binding
,并将android:key
属性设为 intent 中相应参数的名称:... <shortcut android:shortcutId="1"> <capability-binding android:key="actions.intent.RECORD_FOOD_OBSERVATION"> <parameter-binding android:key="foodObservation.forMeal" /> </capability-binding> </shortcut> <shortcut android:shortcutId="2"> <capability-binding android:key="actions.intent.RECORD_FOOD_OBSERVATION"> <parameter-binding android:key="foodObservation.forMeal" /> </capability-binding> </shortcut> <shortcut android:shortcutId="3"> <capability-binding android:key="actions.intent.RECORD_FOOD_OBSERVATION"> <parameter-binding android:key="foodObservation.forMeal" /> </capability-binding> </shortcut> ...
向
parameter-binding
添加android:value
属性,然后定义extra
元素。在相同的示例中,若要支持 entity,则需更新
meal_breakfast
、meal_lunch
和meal_dinner
的capability-bindings
,并添加对应的extra
元素:... <shortcut android:shortcutId="1"> <capability-binding android:key="actions.intent.RECORD_FOOD_OBSERVATION"> <parameter-binding android:key="foodObservation.forMeal" /> </capability-binding> <extra android:key="sameAs" android:value="http://schema.googleapis.com/MealTypeBreakfast" /> </shortcut> <shortcut android:shortcutId="2"> <capability-binding android:key="actions.intent.RECORD_FOOD_OBSERVATION"> <parameter-binding android:key="foodObservation.forMeal" /> </capability-binding> <extra android:key="sameAs" android:value="http://schema.googleapis.com/MealTypeLunch" /> </shortcut> <shortcut android:shortcutId="3"> <capability-binding android:key="actions.intent.RECORD_FOOD_OBSERVATION"> <parameter-binding android:key="foodObservation.forMeal" /> </capability-binding> <extra android:key="sameAs" android:value="http://schema.googleapis.com/MealTypeDinner" /> </shortcut> ...
您已迁移的 capability 现在已准备好进行测试。
示例:actions.xml 对比 shortcuts.xml
以下示例演示了分别使用 actions.xml
和 shortcuts.xml
文件实现的与应用有关的 Action。
actions.xml - 财经
<?xml version="1.0" encoding="utf-8"?>
<actions>
<action intentName="actions.intent.CREATE_MONEY_TRANSFER">
<fulfillment urlTemplate="mybankapp://transfer{?amount,currency,recipientBankAccountType,senderBankAccountType,mode}">
<parameter-mapping
intentParameter="moneyTransfer.amount.value"
urlParameter="amount" />
<parameter-mapping
intentParameter="moneyTransfer.amount.currency"
urlParameter="currency" />
<parameter-mapping
intentParameter="moneyTransfer.moneyTransferDestination.name"
urlParameter="recipientBankAccountType" />
<parameter-mapping
intentParameter="moneyTransfer.moneyTransferOrigin.name"
urlParameter="senderBankAccountType" />
<parameter-mapping
intentParameter="moneyTransfer.transferMode"
urlParameter="mode" />
</fulfillment>
</action>
</actions>
shortcuts.xml - 财经
<?xml version="1.0" encoding="utf-8"?>
<shortcuts>
<capability android:name="actions.intent.CREATE_MONEY_TRANSFER">
<intent>
<url-template android:value="mybankapp://transfer{?amount,currency,recipientBankAccountType,senderBankAccountType,mode}" />
<parameter
android:name="moneyTransfer.amount.value"
android:key="amount"
android:required="true" />
<parameter
android:name="moneyTransfer.amount.currency"
android:key="currency" />
<parameter
android:name="moneyTransfer.moneyTransferDestination.name"
android:key="recipientBankAccountType" />
<parameter
android:name="moneyTransfer.moneyTransferOrigin.name"
android:key="senderBankAccountType" />
<parameter
android:name="moneyTransfer.transferMode"
android:key="mode" />
</intent>
</capability>
</shortcuts>
actions.xml - 健身与营养
<?xml version="1.0" encoding="utf-8"?>
<actions>
<action intentName="actions.intent.RECORD_FOOD_OBSERVATION">
<parameter name="foodObservation.forMeal">
<entity-set-reference entitySetId="MealEntitySet"/>
</parameter>
<fulfillment urlTemplate="myfoodapp://record{?food,meal}">
<parameter-mapping
intentParameter="foodObservation.forMeal"
urlParameter="meal"
entityMatchRequired="true" />
<parameter-mapping
intentParameter="foodObservation.aboutFood.name"
urlParameter="food" />
</fulfillment>
</action>
<entity-set entitySetId="MealEntitySet">
<entity
sameAs="http://schema.googleapis.com/MealTypeBreakfast"
identifier="1" />
<entity
sameAs="http://schema.googleapis.com/MealTypeLunch"
identifier="2" />
<entity
sameAs="http://schema.googleapis.com/MealTypeDinner"
identifier="3" />
</entity-set>
</actions>
shortcuts.xml - 健身与营养
<?xml version="1.0" encoding="utf-8"?>
<shortcuts>
<capability android:name="actions.intent.RECORD_FOOD_OBSERVATION">
<intent>
<url-template android:value="myfoodapp://record{?food,meal}" />
<parameter
android:name="foodObservation.forMeal"
android:key="meal"
android:required="true" />
<parameter
android:name="foodObservation.aboutFood.name"
android:key="food" />
</intent>
</capability>
<shortcut android:shortcutId="1">
<capability-binding android:key="actions.intent.RECORD_FOOD_OBSERVATION">
<parameter-binding android:key="foodObservation.forMeal" />
</capability-binding>
<extra
android:key="sameAs"
android:value="http://schema.googleapis.com/MealTypeBreakfast" />
</shortcut>
<shortcut android:shortcutId="2">
<capability-binding android:key="actions.intent.RECORD_FOOD_OBSERVATION">
<parameter-binding android:key="foodObservation.forMeal" />
</capability-binding>
<extra
android:key="sameAs"
android:value="http://schema.googleapis.com/MealTypeLunch" />
</shortcut>
<shortcut android:shortcutId="3">
<capability-binding android:key="actions.intent.RECORD_FOOD_OBSERVATION">
<parameter-binding android:key="foodObservation.forMeal" />
</capability-binding>
<extra
android:key="sameAs"
android:value="http://schema.googleapis.com/MealTypeDinner" />
</shortcut>
</shortcuts>
actions.xml - 订餐
<?xml version="1.0" encoding="utf-8"?>
<actions>
<action intentName="actions.intent.ORDER_MENU_ITEM">
<parameter name="menuItem.inMenuSection.inMenu.forRestaurant.servesCuisine">
<entity-set-reference entitySetId="CuisineEntitySet"/>
</parameter>
<fulfillment urlTemplate="myfoodapp://order{?restaurant}">
<parameter-mapping
intentParameter="menuItem.inMenuSection.inMenu.forRestaurant.name"
urlParameter="restaurant"
required="true" />
</fulfillment>
<fulfillment urlTemplate="myfoodapp://browse{?food}">
<parameter-mapping
intentParameter="menuItem.name"
urlParameter="food" />
</fulfillment>
</action>
<entity-set entitySetId="CuisineEntitySet">
<entity
url="myfoodapp://browse/italian/pizza"
name="@string/pizza"
alternateName="@array/pizzaSynonyms" />
<entity
url="myfoodapp://browse/american/hamburger"
name="@string/hamburger"
alternateName="@array/hamburgerSynonyms" />
<entity
url="myfoodapp://browse/mediterranean"
name="@string/mediterranean"
alternateName="@array/mediterraneanSynonyms" />
</entity-set>
</actions>
shortcuts.xml - 订餐
<?xml version="1.0" encoding="utf-8"?>
<shortcuts
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<capability android:name="actions.intent.ORDER_MENU_ITEM">
<intent>
<url-template android:value="myfoodapp://order{?restaurant}" />
<parameter
android:name="menuItem.inMenuSection.inMenu.forRestaurant.name"
android:key="restaurant"
android:required="true" />
</intent>
<intent>
<url-template android:value="myfoodapp://browse{?food}" />
<parameter
android:name="menuItem.name"
android:key="food"
android:required="true" />
</intent>
</capability>
<shortcut android:shortcutId="food_pizza">
<intent android:data="myfoodapp://browse/italian/pizza"/>
<capability-binding android:key="actions.intent.ORDER_MENU_ITEM">
<parameter-binding
android:key="menuItem.name"
android:value="@string/pizza" />
</capability-binding>
</shortcut>
<shortcut android:shortcutId="food_hamburger">
<intent android:data="myfoodapp://browse/american/hamburger"/>
<capability-binding android:key="actions.intent.ORDER_MENU_ITEM">
<parameter-binding
android:key="menuItem.name"
android:value="@string/hamburger" />
</capability-binding>
</shortcut>
<shortcut android:shortcutId="food_mediterranean">
<intent android:data="myfoodapp://browse/mediterranean"/>
<capability-binding android:key="actions.intent.ORDER_MENU_ITEM">
<parameter-binding
android:key="menuItem.name"
android:value="@string/mediterranean" />
</capability-binding>
</shortcut>
</shortcuts>
actions.xml - 交通
<?xml version="1.0" encoding="utf-8"?>
<actions>
<action intentName="actions.intent.CREATE_TAXI_RESERVATION">
<fulfillment urlTemplate="https://taxi-actions.firebaseapp.com/order{?dropoffAddress}">
<parameter-mapping
intentParameter="taxiReservation.dropoffLocation.name"
urlParameter="dropoffAddress"/>
</fulfillment>
</action>
</actions>
shortcuts.xml - 交通
<?xml version="1.0" encoding="utf-8"?>
<shortcuts
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<capability android:name="actions.intent.CREATE_TAXI_RESERVATION">
<intent>
<url-template android:value="https://taxi-actions.firebaseapp.com/order{?dropoffAddress}" />
<parameter
android:name="taxiReservation.dropoffLocation.name"
android:key="dropoffAddress" />
</intent>
</capability>
</shortcuts>
actions.xml - 其他
<?xml version="1.0" encoding="utf-8"?>
<actions>
<action intentName="actions.intent.OPEN_APP_FEATURE">
<parameter name="feature">
<entity-set-reference entitySetId="FeatureEntitySet"/>
</parameter>
<fulfillment urlTemplate="myexampleapp://pathto{?appFeature}">
<parameter-mapping intentParameter="feature" urlParameter="appFeature" />
</fulfillment>
</action>
<entity-set entitySetId="FeatureEntitySet">
<entity identifier="FEATUREONE" name="first feature" />
<entity identifier="FEATURETWO" name="second feature" />
</entity-set>
</actions>
shortcuts.xml - 其他
<?xml version="1.0" encoding="utf-8"?>
<shortcuts
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<capability android:name="actions.intent.OPEN_APP_FEATURE">
<intent>
<url-template android:value="myexampleapp://pathto{?appFeature}" />
<parameter android:name="feature" android:key="appFeature" />
</intent>
</capability>
<shortcut android:shortcutId="FEATUREONE">
<capability-binding android:key="actions.intent.OPEN_APP_FEATURE">
<parameter-binding
android:key="feature"
android:value="@string/featureOne" />
</capability-binding>
</shortcut>
<shortcut android:shortcutId="FEATURETWO">
<capability-binding android:key="actions.intent.OPEN_APP_FEATURE">
<parameter-binding
android:key="feature"
android:value="@string/featureTwo" />
</capability-binding>
</shortcut>
</shortcuts>