Para muitas intents, o melhor é fornecer ao usuário uma resposta simples, uma confirmação breve ou uma experiência interativa rápida. Você pode mostrar um widget de app Android no Google Assistente para atender a esses tipos de intents.
Este guia ensina como realizar consultas de usuários no Google Assistente usando widgets e como melhorar sua experiência com o Google Assistente usando a biblioteca Widgets Extension das Ações no app.
Benefícios
Os widgets são visualizações em miniatura de apps que podem ser incorporadas em plataformas do Android, como a tela de início ou de bloqueio. Com as Ações no app, você aumenta o impacto dos seus widgets, fazendo com que eles possam aparecer no Google Assistente:
- Descoberta: mostre widgets de forma proativa em resposta às consultas dos usuários em linguagem natural.
- Engajamento: mostre widgets em contextos viva-voz, como quando o Google Assistente fornece resultados personalizados na tela de bloqueio e no Android Auto.
- Retenção: permita que os usuários fixem na tela de início os widgets mostrados no Google Assistente. Essa função exige a biblioteca Widgets Extension.
Como o Google Assistente mostra widgets
Os usuários têm duas maneiras de invocar widgets no Google Assistente:
- Solicitar um widget explicitamente pelo nome.
- Fazer uma consulta com o Google Assistente, que aciona uma intent integrada (BII, na sigla em inglês) ou uma intent personalizada configurada para fulfillment de widget
Invocação explícita
Para invocar explicitamente os widgets de qualquer app instalado, os usuários podem fazer pedidos como estes ao Google Assistente:
- "Ok Google, mostre o widget do ExampleApp."
- "Widgets do ExampleApp."
O Google Assistente mostra esses widgets com a introdução genérica: "Aqui está o widget do ExampleApp". O Google Assistente retorna os widgets solicitados dessa maneira de forma nativa, sem nenhum trabalho do desenvolvedor do app, mas esse método de invocação exige que o usuário tenha conhecimento explícito do widget a ser solicitado. Para simplificar a descoberta de widgets, use o método de fulfillment da intent detalhado na seção a seguir.
Fulfillment da intent
Seus widgets podem ser encontrados com mais facilidade quando são usados para atender às consultas
que os usuários fazem no Google Assistente usando linguagem natural. Por exemplo, você pode retornar um
widget sempre que um usuário acionar a BII GET_EXERCISE_OBSERVATION
no
seu app fitness perguntando "Ok Google, quantos quilômetros eu corri esta semana no
ExampleApp?". Além de simplificar a descoberta, a integração de widgets com
as Ações no app oferece estas vantagens:
- Acesso a parâmetros: o Google Assistente fornece os parâmetros de intent extraídos da consulta do usuário para seu widget, resultando em respostas personalizadas.
- Apresentações personalizadas de TTS: você pode fornecer uma string de conversão de texto em voz (TTS) para o Google Assistente anunciar ao mostrar seu widget.
- Fixação de widgets: o Google Assistente mostra um botão Adicionar este widget ao lado do seu widget para que ele possa ser fixado na tela de início de forma simples.
Implementar o fulfillment de widgets
Para implementar o fulfillment de widgets para as intents, siga estas etapas:
- Implemente um widget do Android seguindo as etapas descritas em Criar um widget simples.
- No arquivo
shortcuts.xml
do seu app, adicione um elemento<app-widget>
ao recurso que contém detalhes de fulfillment e tags de<parameter>
da BII. Atualize o widget para processar os parâmetros. - Adicione a biblioteca Widgets Extension obrigatória, que permite que o Google Assistente transmita nomes e parâmetros de BIIs aos widgets. Ela também ativa as apresentações de TTS personalizadas e a funcionalidade de fixação de widgets.
A seção a seguir descreve o esquema de <app-widget>
para o shortcuts.xml
.
Esquema do widget
Os elementos <app-widget>
são definidos como fulfillments dentro dos elementos
<capability>
no arquivo shortcuts.xml
. A menos que sejam considerados opcionais,
eles exigem os seguintes atributos:
Tag no "shortcuts.xml" | Contida em | Atributos |
---|---|---|
<app-widget> |
<capability> |
|
<parameter> |
<app-widget> |
|
<extra> |
<app-widget> |
|
Descrição do esquema do widget
<app-widget>
Elemento de fulfillment do widget de nível superior.
Atributos:
android:identifier
: o identificador desse fulfillment. Esse valor precisa ser único entre os elementos de fulfillment<app-widget>
e<intent>
definidos em um elemento<capability>
.android:targetClass
: o nome completo da classe da suaAppWidgetProvider
para processar a intent.
<parameter>
Associa um parâmetro de BII a um valor <parameter>
de intent. É possível definir zero ou
mais parâmetros para cada elemento <app-widget>
. Durante o fulfillment, o Google Assistente
transmite os parâmetros atualizando os extras da instância de widget como pares de chave-valor
com o seguinte formato:
- Chave: o
android:key
definido para o parâmetro. - Valor: aquele que a BII extrai da entrada de voz de um usuário.
Para acessar esses extras, chame getAppWidgetOptions()
no objeto
AppWidgetManager
associado que retorna um Bundle
contendo o nome da
BII e os parâmetros dela. Consulte
Extrair valores de parâmetros para ver mais detalhes.
Se quiser mais informações sobre a correspondência de parâmetros de BII, consulte Correspondência e dados de parâmetros.
<extra>
Tag opcional que declara que uma apresentação personalizada de TTS é usada para esse widget. Essa tag requer os seguintes valores de atributo:
android:name
:"hasTts"
android:value
:"true"
Exemplo de código
O exemplo a seguir de um arquivo shortcuts.xml
demonstra uma configuração
de fulfillment de widget para um
recurso 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>
Você pode especificar vários elementos <app-widget>
ou usar uma combinação de
elementos <app-widget>
e <intent>
por recurso. Essa abordagem permite
fornecer uma experiência personalizada com base em diferentes combinações de parâmetros
fornecidos pelos usuários. Por exemplo, caso o usuário não especifique um local de desembarque
na consulta, ele pode ser direcionado para a atividade no app que mostra
opções para definir os locais de embarque e desembarque. Consulte a
seção Intents substitutas para mais informações
sobre como definir essas intents.
Extrair valores de parâmetros
Na classe AppWidgetProvider
de exemplo a seguir, a função particular
updateAppWidget()
é usada para extrair o nome e os parâmetros da BII do
Bundle
de opções de 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 Widgets Extension
A biblioteca Widget Extensions de Ações no app melhora os widgets para experiências do Google Assistente que usam a voz. Ela permite que os widgets recebam informações importantes de fulfillment da BII de acionamento, incluindo o nome da BII e os parâmetros de intent extraídos da consulta do usuário.
Com essa biblioteca do Maven, você pode fornecer uma apresentação personalizada de conversão de texto em voz (TTS, na sigla em inglês) para cada widget, permitindo que o Google Assistente anuncie um resumo do conteúdo que está sendo renderizado visualmente. Ela também ativa a fixação na tela de início, fazendo com que seja mais fácil salvar nessa tela os widgets mostrados no Google Assistente.
Para começar, adicione a biblioteca à seção de dependências do
arquivo build.gradle
do módulo do app:
dependencies {
//...
implementation "com.google.assistant.appactions:widgets:0.0.1"
}
Apresentações personalizadas
Depois de importar a biblioteca Widgets Extension, você pode fornecer apresentações personalizadas de TTS
para seus widgets. Se quiser adicionar sua definição à AppWidgetProvider
do widget, abra essa classe no ambiente de desenvolvimento integrado e importe a biblioteca
Widgets Extension:
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); } }
Recomendações de estilo para TTS
Use as recomendações de estilo a seguir para otimizar as apresentações do widget personalizado para o TTS e as solicitações exibidas.
Recomendação | Recomendado | Não recomendado |
---|---|---|
Expressões mais naturaisUse expressões que soam mais naturais nas solicitações de TTS. Mensagens muito longas e formais ficam muito rígidas e robóticas, e não naturais e conversacionais. Falar palavras como "não foi possível" e "desculpe" pode soar pouco natural. |
ResponseSpeech (TTS)Não encontrei uma reserva. ResponseText Não consigo encontrar uma reserva. |
ResponseSpeech (TTS)Não encontrei uma reserva. ResponseText Desculpe, não foi possível encontrar uma reserva. |
ListasPara aumentar a clareza, use "e" para separar quando há três itens ou ao final de uma lista. Sem o "e", é possível que itens individuais na lista sejam ouvidos de forma incorreta ou lidos como grupos. Por exemplo, em "gafanhotos, margaridas, girassóis", "margaridas e girassóis" soa como se estivessem reunidos. Em "macarrão, margaridas e girassóis", os três são claramente separados. |
ResponseSpeech (TTS)As flores mais conhecidas incluem rosas amarelas, narcisos, margaridas e girassóis. ResponseText As flores mais conhecidas incluem rosas amarelas, narcisos, margaridas e girassóis. |
ResponseSpeech (TTS)As flore mais conhecidas incluem rosas amarelas, narcisos, margaridas, girassóis. ResponseText Os mais procurados incluem rosas amarelas, narcisos, margaridas, girassóis. |
NumeraisUse números em vez de texto para facilitar a visualização do conteúdo. |
ResponseSpeech (TTS)Sua pressão arterial é de 100 por 80. ResponseText Sua pressão arterial é de 100/80. |
ResponseSpeech (TTS)Sua pressão arterial é de 100/80. ResponseText Sua pressão arterial é de cem por oitenta. |
SímbolosUse símbolos especializados em vez de texto para facilitar a visualização do conteúdo. |
ResponseSpeech (TTS)Sua última compra foi de R$ 24,65. ResponseText Sua última compra foi de R$ 24,65. |
ResponseSpeech (TTS)Sua última compra foi de vinte e quatro reais e sessenta e cinco centavos. ResponseText Sua última compra foi de vinte e quatro reais e sessenta e cinco centavos. |
Evite cortesiasAs cortesias tornam as respostas distantes e formais. Deixe de lado as formalidades e mantenha a conversa amigável e informal. |
ResponseSpeech (TTS)Seu pedido foi entregue. ResponseText Seu pedido foi entregue. |
ResponseSpeech (TTS)Claro, eu posso fornecer essa informação. Seu pedido foi entregue. ResponseText Claro, eu posso fornecer essa informação. Seu pedido foi entregue. |
Evite pontos de exclamaçãoEles podem ser entendidas como gritos. |
ResponseSpeech (TTS)Você correu 1,5 km hoje. ResponseText Você correu 1,5 km hoje. |
ResponseSpeech (TTS)Você correu 1,5 km hoje! ResponseText Você correu 1,5 km hoje! |
HoraUse numerais: "5:15", em vez de "cinco e quinze". Para o relógio de 12 horas, use AM ou PM. |
ResponseSpeech (TTS)Sua entrega deve chegar até as 8h15. ResponseText Sua entrega deve chegar até as 8h15. |
ResponseSpeech (TTS)Sua entrega deve chegar 15 minutos após as 8h de hoje. ResponseText Sua entrega deve chegar 15 minutos após as 8h de hoje. |
Cuidado para não fazer monólogosSeja informativo, mas mantenha as respostas concisas. Não entre em detalhes complicados que não tenham um benefício claro para o usuário. |
ResponseSpeech (TTS)No mês passado, você consumiu 159 horas de energia. ResponseText No mês passado, você consumiu 159 horas de energia. |
ResponseSpeech (TTS)Economizar energia é muito importante para o planeta e o meio ambiente. No mês passado, você consumiu 159 horas de energia. Neste mês, você consumiu 58 horas de energia. ResponseText Economizar energia é muito importante para o planeta e o meio ambiente. No mês passado, você consumiu 159 horas de energia. Neste mês, você consumiu 58 horas de energia. |
Use palavras curtas e simplesUma linguagem simples e breve é mais atrativa, o que a torna mais acessível para pessoas de todas as origens. |
ResponseSpeech (TTS)O resultado da sua última leitura de açúcar no sangue foi 126. ResponseText O resultado da sua última leitura de açúcar no sangue foi 126 mg/dL. |
ResponseSpeech (TTS)O penúltimo nível de glicose no sangue foi 126. ResponseText O penúltimo nível de glicose no sangue foi 126. |
Fixação na tela de início
A biblioteca Widgets Extension permite que o botão Add this widget seja mostrado
com seu widget no Google Assistente. Para ativar a fixação, adicione a seguinte definição
de 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>
Disponibilidade de inventário
As BIIs com suporte ao inventário inline ou ao inventário da Web podem ampliar esses inventários para os fulfillments do widget.
Inventário inline
O código a seguir de um arquivo shortcuts.xml
de exemplo demonstra um
recurso da BII START_EXERCISE
configurado para inventário inline e fulfillment do widget:
<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>
No exemplo anterior, quando um usuário pedir
para o Google Assistente "Começar a correr com o ExampleApp", o pacote de opções para o
fulfillment <app-widget>
vai conter o seguinte par de chave-valor:
- Tecla =
“exerciseName”
- Valor:
“RunningShortcut”
Inventário da Web
O código a seguir de um exemplo de arquivo shortcuts.xml
mostra um recurso
ativado para inventário da Web e fulfillment do widget:
<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>
Testar Ações no app
Use a App Actions Test Tool (um recurso do plug-in do Google Assistente para Android Studio) para testar widgets em um dispositivo físico ou virtual. Siga estas etapas para usar a ferramenta de teste:
- Conecte o dispositivo de teste em que o app está sendo executado.
- No Android Studio, acesse Tools > App Actions > App Actions Test Tool.
- Clique em Create preview.
- No Android Studio, execute o app no dispositivo de teste.
- Use o app Google Assistente no seu dispositivo para testar a ação no app. Por exemplo, você pode dizer algo como "Ok Google, quantos quilômetros eu corri esta semana no ExampleApp?".
- Observe o comportamento do app ou use o depurador do Android Studio para verificar o resultado da ação desejada.
Diretrizes de qualidade
Esta seção destaca os principais requisitos e as práticas recomendadas quando você integra Ações no app com widgets.
Conteúdo em widgets
- (Obrigatório) Não mostre anúncios nos seus widgets.
- Concentre-se totalmente no conteúdo do widget para cumprir a intent. Não atenda a várias intents com um único widget nem adicione conteúdo irrelevante.
Processar a autenticação
- (Obrigatório) Quando a autenticação do usuário for necessária para concluir um fluxo do usuário, retorne um widget que explica que o usuário precisa continuar no app. As Ações no app não têm suporte para a autenticação de usuários inline no Google Assistente.
- Se os usuários permitirem que o app mostre dados usando widgets, você poderá retornar um widget de erro no tempo de execução para usuários não autorizados.
Intents substitutas
(Obrigatório) No
shortcuts.xml
, sempre forneça uma<intent>
substituta com o fulfillment do widget para um recurso específico. Uma intent substituta é um elemento<intent>
sem valores de<parameter>
obrigatórios.Isso permite que o Google Assistente realize uma ação quando a consulta do usuário não tiver parâmetros exigidos pelos outros elementos de fulfillment definidos no recurso. A exceção é quando não há parâmetros obrigatórios para o recurso. Nesse caso, apenas o fulfillment do widget é necessário.
Use a intent de fallback para abrir o app na tela relevante, não na tela inicial.
O código a seguir de um exemplo de arquivo shortcuts.xml
demonstra uma
<capability>
com uma <intent>
substituta que oferece suporte a um fulfillment
principal do <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>
Declaração sobre o uso de dados pelo Google Play
Esta seção lista os dados do usuário final coletados pela versão mais recente da biblioteca Widgets Extension.
Esse SDK envia as respostas de conversão de texto em voz (TTS) fornecidas pelo desenvolvedor que são ditas ao usuário pelo Google Assistente usando a tecnologia de fala dele. Essas informações não são armazenadas pelo Google.
As Ações no app também podem coletar metadados do app cliente para as seguintes finalidades:
- Monitorar as taxas de adoção de diferentes versões do SDK.
- Quantificar o uso dos recursos do SDK nos apps.