1. Descripción general
En el primer codelab de Acciones en apps, aprendiste a implementar el Asistente de Google en una app de fitness de ejemplo configurando intents integrados (BII) de la categoría Salud y fitness.
Las Acciones en apps permiten que los usuarios utilicen el Asistente para iniciar funciones específicas de una app directamente con frases como "Hey Google, inicia una actividad de correr en App de Ejemplo". Además de iniciar apps, el Asistente puede mostrarle al usuario un widget de Android interactivo para llevar a cabo solicitudes relacionadas con BII aptos.
Qué harás
En este codelab, aprenderás a mostrar widgets de Android para llevar a cabo las solicitudes de los usuarios del Asistente. También aprenderás a hacer lo siguiente:
- Utilizar parámetros de BII para personalizar widgets
- Mostrar introducciones a la función de texto a voz (TTS) en el Asistente para tus widgets
- Consultar la referencia de intents integrados para determinar qué BII admiten la entrega de widgets
Requisitos previos
Antes de continuar, asegúrate de que tu entorno de desarrollo esté preparado para el desarrollo de Acciones en apps. Debe incluir lo siguiente:
- Una terminal para ejecutar comandos de shell con Git instalado
- La versión estable más reciente de Android Studio
- Un dispositivo Android físico o virtual con acceso a Internet
- Una Cuenta de Google para acceder a Android Studio, la app de Google y la app del Asistente de Google
Si utilizas un dispositivo físico, conéctalo a tu máquina de desarrollo local.
2. Comprende el funcionamiento
El Asistente de Google emplea la comprensión del lenguaje natural (CLN) para interpretar la solicitud del usuario y relacionarla con un intent integrado (BII) del Asistente. De esta forma, el Asistente puede asignar el intent a la capability (que implementa el BII) que tú configuras para ese intent en tu app. Por último, para llevar a cabo la solicitud del usuario, el Asistente muestra el widget de Android que tu app genera con los detalles incluidos en la capability.
En este codelab, definirás una capability que establece la implementación del BII GET_EXERCISE_OBSERVATION
. Con esta capability, le ordenas al Asistente que genere un intent de Android para la clase de widget FitActions
de forma tal que complete las solicitudes de ese BII. Específicamente, tienes que actualizar esa clase con el fin de generar un widget personalizado, así como una introducción a la función de TTS, para que el Asistente se los pueda mostrar al usuario.
En el siguiente diagrama se muestra ese procedimiento:
Widget FitActions
La app de ejemplo FitActions contiene un widget de información de entrenamiento que los usuarios pueden agregar a su pantalla principal. Este widget es un excelente medio para llevar a cabo las consultas de los usuarios que activan el BII GET_EXERCISE_OBSERVATION
.
Cómo funciona el widget
Cuando un usuario agrega un widget a la pantalla principal, el widget hace ping al receptor de emisión del dispositivo. Este servicio recupera información sobre el widget consultando la definición del receptor del widget incluida en el recurso AndroidManifest.xml
de la app. En particular, utiliza esa información para generar un objeto RemoteViews
que representa el widget.
La app de ejemplo define el receptor widgets.StatsWidgetProvider
, que corresponde a la clase StatsWidgetProvider
:
<!-- app/src/main/AndroidManifest.xml -->
<receiver
android:name=".widgets.StatsWidgetProvider"
android:exported="false">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/stats_widget" />
</receiver>
La clase StatsWidgetProvider
, StatsWidgetProvider.kt
, administra los flujos de creación del objeto StatsWidget
. Además, controla estas responsabilidades:
- Crear instancias de widgets y propagarlas con datos de ejercicios de la base de datos de la app
- Aplicar formato a los datos de entrenamiento para facilitar la lectura, con
formatDataAndSetWidget()
- Proporcionar valores predeterminados por medio de
setNoActivityDataWidget()
si los datos de entrenamiento no están disponibles
Configura la implementación del Asistente
En este codelab, tienes que actualizar la app de ejemplo para controlar la funcionalidad de Acciones en apps. Entre los cambios necesarios para tal fin se incluyen los siguientes:
- Configurar la capability de BII
GET_EXERCISE_OBSERVATION
para mostrar una instancia del objetoStatsWidget
- Actualizar la clase
StatsWidget
para usar funciones de Acciones en apps; por ejemplo:- Utilizar parámetros de BII para permitir que los usuarios vean estadísticas de entrenamiento específicas mediante preguntas como "Hey Google, muéstrame las estadísticas de mis actividades de correr en App de Ejemplo"
- Mostrar cadenas de introducción a la función de TTS
- Administrar casos especiales, como podría ser una consulta del usuario que no incluye un parámetro de tipo de entrenamiento
3. Prepara tu entorno de desarrollo
Descarga los archivos fundamentales
Ejecuta este comando para clonar el repositorio de GitHub de la app de ejemplo:
git clone --branch start-widget-codelab https://github.com/actions-on-google/appactions-fitness-kotlin.git
Una vez que hayas clonado el repositorio, sigue estos pasos para abrirlo en Android Studio:
- En el diálogo Welcome to Android Studio, haz clic en Import project.
- Busca y selecciona la carpeta donde clonaste el repositorio.
Para ver una versión de la app que representa el codelab completado, clona el repositorio de la app de ejemplo con el parámetro --branch master
.
Actualiza el ID de aplicación para Android
La actualización del ID de aplicación identifica de forma exclusiva la app en tu dispositivo de prueba y evita que se muestre el error "Duplicate package name" si la app se sube a Play Console. Para actualizar el ID de aplicación, abre app/build.gradle
:
android {
...
defaultConfig {
applicationId "com.MYUNIQUENAME.android.fitactions"
...
}
}
Reemplaza "MYUNIQUENAME" en el campo applicationId
por algo que sea único para ti.
Instala el complemento de prueba
El complemento Google Assistant te permite probar tus Acciones en apps en un dispositivo de prueba. Su funcionamiento consiste en enviarle información al Asistente mediante la app de Google en tu dispositivo Android. Si aún no tienes este complemento, sigue los pasos que se indican a continuación para instalarlo:
- Ve a File > Settings (Android Studio > Preferences en MacOS).
- En la sección Plugins, accede a Marketplace y busca "Google Assistant". También puedes descargar e instalar la herramienta de prueba manualmente.
- Instala la herramienta y reinicia Android Studio.
Prueba la app en tu dispositivo
Antes de realizar más cambios en la app, es conveniente hacer una prueba para tener una idea de lo que puede hacer la app de ejemplo.
Ejecuta la app en tu dispositivo de prueba:
- En Android Studio, selecciona tu dispositivo físico o virtual. Luego selecciona Run > Run app, o haz clic en Run
en la barra de herramientas.
- Mantén presionado el botón de inicio para configurar el Asistente y verificar que funcione. Si aún no lo hiciste, tendrás que acceder al Asistente en tu dispositivo.
Para obtener más información sobre los dispositivos virtuales de Android, consulta Cómo crear y administrar dispositivos virtuales.
Explora la app brevemente para ver lo que puede hacer. La app prepropaga 10 actividades de ejercicio y muestra esta información en la primera vista.
Prueba el widget
- Presiona el botón de inicio para ir a la pantalla principal de tu dispositivo de prueba.
- Mantén presionado un espacio vacío en la pantalla principal y selecciona Widgets.
- Desplázate hacia abajo por la lista de widgets hasta FitActions.
- Mantén presionado el ícono de FitActions y coloca el widget en la pantalla principal.
4. Configura la Acción en la app
En este paso, tienes que agregar la capability de BII GET_EXERCISE_OBSERVATION
. Para ello, incluye un nuevo elemento capability
en el archivo shortcuts.xml
. Esta capability establece cómo se ejecuta su activación, cómo se utilizan los parámetros de BII y qué intents de Android se deben invocar para llevar a cabo la solicitud.
- Agrega un nuevo elemento
capability
al recursoshortcuts.xml
del proyecto de ejemplo con la siguiente configuración: Reemplaza el valor de<!-- fitnessactions/app/src/main/res/xml/shortcuts.xml --> <capability android:name="actions.intent.GET_EXERCISE_OBSERVATION"> <app-widget android:identifier="GET_EXERCISE_OBSERVATION" android:targetClass="com.devrel.android.fitactions.widgets.StatsWidgetProvider" android:targetPackage="PUT_YOUR_APPLICATION_ID_HERE"> <parameter android:name="exerciseObservation.aboutExercise.name" android:key="aboutExerciseName" android:required="true"> </parameter> <extra android:name="hasTts" android:value="true"/> </app-widget> <!-- Add Fallback Intent--> </capability>
android:targetPackage
, es decir,PUT_YOUR_APPLICATION_ID_HERE
, por tuapplicationId
único.
Esta capability asigna el BII GET_EXERCISE_OBSERVATION
al intent app-widget
; por lo tanto, cuando se active el BII, se creará una instancia del widget y este se le mostrará al usuario.
Antes de activar el widget, el Asistente extrae parámetros de BII admitidos de la consulta del usuario. Este codelab requiere el parámetro de BII exerciseObservation.aboutExercise.name
, que representa el tipo de ejercicio solicitado por el usuario. La app admite tres tipos de ejercicio: "correr", "caminar" y "andar en bicicleta". Eres tú quien le informa al Asistente estos valores admitidos por medio de un inventario intercalado.
- Para definir estos elementos del inventario, agrega al archivo
shortcuts.xml
la siguiente configuración, arriba de la capabilityGET_EXERCISE_OBSERVATION
:<!-- shortcuts.xml --> <!-- shortcuts are bound to the GET_EXERCISE_OBSERVATION capability and represent the types of exercises supported by the app. --> <shortcut android:shortcutId="running" android:shortcutShortLabel="@string/activity_running"> <capability-binding android:key="actions.intent.GET_EXERCISE_OBSERVATION"> <parameter-binding android:key="exerciseObservation.aboutExercise.name" android:value="@array/runningSynonyms"/> </capability-binding> </shortcut> <shortcut android:shortcutId="walking" android:shortcutShortLabel="@string/activity_walking"> <capability-binding android:key="actions.intent.GET_EXERCISE_OBSERVATION"> <parameter-binding android:key="exerciseObservation.aboutExercise.name" android:value="@array/walkingSynonyms"/> </capability-binding> </shortcut> <shortcut android:shortcutId="cycling" android:shortcutShortLabel="@string/activity_cycling"> <capability-binding android:key="actions.intent.GET_EXERCISE_OBSERVATION"> <parameter-binding android:key="exerciseObservation.aboutExercise.name" android:value="@array/cyclingSynonyms"/> </capability-binding> </shortcut> <capability android:name="actions.intent.GET_EXERCISE_OBSERVATION"> <!-- ... --> </capability>
Agrega un intent de resguardo
Los intents de resguardo controlan situaciones en las que no es posible llevar a cabo una consulta del usuario porque esta carece de ciertos parámetros que la capability establece como obligatorios. La capability GET_EXERCISE_OBSERVATION
exige el parámetro exerciseObservation.aboutExercise.name
, especificado por el atributo android:required="true"
. En estas situaciones, el Asistente requiere que definas un intent de resguardo para permitir que la solicitud se procese correctamente, incluso si no se proporcionan parámetros en la consulta.
- En el archivo
shortcuts.xml
, agrega un intent de resguardo a la capabilityGET_EXERCISE_OBSERVATION
con esta configuración:<!-- shortcuts.xml --> <capability android:name="actions.intent.GET_EXERCISE_OBSERVATION"> <app-widget> <!-- ... --> </app-widget> <!-- Fallback intent with no parameters needed to successfully execute.--> <intent android:identifier="GET_EXERCISE_OBSERVATION_FALLBACK" android:action="android.intent.action.VIEW" android:targetClass="com.devrel.android.fitactions.widgets.StatsWidgetProvider"> </intent> </capability>
En esta configuración de ejemplo, la entrega de resguardo es un intent de Android sin parámetros en sus datos de Extra
.
5. Habilita el widget para el Asistente
Con la capability GET_EXERCISE_OBSERVATION
establecida, actualiza la clase de widget para admitir la invocación por voz de Acciones en apps.
Agrega la biblioteca de Widgets Extension
La biblioteca de Widgets Extension de Acciones en apps mejora tus widgets para ofrecer experiencias del Asistente que promueven el uso de comandos por voz. Específicamente, te permite proporcionar una introducción personalizada a la función de TTS para tus widgets.
- Agrega la dependencia de la biblioteca de Widgets Extension al recurso
/app/build.gradle
de la app de ejemplo: Haz clic en Sync Now en el cuadro de advertencia que aparece en Android Studio. La sincronización después de cada cambio de// app/build.gradle dependencies { //... implementation "com.google.assistant.appactions:widgets:0.0.1" }
build.gradle
te ayuda a evitar errores durante la compilación de la app.
Agrega el servicio de widgets
Un Service es un componente de la aplicación que puede ejecutar operaciones de larga duración en segundo plano. Tu app tiene que incluir un servicio para procesar las solicitudes de widgets.
- Agrega un servicio al recurso
AndroidManifest.xml
de la app de ejemplo con esta configuración:<!-- AndroidManifest.xml --> <service android:name=".widgets.StatsWidgetProvider" android:enabled="true" android:exported="true"> <intent-filter> <action android:name="com.google.assistant.appactions.widgets.PIN_APP_WIDGET" /> </intent-filter> </service>
Durante una consulta por voz que activa la entrega del widget, el Asistente utiliza ese servicio para enviar solicitudes a la app. El servicio recibe la solicitud junto con los datos del BII y usa estos datos para generar un objeto de widget RemoteView
con el fin de renderizarlo en el Asistente.
Actualiza la clase del widget
La app ya está configurada para que las solicitudes relacionadas con la capability GET_EXERCISE_OBSERVATION
se enruten a la clase de tu widget. A continuación, actualiza la clase StatsWidget.kt
para generar una instancia de widget personalizada para la solicitud del usuario mediante valores de parámetros de BII.
- Abre la clase
StatsWidget.kt
y, luego, importa la biblioteca de Widgets Extension de Acciones en apps:// StatsWidget.kt // ... Other import statements import com.google.assistant.appactions.widgets.AppActionsWidgetExtension
- Agrega estas variables privadas, que usarás cuando determines la información que debe propagar el widget:
// StatsWidget.kt private val hasBii: Boolean private val isFallbackIntent: Boolean private val aboutExerciseName: String private val exerciseType: FitActivity.Type
- Agrega la función
init
para permitir que la clase use los datos de opciones del widget que pase el Asistente:// StatsWidget.kt init { val optionsBundle = appWidgetManager.getAppWidgetOptions(appWidgetId) val bii = optionsBundle.getString(AppActionsWidgetExtension.EXTRA_APP_ACTIONS_BII) hasBii = !bii.isNullOrBlank() val params = optionsBundle.getBundle(AppActionsWidgetExtension.EXTRA_APP_ACTIONS_PARAMS) if (params != null) { isFallbackIntent = params.isEmpty if (isFallbackIntent) { aboutExerciseName = context.resources.getString(R.string.activity_unknown) } else { aboutExerciseName = params.get("aboutExerciseName") as String } } else { isFallbackIntent = false aboutExerciseName = context.resources.getString(R.string.activity_unknown) } exerciseType = FitActivity.Type.find(aboutExerciseName) }
Veamos una explicación de cómo estas actualizaciones habilitan la clase StatsWidget.kt
para que responda a los intents de Android generados por la capability GET_EXERCISE_OBSERVATION
:
optionsBundle
= Bundle- Los paquetes son objetos diseñados para utilizarse en varios procesos y entre distintas actividades con intents, y para almacenar el estado transitorio de los cambios de configuración. El Asistente emplea objetos
Bundle
para pasarle al widget datos de configuración.
- Los paquetes son objetos diseñados para utilizarse en varios procesos y entre distintas actividades con intents, y para almacenar el estado transitorio de los cambios de configuración. El Asistente emplea objetos
bii
=actions.intent.GET_EXERCISE_OBSERVATION
- El nombre del BII se obtiene del paquete mediante
AppActionsWidgetExtension
.
- El nombre del BII se obtiene del paquete mediante
hasBii
=true
- Sirve para verificar si hay un BII.
params
=Bundle[{aboutExerciseName=running}]
- Hay un paquete especial, generado por Acciones en apps, anidado dentro del
Bundle
de opciones del widget. Contiene los pares clave-valor del BII. En este caso, el valorrunning
se extrajo de la consulta de ejemplo "Hey Google, muéstrame las estadísticas de mis actividades de correr en App de Ejemplo".
- Hay un paquete especial, generado por Acciones en apps, anidado dentro del
isFallbackIntent
=false
- Sirve para verificar la presencia de parámetros de BII obligatorios en los
Extras
del intent.
- Sirve para verificar la presencia de parámetros de BII obligatorios en los
aboutExerciseName
=running
- Obtiene el valor de
Extras
del intent paraaboutExerciseName
.
- Obtiene el valor de
exerciseType
=RUNNING
- Emplea
aboutExerciseName
para buscar el objeto del tipo de base de datos correspondiente.
- Emplea
Ahora que la clase StatsWidget
puede procesar datos de intents de Android entrantes de Acciones en apps, actualiza la lógica del flujo de creación del widget para verificar si una Acción en la app activó el widget.
- En
StatsWidget.kt
, reemplaza la funciónupdateAppWidget()
por este código:// StatsWidget.kt fun updateAppWidget() { /** * Checks for App Actions BII invocation and if BII parameter data is present. * If parameter data is missing, use data from last exercise recorded to the * fitness tracking database. */ if (hasBii && !isFallbackIntent) { observeAndUpdateRequestedExercise() } else observeAndUpdateLastExercise() }
El código anterior hace referencia a una función nueva: observeAndUpdateRequestedExercise
. Esta función genera datos de widget por medio de los datos del parámetro exerciseType
que pasa el intent de Android de Acciones en apps.
- Agrega la función
observeAndUpdateRequestedExercise
con este código:// StatsWidget.kt /** * Create and observe the last exerciseType activity LiveData. */ private fun observeAndUpdateRequestedExercise() { val activityData = repository.getLastActivities(1, exerciseType) activityData.observeOnce { activitiesStat -> if (activitiesStat.isNotEmpty()) { formatDataAndSetWidget(activitiesStat[0]) updateWidget() } else { setNoActivityDataWidget() updateWidget() } } }
En el código anterior, utiliza una clase de repositorio que esté presente en la app para recuperar datos de fitness de la base de datos local de la app. Esa clase agrega una API que simplifica el acceso a la base de datos. El repositorio expone un objeto LiveData cuando se hacen consultas a la base de datos. En tu código, debes observar ese LiveData
para recuperar la actividad de fitness más reciente.
Habilita la función de TTS
Puedes incluir una cadena de TTS para que el Asistente la presente cuando muestre tu widget. Nuestra recomendación es que la incluyas para ofrecer widgets con un contexto de información audible. La biblioteca de Widgets Extension de Acciones en apps proporciona esa funcionalidad y te permite agregar el texto y las introducciones a la función de TTS que acompañarán a tus widgets en el Asistente.
Un buen lugar donde incluir una introducción a la función de TTS es dentro de la función formatDataAndSetWidget
, que da formato a los datos de actividades que muestra la base de datos de la app.
- En
StatsWidget.kt
, agrega este código a la funciónformatDataAndSetWidget
:// StatsWidget.kt private fun formatDataAndSetWidget( activityStat: FitActivity, ) { // ... // Add conditional for hasBii for widget with data if (hasBii) { // Formats TTS speech and display text for Assistant val speechText = context.getString( R.string.widget_activity_speech, activityExerciseTypeFormatted, formattedDate, durationInMin, distanceInKm ) val displayText = context.getString( R.string.widget_activity_text, activityExerciseTypeFormatted, formattedDate ) setTts(speechText, displayText) } }
El código anterior hace referencia a dos recursos de cadenas: uno para la voz y otro para el texto. En nuestro video sobre widgets, puedes consultar la sección de recomendación de estilo de redacción para la función de texto a voz (TTS). El ejemplo también hace referencia a setTts
, una nueva función que proporciona la información de TTS a la instancia de widget.
- Agrega esta nueva función
setTts
aStatsWidget.kt
con este código:// StatsWidget.kt /** * Sets TTS to widget */ private fun setTts( speechText: String, displayText: String, ) { val appActionsWidgetExtension: AppActionsWidgetExtension = AppActionsWidgetExtension.newBuilder(appWidgetManager) .setResponseSpeech(speechText) // TTS to be played back to the user .setResponseText(displayText) // Response text to be displayed in Assistant .build() // Update widget with TTS appActionsWidgetExtension.updateWidget(appWidgetId) }
Por último, completa la lógica de TTS estableciendo información de TTS cuando la base de datos de ejercicios no muestre datos para un tipo de entrenamiento solicitado.
- Actualiza la función
setNoActivityDataWidget()
enStatsWidget.kt
con este código:// StatsWidget.kt private fun setNoActivityDataWidget() { // ... // Add conditional for hasBii for widget without data if (hasBii) { // formats speech and display text for Assistant // https://developers.google.com/assistant/app/widgets#library val speechText = context.getString(R.string.widget_no_activity_speech, aboutExerciseName) val displayText = context.getString(R.string.widget_no_activity_text) setTts(speechText, displayText) } }
6. Prueba la Acción en la app
Durante el desarrollo, utiliza el complemento Google Assistant para obtener una vista previa de las Acciones en apps del Asistente en un dispositivo de prueba. Puedes usar la herramienta para ajustar los parámetros de intent de una Acción en la app y probar cómo tu acción procesa las diferentes maneras en que un usuario podría pedirle al Asistente que la ejecute.
Crea una vista previa
Para probar la Acción en la app con el complemento, haz lo siguiente:
- Ve a Tools > Google Assistant > App Actions Test Tool. Puede que tengas que acceder a Android Studio con tu Cuenta de Google.
- Haz clic en Create Preview. Si se te solicita, revisa y acepta las políticas y las Condiciones del Servicio de Acciones en apps.
Prueba un tipo de ejercicio previsto
Para mostrar un widget con información sobre la última actividad de correr completada en la app, sigue estos pasos en la herramienta de prueba:
- En el primer paso, en el que la herramienta te solicita que elijas y configures un BII, selecciona
actions.intent.GET_EXERCISE_OBSERVATION
. - En el cuadro exerciseObservation, actualiza el nombre de ejercicio predeterminado, del valor
climbing
arun
. - Haz clic en Run App Action.
Prueba un tipo de ejercicio no previsto
Para probar un tipo de ejercicio no previsto en la herramienta de prueba, sigue estos pasos:
- En el cuadro exerciseObservation, actualiza el valor de
name
, deRun
aClimbing
. - Haz clic en Run App Action.
El Asistente debería mostrar un widget con el mensaje "No activity found".
Prueba el intent de resguardo
Las consultas que activan el intent de resguardo deberían mostrar un widget con información sobre la última actividad registrada de cualquier tipo de ejercicio.
Para probar el intent de resguardo, haz lo siguiente:
- En el cuadro exerciseObservation, borra el objeto
aboutExercise
. - Haz clic en Run App Action.
El Asistente debería mostrar un widget con información del último ejercicio completado.
7. Próximos pasos
¡Felicitaciones!
Ahora sabes cómo habilitar un widget de Android para el Asistente con el fin de responder a las consultas de los usuarios.
Temas abordados
En este codelab, aprendiste a hacer lo siguiente:
- Agregar a un BII un widget de una app
- Modificar un widget para acceder a los parámetros desde Extras de Android
¿Qué sigue?
De ahora en adelante, podrás definir mejor tu app de fitness. Para consultar el proyecto finalizado, accede al repositorio principal en GitHub.
A continuación, presentamos algunas sugerencias para adquirir más conocimientos sobre cómo configurar esta app con Acciones en apps:
- Consulta la referencia de intents integrados de Acciones en apps para descubrir otras maneras de implementar el Asistente en tus apps.
Para continuar tu recorrido de Actions on Google, explora estos recursos:
- developers.google.com/assistant/app (sitio de documentación oficial sobre Acciones en apps del Asistente de Google)
- Índice de muestra de Acciones en apps (apps de ejemplo y código de muestra para explorar las capabilities de Acciones en apps)
- Repositorio de Actions on Google en GitHub (código de muestra y bibliotecas)
- r/GoogleAssistantDev (comunidad oficial de Reddit para desarrolladores que trabajan con el Asistente de Google)
Síguenos en Twitter (@ActionsOnGoogle) para mantenerte al tanto de nuestros anuncios más recientes y twittea con #appactions para compartir tus compilaciones.
Encuesta de comentarios
Por último, completa esta encuesta para enviarnos comentarios sobre tu experiencia con este codelab.