1. Visão geral
No primeiro codelab das Ações no app, você aprendeu a vincular o Google Assistente a um app fitness implementando intents integradas (BIIs, na sigla em inglês) da categoria "Saúde e fitness".
Com as Ações no app, as pessoas podem acessar recursos específicos de aplicativos usando o Assistente. Basta pedir algo como Ok Google, comece uma corrida no AppDeExemplo. Além de iniciar apps, o Assistente pode mostrar ao usuário um widget interativo do Android e atender a solicitações de BIIs qualificadas.
O que você vai criar
Neste codelab, você vai aprender a retornar widgets do Android para atender a pedidos de usuários no Google Assistente, além de:
- Usar parâmetros de BII para personalizar widgets.
- Fazer apresentações de conversão de texto em voz (TTS) no Google Assistente para seus widgets.
- Utilizar a referência de intents integradas para determinar quais BIIs são compatíveis com o fulfillment de widgets.
Pré-requisitos
Antes de continuar, verifique se o ambiente está pronto para o desenvolvimento de Ações no app. Ele precisa ter:
- Um terminal para executar comandos do shell com git instalado.
- A versão estável mais recente do Android Studio.
- Um dispositivo Android físico ou virtual com acesso à Internet.
- Uma Conta do Google conectada ao Android Studio, ao Google app e ao Assistente.
Dispositivos físicos precisam estar conectados à sua máquina de desenvolvimento local.
2. Como funciona
O Google Assistente usa processamento de linguagem natural (PLN) para entender e associar o pedido do usuário a uma BII do Assistente. Em seguida, o Assistente mapeia a intent para o capability (responsável por implementar a BII), que você registra para ela no app. Depois, o Google Assistente atende o que o usuário pediu mostrando o widget do Android que o app gera (usando os detalhes encontrados no capability).
Neste codelab, você define um capability que registra a compatibilidade com a BII GET_EXERCISE_OBSERVATION
. Nesse capability, você instrui o Google Assistente a gerar uma intent do Android para a classe de widgets FitActions
e, com isso, atender às solicitações dessa BII. Você atualiza a classe para gerar um widget personalizado, que o Google Assistente mostra ao usuário, e uma apresentação de TTS para o Assistente anunciar.
O diagrama a seguir mostra esse fluxo:
Widget FitActions
O app de exemplo FitActions inclui um widget de informações sobre o treino que os usuários podem adicionar à tela inicial. Esse widget é ideal para atender a consultas do usuário que acionam a BII GET_EXERCISE_OBSERVATION
.
Como o widget funciona
Todo widget adicionado à tela inicial dá um ping no dispositivo Broadcast Receiver. Esse serviço recupera informações sobre o widget com base na definição do receptor do widget no recurso AndroidManifest.xml
do app e usa esses dados para gerar um objeto RemoteViews
que representa o widget.
O app de exemplo define o receptor widgets.StatsWidgetProvider
, que corresponde à classe 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>
A classe de StatsWidgetProvider
, StatsWidgetProvider.kt
, gerencia a criação do objeto StatsWidget
. Ela tem estas responsabilidades:
- Criar e preencher instâncias do widget com dados sobre exercícios do banco de dados do app.
- Usar
formatDataAndSetWidget()
para formatar dados sobre treinos, facilitando o entendimento. - Utilizar
setNoActivityDataWidget()
para informar valores padrão se os dados sobre treinos não estiverem disponíveis.
Adicionar suporte ao Google Assistente
Neste codelab, você atualiza o aplicativo de exemplo para processar a funcionalidade das Ações no app. Essas mudanças incluem:
- Configurar o capability de BII
GET_EXERCISE_OBSERVATION
para retornar uma instância do objetoStatsWidget
. - Atualizar a classe
StatsWidget
para aproveitar os recursos das Ações no app, como:- Usar parâmetros de BII, permitindo que os usuários confiram detalhes sobre os treinos pedindo algo como Ok Google, mostre minhas estatísticas de corrida no AppDeExemplo.
- Fornecer strings para a apresentação de TTS.
- Gerenciar casos especiais, por exemplo, quando a consulta do usuário não inclui um parâmetro do tipo de treino.
3. Preparar seu ambiente de desenvolvimento
Fazer o download dos arquivos de base
Execute o comando abaixo para clonar o repositório do GitHub do app de exemplo (link em inglês):
git clone --branch start-widget-codelab https://github.com/actions-on-google/appactions-fitness-kotlin.git
Depois, siga estas etapas para abrir o conteúdo clonado no Android Studio:
- Na caixa de diálogo Welcome to Android Studio, clique em Import project.
- Encontre e selecione a pasta em que você clonou o repositório.
Para conferir uma versão do app que represente o codelab pronto, clone o repositório do app de exemplo usando a sinalização --branch master
.
Atualizar o ID do app Android
Atualize o ID para identificar seu app de forma exclusiva no dispositivo de teste, evitando o erro "Duplicate package name" se o aplicativo for enviado ao Play Console. Para atualizar o ID do aplicativo, abra app/build.gradle
:
android {
...
defaultConfig {
applicationId "com.MYUNIQUENAME.android.fitactions"
...
}
}
Substitua "MYUNIQUENAME" no campo applicationId
por algo exclusivo.
Instalar o plug-in de teste
Com o plug-in do Google Assistente, você pode testar as Ações no app em um dispositivo. Ele envia informações para o Assistente usando o Google app no seu aparelho Android. Para instalar o plug-in:
- Acesse File > Settings (Android Studio > Preferences no MacOS).
- Na seção "Plugins", acesse Marketplace e pesquise "Google Assistant". Também é possível fazer o download e instalar manualmente a ferramenta de teste.
- Instale a ferramenta e reinicie o Android Studio.
Testar o app no seu dispositivo
Antes de fazer outras mudanças, teste o app de exemplo para saber o que ele consegue fazer.
Execute o app no seu dispositivo de teste:
- No Android Studio, escolha o dispositivo físico ou virtual e selecione Run > Run app ou clique em Run
na barra de ferramentas.
- Toque e mantenha pressionado o botão home para configurar o Google Assistente e verificar se ele está funcionando. Faça login no Google Assistente usando seu dispositivo.
Para mais informações sobre dispositivos virtuais Android, consulte Criar e gerenciar dispositivos virtuais.
Use um pouco o app para saber o que ele oferece. Dez atividades de exercício já vêm preenchidas, e o aplicativo mostra essas informações na primeira visualização.
Testar o widget atual
- Toque no botão home para acessar a tela inicial do dispositivo de teste.
- Toque e mantenha pressionado um espaço vazio na tela inicial e selecione Widgets.
- Role a lista de widgets para baixo até chegar em FitActions.
- Toque no ícone FitActions. Mantenha pressionado e posicione o widget na tela inicial.
4. Adicionar a Ação no app
Nesta etapa, você adiciona o capability de BII GET_EXERCISE_OBSERVATION
. Para fazer isso, inclua um novo elemento capability
no arquivo shortcuts.xml
. Esse capability especifica como ele é acionado, como os parâmetros de BII são usados e quais intents do Android precisam ser invocadas para atender ao pedido.
- Adicione um novo elemento
capability
ao recursoshortcuts.xml
do projeto de exemplo com esta configuração: Substitua o 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
,PUT_YOUR_APPLICATION_ID_HERE
, peloapplicationId
exclusivo.
Esse capability mapeia a BII GET_EXERCISE_OBSERVATION
para a intent app-widget
. Assim, quando a BII é acionada, o widget é instanciado e mostrado ao usuário.
Antes de acionar o widget, o Google Assistente extrai da consulta do usuário os parâmetros de BII aceitos. Este codelab requer o parâmetro de BII exerciseObservation.aboutExercise.name
, que representa o tipo de exercício que a pessoa pediu. O app funciona com três tipos de exercícios: "corrida", "caminhada" e "ciclismo". Você fornece um inventário inline para informar esses valores ao Google Assistente.
- Para definir esses elementos de inventário, adicione ao arquivo
shortcuts.xml
a seguinte configuração acima do 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>
Adicionar uma intent substituta
As intents substitutas são usadas em situações em que não é possível atender a uma consulta do usuário porque faltam parâmetros que o capability exige. O capability GET_EXERCISE_OBSERVATION
requer o parâmetro exerciseObservation.aboutExercise.name
, que é especificado pelo atributo android:required="true"
. Nessas situações, o Google Assistente exige que você defina uma intent substituta para a solicitação, mesmo que nenhum parâmetro seja informado na consulta.
- Em
shortcuts.xml
, adicione uma intent substituta ao capabilityGET_EXERCISE_OBSERVATION
com esta configuração:<!-- 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>
Nesta configuração de exemplo, o fulfillment substituto é uma intent do Android sem parâmetros nos dados de Extra
.
5. Ativar o widget do Assistente
Com o capability GET_EXERCISE_OBSERVATION
estabelecido, atualize a classe do widget para aceitar comandos de voz nas Ações no app.
Adicionar a biblioteca Widgets Extension
A biblioteca Widgets Extension das Ações no app melhora os widgets para experiências do Google Assistente que usam a voz. Com ela, também é possível oferecer uma apresentação personalizada de TTS para seus widgets.
- Adicione a dependência da biblioteca Widgets Extension ao recurso
/app/build.gradle
do app de exemplo: Clique em Sync Now na caixa de aviso que aparece no Android Studio. Faça a sincronização após cada mudança do// app/build.gradle dependencies { //... implementation "com.google.assistant.appactions:widgets:0.0.1" }
build.gradle
para evitar erros no desenvolvimento do app.
Adicionar o serviço de widgets
Um serviço é um componente de aplicativo que executa operações de longa duração em segundo plano. Seu app precisa fornecer um serviço para processar as solicitações dos widgets.
- Adicione um serviço ao recurso
AndroidManifest.xml
do app de exemplo com esta configuração:<!-- 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 uma consulta por voz que aciona o fulfillment do widget, o Google Assistente usa esse serviço para enviar solicitações ao app. O serviço recebe o pedido com os dados da BII e usa essas informações para gerar um objeto de widget de RemoteView
, que é renderizado no Assistente.
Atualizar a classe do widget
Seu app agora consegue encaminhar solicitações do capability GET_EXERCISE_OBSERVATION
à sua classe de widgets. Em seguida, atualize a classe StatsWidget.kt
para gerar uma instância de widget personalizada de acordo com o pedido do usuário, utilizando valores de parâmetros de BII.
- Abra a classe
StatsWidget.kt
e importe a biblioteca Widget Extension das Ações no app:// StatsWidget.kt // ... Other import statements import com.google.assistant.appactions.widgets.AppActionsWidgetExtension
- Adicione as variáveis particulares usadas para determinar as informações que vão preencher o widget:
// StatsWidget.kt private val hasBii: Boolean private val isFallbackIntent: Boolean private val aboutExerciseName: String private val exerciseType: FitActivity.Type
- Adicione a função
init
para permitir que a classe use os dados de opções do widget transmitidos pelo Google Assistente:// 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) }
Confira abaixo como essas atualizações permitem que a classe StatsWidget.kt
responda a intents do Android geradas pelo capability GET_EXERCISE_OBSERVATION
:
optionsBundle
= pacote- Os pacotes são objetos usados nos limites de processamento, entre atividades com intents, e para armazenar o estado temporário durante as mudanças na configuração. O Google Assistente usa objetos
Bundle
para transmitir dados de configuração ao widget.
- Os pacotes são objetos usados nos limites de processamento, entre atividades com intents, e para armazenar o estado temporário durante as mudanças na configuração. O Google Assistente usa objetos
bii
=actions.intent.GET_EXERCISE_OBSERVATION
- Para saber o nome da BII no pacote, use
AppActionsWidgetExtension
.
- Para saber o nome da BII no pacote, use
hasBii
=true
- Verifica se há uma BII.
params
=Bundle[{aboutExerciseName=running}]
- Um pacote especial, gerado por Ações no app, está aninhado no
Bundle
das opções do widget. Ele contém os pares de chave-valor da BII. Nesse caso, o valorrunning
foi extraído da consulta de exemplo Ok Google, mostre minhas estatísticas de corrida no AppDeExemplo.
- Um pacote especial, gerado por Ações no app, está aninhado no
isFallbackIntent
=false
- Verifica se os parâmetros de BII necessários nos
Extras
da intent estão presentes.
- Verifica se os parâmetros de BII necessários nos
aboutExerciseName
=running
- Recebe o valor dos
Extras
da intent paraaboutExerciseName
.
- Recebe o valor dos
exerciseType
=RUNNING
- Usa
aboutExerciseName
para procurar o objeto do tipo de banco de dados correspondente.
- Usa
Agora que a classe StatsWidget
processa dados da intent do Android referentes às Ações no app, atualize a lógica da criação de widgets para verificar se o widget foi acionado por uma dessas ações.
- Em
StatsWidget.kt
, substitua a funçãoupdateAppWidget()
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() }
O código anterior faz referência a uma nova função, observeAndUpdateRequestedExercise
, que gera dados do widget usando as informações do parâmetro exerciseType
transmitidas pela intent do Android das Ações no app.
- Adicione a função
observeAndUpdateRequestedExercise
com 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() } } }
No código anterior, use uma classe de repositório do app para recuperar dados de condicionamento físico no banco de dados local do aplicativo. Essa classe fornece uma API que simplifica o acesso ao banco de dados. O repositório expõe um objeto LiveData quando consulta o banco. No seu código, você observa esse LiveData
para recuperar o exercício mais recente.
Ativar a TTS
Você pode fornecer uma string de TTS para o Google Assistente anunciar quando mostrar seu widget. Recomendamos incluir uma string para criar um contexto audível com os widgets. Esse recurso é oferecido pela biblioteca Widgets Extension das Ações no app, que permite definir o texto e as apresentações de TTS que acompanham seus widgets no Assistente.
Um bom lugar para fazer a apresentação de TTS é na função formatDataAndSetWidget
, que formata os dados da atividade retornados do banco de dados do app.
- Em
StatsWidget.kt
, adicione este código à funçãoformatDataAndSetWidget
:// 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) } }
O código anterior faz referência a dois recursos de string: um para fala e outro para texto. Confira as sugestões de TTS na seção Recomendação de estilo da conversão de texto em voz do vídeo sobre nossos widgets. O exemplo também faz referência a setTts
, uma nova função que transmite as informações de TTS para a instância do widget.
- Adicione a nova função
setTts
aStatsWidget.kt
usando 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) }
Para concluir a lógica de TTS, defina informações de TTS quando o banco de dados sobre exercícios não retornar dados para o tipo de treino solicitado.
- Atualize a função
setNoActivityDataWidget()
noStatsWidget.kt
com 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. Testar a Ação no app
Durante o desenvolvimento, use o plug-in do Google Assistente para conferir as Ações no app em um dispositivo de teste. É possível ajustar os parâmetros de intent de uma Ação no app para testar como ela processa as várias formas possíveis de um usuário pedir algo ao Assistente.
Criar uma prévia
Para testar a Ação no app com o plug-in:
- Acesse Tools > Google Assistant > App Actions Test Tool. Talvez seja necessário fazer login no Android Studio usando sua Conta do Google.
- Clique em Create preview. Confira e aceite as políticas e os Termos de Serviço das Ações no app, se for o caso.
Testar um tipo de exercício esperado
Para redirecionar a um widget que mostra informações sobre a última corrida concluída no app, siga estas etapas na ferramenta de teste:
- Primeiro, a ferramenta pede para selecionar e configurar uma BII. Escolha
actions.intent.GET_EXERCISE_OBSERVATION
. - Na caixa exerciseObservation mude o nome padrão do exercício de
climbing
pararun
. - Clique em Run App Action.
Testar um tipo de exercício inesperado
Para testar um tipo de exercício inesperado na ferramenta:
- Na caixa exerciseObservation mude o valor
name
deRun
paraClimbing
. - Clique em Run App Action.
O Google Assistente vai retornar um widget com a informação "Nenhuma atividade encontrada".
Testar a intent substituta
As consultas que acionam a intent substituta precisam retornar um widget com informações sobre a última atividade registrada de qualquer tipo de exercício.
Para testar a intent substituta:
- Na caixa exerciseObservation, exclua o objeto
aboutExercise
. - Clique em Run App Action.
O Google Assistente vai retornar um widget com informações sobre o último exercício concluído.
7. Próximas etapas
Parabéns!
Agora você sabe como atender às consultas dos usuários com um widget do Android usando o Google Assistente.
O que aprendemos
Neste codelab, você aprendeu a:
- Adicionar um widget de app a uma BII.
- Modificar um widget para acessar parâmetros de extras do Android.
O que vem a seguir
Você pode melhorar ainda mais o app fitness. Para fazer referência ao projeto finalizado, consulte o repositório principal no GitHub (link em inglês).
Confira algumas sugestões para integrar esse aplicativo usando as Ações no app:
- Acesse a referência de intents integradas das Ações no app para descobrir mais formas de integrar seus apps ao Google Assistente.
Para continuar sua jornada na plataforma Actions on Google, confira estes recursos:
- developers.google.com/assistant/app: site da documentação oficial das Ações no app no Google Assistente
- Índice de exemplos de Ações no app: códigos e aplicativos de exemplo para conhecer os capabilities das Ações no app
- Repositório do GitHub da plataforma Actions on Google (link em inglês): exemplo de código e bibliotecas
- r/GoogleAssistantDev: comunidade oficial do Reddit em inglês para desenvolvedores que trabalham com o Google Assistente
Siga nosso perfil @ActionsOnGoogle no Twitter, fique por dentro das novidades e envie um tweet com #appactions para mostrar o que você criou.
Pesquisa de feedback
Para terminar, responda a esta pesquisa e dê seu feedback sobre o que achou do codelab.