En esta guía, se describen los pasos básicos que debes seguir para migrar tus acciones de un archivo actions.xml
a uno shortcuts.xml
. Úsala junto con la utilidad de conversión de actions.xml a shortcuts.xml de Acciones en apps para simplificar la migración al formato shortcuts.xml
.
Diferencias entre actions.xml y shortcuts.xml
Existen varias diferencias importantes entre los archivos actions.xml
y shortcuts.xml
:
El archivo que usas para definir las capacidades de voz de tu app (por lo general,
res/xml/shortcuts.xml
en el proyecto de esta) también se usa con el fin de definir etajos en Android. Si ya implementaste los atajos estáticos de Android para tu app, migra tus acciones deactions.xml
a ese archivo existente.Los conjuntos de entidades ya no existen. En cambio, las entidades se definen con elementos
shortcut
.Los vínculos directos siguen siendo compatibles, pero no son el método principal de entrega. En su lugar, usa intents explícitos de Android.
Requisitos previos
Para admitir el espacio de nombres app
que usan los atributos en shortcuts.xml
, debes incluir la Biblioteca Android Jetpack Core versión 1.6.0 o posterior con tu app. En los ejemplos de esta página, se muestra cuándo es necesario usar el espacio de nombres app
.
Cómo configurar shortcuts.xml
Si ya implementaste atajos de Android en tu app, usa ese archivo para configurar tus capacidades.
Si el archivo shortcuts.xml
no existe, sigue estos pasos:
En el directorio
res/xml
del proyecto de tu app, crea el archivoshortcuts.xml
.Quita la etiqueta
<meta-data>
que hace referencia aactions.xml
en el archivoAndroidManifest.xml
.Agrega una referencia a
shortcuts.xml
enAndroidManifest.xml
con una etiqueta<meta-data>
en la actividad que tiene filtros de intents paraMAIN
yLAUNCHER
. Puedes ver los detalles de este proceso en la descripción general de la creación de atajos.En
shortcuts.xml
, define un elementoshortcuts
, como se muestra en el siguiente ejemplo:<?xml version="1.0" encoding="utf-8"?> <shortcuts xmlns:android="http://schemas.android.com/apk/res/android"> </shortcuts>
Cómo configurar las funciones
Cuando migres tus acciones de un archivo actions.xml
a uno shortcuts.xml
, deberás configurar los elementos capability
. Una capability
identifica el intent de Acción en la app que tu app quiere reconocer. Para migrar, cada acción en actions.xml
debe convertirse en una capacidad en shortcuts.xml
.
Si tienes conjuntos de entidades asociados con tus acciones, completa este procedimiento para agregar las capacidades y, luego, configura atajos a fin de representar los conjuntos de entidades.
Si quieres obtener más información para configurar capacidades, consulta Cómo crear shortcuts.xml
.
Para migrar una acción a una capacidad, sigue estos pasos:
En
shortcuts.xml
, en el elementoshortcuts
, define un elementocapability
:<?xml version="1.0" encoding="utf-8"?> <shortcuts xmlns:android="http://schemas.android.com/apk/res/android"> <capability> </capability> </shortcuts>
Configura el atributo
android:name
decapability
en el BII que usa tu acción. Enactions.xml
, el valor se encuentra en el atributointentName
de tu elementoaction
.Si tu acción usa un intent personalizado, también debes incluir el atributo
app:queryPatterns
. Enactions.xml
, el valor se encuentra en el atributoqueryPatterns
de tu elementoaction
.Por ejemplo, supongamos que tu acción invoca el intent
actions.intent.RECORD_FOOD_OBSERVATION
, como se muestra en el siguienteactions.xml
de ejemplo:Intent integrado
<?xml version="1.0" encoding="utf-8"?> <actions> <action intentName="actions.intent.RECORD_FOOD_OBSERVATION"> ... </action> </actions>
En este ejemplo, se establece el atributo
android:name
de tucapability
enactions.intent.RECORD_FOOD_OBSERVATION
, enshortcuts.xml
:<shortcuts xmlns:android="http://schemas.android.com/apk/res/android"> <capability android:name="actions.intent.RECORD_FOOD_OBSERVATION"> </capability> </shortcuts>
Intent personalizado
<?xml version="1.0" encoding="utf-8"?> <actions> <action intentName="custom.actions.intent.RECORD_FOOD_OBSERVATION" queryPatterns="@array/foodObservationQueries"> ... </action> </actions>
En este ejemplo, se establece el atributo
android:name
de tucapability
enactions.intent.RECORD_FOOD_OBSERVATION
, y elapp:queryPatterns
en@array/foodObservationQueries
, enshortcuts.xml
:<?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>
En
capability
, para cadafulfillment
definido en tu acción, crea unintent
o unaslice
. Solo debes agregar un elementoslice
si el atributofulfillmentMode
de unafulfillment
se establece enactions.fulfillment.SLICE
. De lo contrario, crea un elementointent
. Esto se muestra en el siguienteshortcuts.xml
de ejemplo:Vínculo directo (predeterminado)
<?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>
Por cada elemento que creaste en el paso anterior, define un elemento
url-template
y establece el atributoandroid:value
en el mismo valor utilizado para el atributourl-template
del elementofulfillment
.Por ejemplo, supongamos que tu acción utiliza la siguiente plantilla de URL en
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>
En este ejemplo, se establece el atributo
android:value
del elementourl-template
enmyfoodapp://record{?food,meal}
, enshortcuts.xml
:Vínculo directo (predeterminado)
<?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>
En cada elemento
parameter-mapping
de la plantilla de URL de tu acción, define un elementoparameter
y establece valores para los atributosandroid:name
yandroid:key
.Configura
android:name
con el mismo valor que el atributointentParameter
del elementoparameter-mapping
.Configura
android:key
con el mismo valor que el atributourlParameter
del elementoparameter-mapping
.
Si se requieren uno o más de tus parámetros, establece el atributo
android:required
deparameter
entrue
.Por ejemplo, supongamos que tu acción incluye las siguientes asignaciones de parámetros para tu plantilla de URL en
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>
En este ejemplo, se crearán los siguientes elementos
parameter
enshortcuts.xml
:Vínculo directo (predeterminado)
<?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>
Cómo configurar atajos
En shortcuts.xml
, las entidades se representan como accesos directos. Si aún no migraste tus acciones a las capacidades, primero debes configurar una capacidad para cada acción.
Cuando migres de actions.xml
a shortcuts.xml
, si la acción tiene un conjunto de entidades, debes crear una shortcut
para cada entidad.
En los siguientes ejemplos, se muestran los pasos de migración.
Supongamos que tu acción original en actions.xml
se ve de la siguiente manera:
<?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>
En este ejemplo, supongamos que ya definiste la capacidad en shortcuts.xml
, incluidos el intent y los parámetros:
<?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>
Para configurar atajos para tus entidades, sigue estos pasos:
En el elemento
shortcuts
, para cada parámetro y entidad, define un elementoshortcut
y establece un valor del atributoandroid:shortcutId
. El valor deandroid:shortcutId
debe ser el mismo que el del atributoidentifier
de la entidad correspondiente.En este ejemplo, se crea un atajo para cada entidad en conjunto de entidades
MealEntitySet
, como se muestra en el siguienteshortcuts.xml
de ejemplo:<?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>
Para cada acceso directo, define un elemento
capability-binding
. Establece el atributoandroid:key
en el intent integrado o el personalizado de tu capacidad:... <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> ...
En cada
capability-binding
, define unaparameter-binding
. Establece el atributoandroid:key
en el nombre del parámetro correspondiente en el 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> ...
Agrega el atributo
android:value
a tuparameter-binding
y, luego, define un elementoextra
.Si usamos el ejemplo, para admitir las entidades, debes actualizar tu
capability-bindings
parameal_breakfast
,meal_lunch
ymeal_dinner
, y agregar los elementosextra
correspondientes:... <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> ...
Las capacidades que migraste ya están lista para probarse.
Ejemplos: actions.xml a shortcuts.xml
En los siguientes ejemplos, se muestran implementaciones de Acciones en apps con archivos actions.xml
y shortcuts.xml
.
Actions.xml: finanzas
<?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: finanzas
<?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: actividad física y nutrición
<?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: actividad física y nutrición
<?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: pedidos de comida
<?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: pedidos de comida
<?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: transporte
<?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: transporte
<?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: otros
<?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: otros
<?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>