Para muchos intents, la mejor respuesta consiste en brindar a los usuarios una respuesta simple, una confirmación breve o una experiencia interactiva rápida. Puedes mostrar un widget de apps para Android en Asistente de Google para entregar estos tipos de intents.
En esta guía, se explica cómo completar las consultas de los usuarios de Asistente mediante widgets y cómo mejorar la experiencia del widget para Asistente con la biblioteca de Widgets Extension de Acciones en apps.
Beneficios
Los widgets son vistas en miniatura de una aplicación que se pueden incorporar en plataformas de Android, como el selector o la pantalla de bloqueo. Con las Acciones en apps, puedes aumentar el impacto de tus widgets de modo que resulten aptos para mostrarse en Asistente:
- Descubrimiento: Muestra widgets de manera proactiva en respuesta a consultas de los usuarios en lenguaje natural.
- Participación: Muestra widgets en contextos de manos libres, como cuando Asistente brinda los resultados personales en la pantalla de bloqueo y en Android Auto.
- Retención: Permite que los usuarios fijen en su selector los widgets que se muestran en Asistente. La función de fijar requiere la biblioteca de Widgets Extension.
Cómo muestra widgets Asistente
Existen dos maneras en las que los usuarios pueden invocar widgets en Asistente:
- Pueden solicitar explícitamente un widget por su nombre.
- Pueden realizar una consulta al Asistente que activa un intent integrado (BII) o un intent personalizado configurados para la entrega de widgets.
Invocación explícita
Para invocar widgets de manera explícita con cualquier app instalada, los usuarios pueden pedirle al Asistente cosas como las siguientes:
- "Hey Google, muestra el widget de AppDeEjemplo".
- "Widgets de AppDeEjemplo".
Asistente muestra estos widgets con la introducción genérica: "AppDeEjemplo dice, aquí hay un widget". Si bien Asistente muestra widgets de esta manera de forma nativa, sin necesidad de que el desarrollador de apps realice el trabajo, con este método de invocación, el usuario debe tener conocimiento explícito del widget que desea solicitar. Para simplificar el descubrimiento de widgets, usa el método de entrega de intents que se describe en la siguiente sección.
Entrega de intents
Haz que sea más fácil encontrar los widgets utilizándolos para entregar las consultas de lenguaje natural que los usuarios realizan en Asistente. Por ejemplo, puedes mostrar un widget cada vez que un usuario active el BII GET_EXERCISE_OBSERVATION
en tu app de fitness. Para ello, pregunta "Hey Google, ¿cuántos kilómetros corrí esta semana en AppDeEjemplo?". Además de simplificar el descubrimiento, integrar estos widgets en Acciones en apps ofrece las siguientes ventajas:
- Acceso a parámetros: Asistente proporciona a tu widget los parámetros de intent extraídos de la consulta del usuario, lo que habilita las respuestas personalizadas.
- Presentaciones personalizadas de TTS: Puedes brindar una cadena de texto a voz (TTS) de modo que Asistente la anuncie cuando muestre tu widget.
- Fijación de widgets: Asistente muestra un botón para agregar el widget cerca de él, lo que permite a los usuarios fijar con facilidad tus widgets en su selector.
Implementa la entrega de widgets
Si deseas implementar la entrega de widgets para tus intents, sigue estos pasos:
- Implementa un widget de Android con los pasos que se describen en el artículo para crear un widget simple.
- En el archivo de recursos
shortcuts.xml
de tu app, agrega un elemento<app-widget>
a tu función que contenga detalles de entrega y etiquetas<parameter>
del BII. Actualiza tu widget para controlar los parámetros. - Agrega la biblioteca de Widgets Extension requerida, que permite que Asistente pase nombres y parámetros de BII a tus widgets. También habilita presentaciones de TTS personalizadas y la funcionalidad de fijación de widgets.
En la siguiente sección, se describe el esquema de <app-widget>
para el archivo shortcuts.xml
.
Esquema de widgets
Los elementos <app-widget>
se definen como entregas dentro de elementos <capability>
en el archivo shortcuts.xml
. Requieren los siguientes atributos, a menos que se indique que son opcionales:
Etiqueta Shortcuts.xml | Dónde se incluye | Atributos |
---|---|---|
<app-widget> |
<capability> |
|
<parameter> |
<app-widget> |
|
<extra> |
<app-widget> |
|
Descripción del esquema de widgets
<app-widget>
Es el elemento de entrega de widgets de nivel superior.
Atributos:
android:identifier
: Es el identificador de esta entrega. Este valor debe ser único entre los elementos de entrega<app-widget>
y<intent>
definidos en una<capability>
.android:targetClass
: Es el nombre completo de la clase de tuAppWidgetProvider
que controlará el intent.
<parameter>
Esta etiqueta asigna un parámetro BII a un valor de intent de <parameter>
. Puedes definir cero o más parámetros para cada elemento <app-widget>
. Durante la entrega, Asistente pasa los parámetros con la actualización de los elementos adicionales de la instancia del widget como pares clave-valor con el siguiente formato:
- Clave: El
android:key
definido para el parámetro - Valor: El valor que extrae el BII de la entrada de voz del usuario
Para acceder a estos elementos adicionales, llama a getAppWidgetOptions()
en el objeto AppWidgetManager
asociado que muestra un Bundle
que contiene el nombre del BII de activación y sus parámetros. Consulta la información para extraer valores de parámetros a fin de obtener más detalles.
Si deseas obtener más información sobre la coincidencia de parámetros de BII, consulta Datos de parámetros y coincidencias.
<extra>
Etiqueta opcional que declara que se usa una introducción personalizada a TTS para este widget. Esta etiqueta requiere los siguientes valores del atributo:
android:name
:"hasTts"
android:value
:"true"
Código de muestra
En el siguiente ejemplo de un archivo shortcuts.xml
, se muestra una configuración de entrega de widgets para una función de BII GET_EXERCISE_OBSERVATION
:
<capability android:name="actions.intent.GET_EXERCISE_OBSERVATION">
<app-widget
android:identifier="GET_EXERCISE_OBSERVATION_1"
android:targetClass="com.exampleapp.providers.exampleAppWidgetProvider"
android:targetPackage="com.exampleapp">
<parameter
android:name="exerciseObservation.aboutExercise.name"
android:key="exercisename">
</parameter>
<extra android:name="hasTts" android:value="true"/>
</app-widget>
</capability>
Puedes especificar varios elementos <app-widget>
o usar una combinación de elementos <app-widget>
y <intent>
por función. Este enfoque te permite brindar una experiencia personalizada basada en diferentes combinaciones de parámetros proporcionados por los usuarios. Por ejemplo, si el usuario no especifica una ubicación de destino en la consulta, puedes dirigirlo a la actividad de tu app que muestra opciones para configurar las ubicaciones de recogida y llegada. Consulta la sección Intents de resguardo a fin de obtener más información para definir intents de resguardo.
Cómo extraer valores de parámetros
En la siguiente clase de AppWidgetProvider
de muestra, se usa la función privada updateAppWidget()
para extraer el nombre y los parámetros del BII a partir del Bundle
de opciones del widget:
Kotlin
package com.example.exampleapp //... Other module imports import com.google.assistant.appactions.widgets.AppActionsWidgetExtension /** * Implementation of App Widget functionality. */ class MyAppWidget : AppWidgetProvider() { override fun onUpdate( context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray ) { // There might be multiple widgets active, so update all of them for (appWidgetId in appWidgetIds) { updateAppWidget(context, appWidgetManager, appWidgetId) } } private fun updateAppWidget( context: Context, appWidgetManager: AppWidgetManager, appWidgetId: Int ) { val widgetText: CharSequence = context.getString(R.string.appwidget_text) // Construct the RemoteViews object val views = RemoteViews(context.packageName, R.layout.my_app_widget) views.setTextViewText(R.id.appwidget_text, widgetText) // Extract the name and parameters of the BII from the widget options val optionsBundle = appWidgetManager.getAppWidgetOptions(appWidgetId) val bii = optionsBundle.getString(AppActionsWidgetExtension.EXTRA_APP_ACTIONS_BII) // "actions.intent.CREATE_TAXI_RESERVATION" val params = optionsBundle.getBundle(AppActionsWidgetExtension.EXTRA_APP_ACTIONS_PARAMS) if (params != null && params.containsKey("dropoff")) { val dropoffLocation = params.getString("dropoff") // Build your RemoteViews with the extracted BII parameter // ... } appWidgetManager.updateAppWidget(appWidgetId, views) } }
Java
package com.example.exampleapp; //... Other module imports import com.google.assistant.appactions.widgets.AppActionsWidgetExtension; /** * Implementation of App Widget functionality. */ public class MyAppWidget extends AppWidgetProvider { @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { // There might be multiple widgets active, so update all of them for (int appWidgetId : appWidgetIds) { updateAppWidget(context, appWidgetManager, appWidgetId); } } private static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) { CharSequence widgetText = context.getString(R.string.appwidget_text); // Construct the RemoteViews object RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.my_app_widget); views.setTextViewText(R.id.appwidget_text, widgetText); // Extract the name and parameters of the BII from the widget options Bundle optionsBundle = appWidgetManager.getAppWidgetOptions(appWidgetId); String bii = optionsBundle.getString(AppActionsWidgetExtension.EXTRA_APP_ACTIONS_BII); // "actions.intent.CREATE_TAXI_RESERVATION" Bundle params = optionsBundle.getBundle(AppActionsWidgetExtension.EXTRA_APP_ACTIONS_PARAMS); if (params != null && params.containsKey(("dropoff"))){ String dropoffLocation = params.getString("dropoff"); // Build your RemoteViews with the extracted BII parameter // ... } appWidgetManager.updateAppWidget(appWidgetId, views); } }
Biblioteca de Widgets Extension
La biblioteca de Widgets Extension de Acciones en apps mejora tus widgets para las experiencias de Asistente de voz. Esta biblioteca permite que tus widgets reciban información de entrega importante del BII de activación, incluido el nombre del BII y cualquier parámetro del intent extraído de la consulta del usuario.
Esta biblioteca de Maven te permite brindar una presentación personalizada de texto a voz (TTS) para cada widget, lo que le permite al Asistente anunciar un resumen del contenido que se renderiza visualmente para los usuarios. También habilita la fijación de selector, lo que facilita a los usuarios guardar los widgets que se muestran en Asistente en sus pantallas de selector.
Para comenzar, agrega la biblioteca en la sección de dependencias del archivo build.gradle
del módulo de tu app:
dependencies {
//...
implementation "com.google.assistant.appactions:widgets:0.0.1"
}
Presentaciones personalizadas
Después de importar la biblioteca de extensiones de widgets, puedes proporcionar presentaciones personalizadas de TTS para tus widgets. Para agregar tu definición al AppWidgetProvider
del widget, abre la clase en tu IDE y, luego, importa la biblioteca de extensiones de widgets:
Kotlin
import com.google.assistant.appactions.widgets.AppActionsWidgetExtension
Java
import com.google.assistant.appactions.widgets.AppActionsWidgetExtension;
Kotlin
package com.example.exampleapp //... Other module imports import com.google.assistant.appactions.widgets.AppActionsWidgetExtension /** * Implementation of App Widget functionality. */ object MyAppWidget : AppWidgetProvider() { fun updateAppWidget( context: Context?, appWidgetManager: AppWidgetManager, appWidgetId: Int ) { val appActionsWidgetExtension = AppActionsWidgetExtension.newBuilder(appWidgetManager) .setResponseSpeech("Hello world") // TTS to be played back to the user .setResponseText("Hello world!") // Response text to be displayed in Assistant .build() // Update widget with TTS appActionsWidgetExtension.updateWidget(appWidgetId) // Update widget UI appWidgetManager.updateAppWidget(appWidgetId, views) } }
Java
package com.example.exampleapp; //... Other module imports import com.google.assistant.appactions.widgets.AppActionsWidgetExtension; /** * Implementation of App Widget functionality. */ public class MyAppWidget extends AppWidgetProvider { static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) { AppActionsWidgetExtension appActionsWidgetExtension = AppActionsWidgetExtension.newBuilder(appWidgetManager) .setResponseSpeech("Hello world") // TTS to be played back to the user .setResponseText("Hello world!") // Response text to be displayed in Assistant .build(); // Update widget with TTS appActionsWidgetExtension.updateWidget(appWidgetId); // Update widget UI appWidgetManager.updateAppWidget(appWidgetId, views); } }
Recomendaciones de estilo de TTS
Usa las siguientes recomendaciones de estilo para optimizar las introducciones de widgets personalizados para TTS y mensajes visibles.
Recomendación | Se recomienda | No se recomienda |
---|---|---|
SencillezUsa expresiones sencillas en mensajes de TTS. Las expresiones más enrevesadas suenan forzadas y robóticas en lugar de naturales y familiares. Decir frases como "no es posible" y "no se ha podido" puede sonar rígido y severo. |
ResponseSpeech (TTS)Lo siento, no puedo encontrar una reserva. ResponseText Lo siento, no puedo encontrar una reserva. |
ResponseSpeech (TTS)Lo siento, no se ha podido encontrar una reserva. ResponseText Lo siento, no se ha podido encontrar una reserva. |
ComasUtiliza la coma de enumeración en listas de tres o más elementos para agregar claridad. Sin la coma de enumeración, los elementos individuales de la lista pueden escucharse de manera incorrecta o leerse como grupos. Por ejemplo, en "narcisos, margaritas y girasoles", "margaritas y girasoles" suenan como si se unieran. En "narcisos, margaritas y girasoles", los tres están claramente separados. |
ResponseSpeech (TTS)Nuestras flores más populares son las rosas amarillas, los narcisos, las margaritas, y los girasoles. ResponseText Nuestras flores más populares son las rosas amarillas, los narcisos y las margaritas, y los girasoles. |
ResponseSpeech (TTS)Nuestras flores más populares son las rosas amarillas, los narcisos y las margaritas y los girasoles. ResponseText Nuestras flores más populares son las rosas amarillas, los narcisos y las margaritas y los girasoles. |
NumeralesUsa números en lugar de texto para que el contenido visual sea más claro. |
ResponseSpeech (TTS)Tu presión arterial es 100 80. ResponseText Tu presión arterial es 100/80. |
ResponseSpeech (TTS)Tu presión arterial es 100/80. ResponseText Tu presión arterial es cien ochenta. |
SímbolosUsa símbolos especializados en lugar de texto para que el contenido visual sea más claro. |
ResponseSpeech (TTS)Tu última compra fue de USD 24.65. ResponseText Tu última compra fue de USD 24.65. |
ResponseSpeech (TTS)Tu última compra fue de veinticuatro dólares y sesenta y cinco centavos. ResponseText Tu última compra fue de veinticuatro dólares y sesenta y cinco centavos. |
Evita el exceso de educaciónEl exceso de educación hace que las respuestas suenen distantes y formales. Evítalo y mantén una conversación informal y amigable. |
ResponseSpeech (TTS)Se entregó tu pedido. ResponseText Se entregó tu pedido. |
ResponseSpeech (TTS)Por supuesto, puedo decirte eso. Se entregó tu pedido. ResponseText Por supuesto, puedo decirte eso. Se entregó tu pedido. |
Evita los signos de exclamaciónPueden percibirse como gritos. |
ResponseSpeech (TTS)Hoy corriste 2.4 kilómetros. ResponseText Hoy corriste 2.4 kilómetros. |
ResponseSpeech (TTS)¡Hoy corriste 2.4 kilómetros! ResponseText ¡Hoy corriste 2.4 kilómetros! |
HoraUsa números: "5:15" en lugar de "cinco quince" o "quince después de cinco". Para el reloj de 12 horas, usa a.m. o p.m. |
ResponseSpeech (TTS)La entrega debería llegar a las 8:15 a.m. ResponseText La entrega debería llegar a las 8:15 a.m. |
ResponseSpeech (TTS)La entrega debería llegar hoy a las 8 y 15 de la mañana. ResponseText La entrega debería llegar hoy a las 8 y 15 de la mañana. |
No hagas monólogosBrinda la información, pero asegúrate de que las respuestas sean concisas. No desarrolles detalles que no ofrezcan un beneficio claro para el usuario. |
ResponseSpeech (TTS)El mes pasado consumiste 159 horas de energía. ResponseText El mes pasado consumiste 159 horas de energía. |
ResponseSpeech (TTS)Ahorrar energía es muy importante para el planeta y el medioambiente. El mes pasado consumiste 159 horas de energía. Este mes consumiste 58 horas de energía. ResponseText Ahorrar energía es muy importante para el planeta y el medioambiente. El mes pasado consumiste 159 horas de energía. Este mes consumiste 58 horas de energía. |
Usa palabras simples y cortasEl lenguaje sencillo y claro tiene el atractivo más amplio, ya que es accesible para personas de todos los orígenes. |
ResponseSpeech (TTS)Tu última medición de azúcar en sangre fue de 126. ResponseText Tu última medición de azúcar en sangre fue de 126 mg/dl. |
ResponseSpeech (TTS)El penúltimo nivel de glucemia fue de 126. ResponseText El penúltimo nivel de glucemia fue de 126. |
Fijación de selectores
La biblioteca de Widgets Extension permite que se muestre el botón para agregar el widget con tu widget en Asistente. Para habilitar la fijación, agrega la siguiente definición del receptor a AndroidManifest.xml
:
<application>
<receiver android:name="com.google.assistant.appactions.widgets.pinappwidget.PinAppWidgetBroadcastReceiver"
android:exported="false">
<intent-filter>
<action android:name="com.google.assistant.appactions.widgets.COMPLETE_PIN_APP_WIDGET" />
</intent-filter>
</receiver>
<service
android:name=
"com.google.assistant.appactions.widgets.pinappwidget.PinAppWidgetService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action
android:name="com.google.assistant.appactions.widgets.PIN_APP_WIDGET" />
</intent-filter>
</service>
</application>
Disponibilidad de inventario
Los BIIs que admiten inventario intercalado o inventario web pueden extender estos inventarios a tus entregas de widgets.
Inventario intercalado
En el siguiente código de un archivo shortcuts.xml
de muestra, se muestra una función de BII START_EXERCISE
configurada para el inventario intercalado y la entrega de widgets:
<capability
android:name="actions.intent.START_EXERCISE">
<app-widget
android:identifier="START_EXERCISE_1"
android:targetClass="com.example.exampleapp.StartExerciseAppWidgetProvider">
<parameter
android:name="exercise.name"
android:key="exerciseName"
app:shortcutMatchRequired="true">
</parameter>
</app-widget>
</capability>
<shortcut android:shortcutId="RunningShortcut">
<intent
android:action="android.intent.action.VIEW"
android:targetClass="com.example.exampleapp.StartExcerciseActivity" />
<capability-binding
android:capability="actions.intent.START_EXERCISE"
android:parameter="exercise.name"
android:value="running;runs" />
</shortcut>
En el ejemplo anterior, cuando un usuario pide al Asistente: "Comienza a ejecutar con AppDeEjemplo". El paquete de opciones para la entrega de <app-widget>
contendrá el siguiente par clave-valor:
- Clave =
“exerciseName”
- Valor =
“RunningShortcut”
Inventario web
En el siguiente código de un archivo shortcuts.xml
de muestra, se muestra una función habilitada para el inventario web y la entrega de widgets:
<shortcuts>
<capability
android:name="actions.intent.START_EXERCISE">
<app-widget
android:identifier="START_EXERCISE_1"
android:targetClass="com.example.exampleapp.CreateTaxiAppWidgetProvider">
<parameter
android:name="exercise.name"
android:key="exerciseName"
android:mimeType="text/*">
<data android:pathPattern="https://exampleapp.com/exercise/.*" />
</parameter>
</app-widget>
</capability>
</shortcuts>
Prueba las Acciones en apps
Usa la herramienta de pruebas de Acciones en apps, una función del complemento de Asistente de Google para Android Studio, para probar widgets en un dispositivo físico o virtual. Para usar esa herramienta, sigue estos pasos:
- Conecta el dispositivo de prueba a la app en ejecución.
- En Android Studio, ve a Tools > App Actions > App Actions Test Tool.
- Haz clic en Create Preview.
- En Android Studio, ejecuta la app en tu dispositivo de prueba.
- Usa la app de Asistente en tu dispositivo de prueba para probar la Acción en la app. Por ejemplo, puedes decir "Hey Google, ¿cuántos kilómetros corrí esta semana en AppDeEjemplo?".
- Observa el comportamiento de tu app o usa el depurador de Android Studio a fin de verificar el resultado de la acción que deseas.
Lineamientos de calidad
En esta sección, se destacan los requisitos fundamentales y las prácticas recomendadas para la integración de Acciones en apps con widgets.
Contenido en widgets
- No muestres anuncios en tus widgets. (Obligatorio)
- Enfoca el contenido del widget por completo en entregar el intent. No intentes entregar varios intents con un widget ni agregues contenido irrelevante.
Cómo controlar la autenticación
- En los casos en que se necesite la autenticación para completar un flujo de usuarios, muestra un widget que explique que el usuario debe continuar en la app. La autenticación intercalada de usuarios en Asistente de Google no es compatible con Acciones en apps. (Obligatorio)
- Si los usuarios permiten que la app muestre datos con widgets, puedes mostrar un widget de error en el tiempo de ejecución a los usuarios no autorizados.
Intents de resguardo
En tu archivo
shortcuts.xml
, siempre proporciona un<intent>
de resguardo además de la entrega de widgets para una función determinada. (Obligatorio) Un intent de resguardo es un elemento<intent>
sin valores de<parameter>
obligatorios.Esto permite que Asistente realice una acción cuando la consulta del usuario no contenga parámetros requeridos por los otros elementos de entrega definidos en la función. La excepción se da cuando no hay parámetros obligatorios para esa función, en cuyo caso solo se necesita la entrega del widget.
Usa el intent de resguardo para abrir la app en la pantalla relevante, no en la pantalla principal.
En el siguiente código de un archivo shortcuts.xml
de muestra, se muestra una <capability>
con un resguardo <intent>
que admite una entrega principal de <app-widget>
:
<shortcuts>
<capability
android:name="actions.intent.CREATE_TAXI_RESERVATION">
<!-- Widget with required parameter, specified using the "android:required" attribute. -->
<app-widget
android:identifier="CREATE_TAXI_RESERVATION_1"
android:targetClass="com.example.myapplication.CreateTaxiAppWidgetProvider">
<parameter
android:name="taxiReservation.dropoffLocation.name"
android:key="dropoff"
android:required="true">
</parameter>
</app-widget>
<!-- Fallback intent with no parameters required to successfully execute. -->
<intent
android:identifier="CREATE_TAXI_RESERVATION_3"
android:action="myapplication.intent.CREATE_TAXI_RESERVATION_1"
android:targetClass="com.example.myapplication.TaxiReservationActivity">
</intent>
</capability>
</shortcuts>
Divulgación de datos de Google Play
En esta sección, se muestra la recopilación de datos del usuario final de la versión más reciente de la biblioteca de Widgets Extension.
Este SDK envía respuestas de texto a voz (TTS) proporcionadas por el desarrollador, que Asistente de Google anuncia al usuario con la tecnología de voz de Asistente. Google no almacena esta información.
Las Acciones en apps también pueden recopilar metadatos de la app cliente para los siguientes fines:
- Supervisar las tasas de adopción de diferentes versiones del SDK
- Cuantificar el uso de las funciones del SDK en las apps