1. Panoramica
Nel primo codelab Azioni app, hai imparato a estendere l'Assistente Google a un'app di fitness di esempio implementando gli intent integrati (BII) della categoria BII per la salute e il fitness.
Le Azioni app consentono agli utenti di avviare direttamente funzionalità specifiche delle app dall'assistente chiedendo ad esempio "Hey Google, inizia una corsa su EsempioApp". Oltre ad avviare app, l'assistente può mostrare all'utente un widget Android interattivo per soddisfare le richieste di intent integrati idonei.

Cosa creerai
In questo codelab, imparerai a restituire widget per Android per soddisfare le richieste degli utenti dell'assistente. Inoltre, imparerai a:
- Utilizza i parametri degli intent integrati (BII) per personalizzare i widget.
- Fornisci introduzioni con sintesi vocale (TTS) nell'assistente per i tuoi widget.
- Utilizza il riferimento agli intent integrati per determinare quali intent integrati supportano il completamento dei widget.
Prerequisiti
Prima di continuare, assicurati che l'ambiente di sviluppo sia pronto per lo sviluppo di Azioni app. Deve avere:
- Un terminale per eseguire comandi shell, con Git installato.
- L'ultima release stabile di Android Studio.
- Un dispositivo Android fisico o virtuale con accesso a internet.
- Un Account Google collegato ad Android Studio, all'app Google e all'app Assistente Google.
Se utilizzi un dispositivo fisico, connettilo alla macchina di sviluppo locale.
2. Comprendere il funzionamento
L'Assistente Google utilizza la comprensione del linguaggio naturale (NLU) per leggere la richiesta di un utente e associarla a un intent integrato dell'assistente (BII). L'assistente mappa l'intent alla funzionalità (che implementa l'intent integrato), per la quale ti registri per quell'intent nella tua app. Infine, l'assistente soddisfa la richiesta dell'utente visualizzando il widget Android generato dalla tua app utilizzando i dettagli trovati nella funzionalità.
In questo codelab, definisci una funzionalità che registra il supporto per l'intent integrato GET_EXERCISE_OBSERVATION. In questa funzionalità, chiedi all'assistente di generare un intent Android per la classe di widget FitActions per soddisfare le richieste per questo intent integrato. Aggiorni questa classe per generare un widget personalizzato che l'assistente mostri all'utente e un'introduzione TTS che l'assistente annunci.
Il seguente diagramma mostra questo flusso:

Il widget FitActions
L'app di esempio FitActions contiene un widget con informazioni sull'allenamento che gli utenti possono aggiungere alla schermata Home. Questo widget è un ottimo candidato per soddisfare le query utente che attivano l'intent integrato GET_EXERCISE_OBSERVATION.
Come funziona il widget
Quando un utente aggiunge un widget alla schermata Home, il widget esegue il ping del ricevitore di trasmissione del dispositivo. Questo servizio recupera le informazioni sul widget dalla definizione del ricevitore del widget nella risorsa AndroidManifest.xml dell'app. Utilizza queste informazioni per generare un oggetto RemoteViews che rappresenta il widget.
L'app di esempio definisce il ricevitore widgets.StatsWidgetProvider, che corrisponde alla 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>
La classe StatsWidgetProvider, StatsWidgetProvider.kt, gestisce i flussi di creazione degli oggetti StatsWidget. Gestisce le seguenti responsabilità:
- Creazione di istanze di widget e compilazione con i dati di allenamento del database dell'app.
- Formattazione dei dati di allenamento per una migliore leggibilità, con
formatDataAndSetWidget(). - Fornire valori predefiniti se i dati di allenamento non sono disponibili, utilizzando
setNoActivityDataWidget().
Aggiungere il supporto dell'assistente
In questo codelab, aggiorni l'app di esempio per gestire la funzionalità Azioni app. Queste modifiche includono:
- Configurazione della funzionalità di intent integrati
GET_EXERCISE_OBSERVATIONper restituire un'istanza dell'oggettoStatsWidget. - Aggiornamento della classe
StatsWidgetper utilizzare le funzionalità delle Azioni app, ad esempio:- Utilizzo di parametri BII, che consentono agli utenti di visualizzare statistiche di allenamento specifiche chiedendo cose come "Hey Google, mostrami le statistiche della mia corsa su ExampleApp".
- Fornire stringhe introduttive di sintesi vocale.
- Gestione di casi speciali, ad esempio quando la query dell'utente non include un parametro di tipo di allenamento.
3. Prepara l'ambiente di sviluppo
Scaricare i file di base
Esegui questo comando per clonare il repository GitHub dell'app di esempio:
git clone --branch start-widget-codelab https://github.com/actions-on-google/appactions-fitness-kotlin.git
Dopo aver clonato il repository, segui questi passaggi per aprirlo in Android Studio:
- Nella finestra di dialogo Benvenuto in Android Studio, fai clic su Importa progetto.
- Trova e seleziona la cartella in cui hai clonato il repository.
Per visualizzare una versione dell'app che rappresenta il codelab completato, clona il repository dell'app di esempio utilizzando il flag --branch master.
Aggiornare l'ID applicazione Android
L'aggiornamento dell'ID applicazione dell'app identifica in modo univoco l'app sul dispositivo di test ed evita l'errore "Nome del pacchetto duplicato" se l'app viene caricata su Play Console. Per aggiornare l'ID applicazione, apri app/build.gradle:
android {
...
defaultConfig {
applicationId "com.MYUNIQUENAME.android.fitactions"
...
}
}
Sostituisci "MYUNIQUENAME" nel campo applicationId con un nome univoco.
Installa il plug-in di test
Il plug-in dell'Assistente Google ti consente di testare le Azioni app su un dispositivo di test. Funziona inviando informazioni all'assistente tramite l'app Google sul tuo dispositivo Android. Se non hai ancora il plug-in, installalo seguendo questi passaggi:
- Vai a File > Impostazioni (Android Studio > Preferenze su macOS).
- Nella sezione Plug-in, vai a Marketplace e cerca "Assistente Google". Puoi anche scaricare e installare manualmente lo strumento di test.
- Installa lo strumento e riavvia Android Studio.
Testare l'app sul dispositivo
Prima di apportare ulteriori modifiche all'app, è utile farsi un'idea di cosa può fare l'app di esempio.
Esegui l'app sul dispositivo di test:
- In Android Studio, seleziona il dispositivo fisico o virtuale e seleziona Esegui > Esegui app o fai clic su Esegui
nella barra degli strumenti. - Tieni premuto il pulsante Home per configurare l'assistente e verificare che funzioni. Se non l'hai ancora fatto, dovrai accedere all'assistente sul tuo dispositivo.
Per ulteriori informazioni sui dispositivi virtuali Android, vedi Creare e gestire dispositivi virtuali.
Esplora brevemente l'app per vedere cosa può fare. L'app precompila 10 attività di allenamento e mostra queste informazioni nella prima visualizzazione.
Prova il widget esistente
- Tocca il pulsante Home per andare alla schermata Home del dispositivo di test.
- Tieni premuto uno spazio vuoto nella schermata Home e seleziona Widget.
- Scorri verso il basso l'elenco dei widget fino a FitActions.
- Tieni premuta l'icona FitActions e posiziona il widget nella schermata Home.

4. Aggiungere l'Azione app
In questo passaggio, aggiungi la funzionalità di intent integrati GET_EXERCISE_OBSERVATION. A tale scopo, aggiungi un nuovo elemento capability in shortcuts.xml. Questa funzionalità specifica come viene attivata, come vengono utilizzati i parametri BII e quali intent Android richiamare per soddisfare la richiesta.
- Aggiungi un nuovo elemento
capabilityalla risorsashortcuts.xmldel progetto di esempio con questa configurazione: Sostituisci il valore<!-- 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, con il tuoapplicationIdunivoco.
Questa funzionalità mappa l'intent integrato GET_EXERCISE_OBSERVATION all'intent app-widget in modo che quando l'intent integrato viene attivato, il widget venga istanziato e visualizzato dall'utente.
Prima di attivare il widget, l'assistente estrae i parametri BII supportati dalla query dell'utente. Questo codelab richiede il parametro intent integrato exerciseObservation.aboutExercise.name, che rappresenta il tipo di allenamento richiesto dall'utente. L'app supporta tre tipi di allenamento: "corsa", "camminata" e "ciclismo". Fornisci un inventario in linea per comunicare all'assistente questi valori supportati.
- Definisci questi elementi dell'inventario aggiungendo questa configurazione, sopra la funzionalità
GET_EXERCISE_OBSERVATION, ashortcuts.xml:<!-- 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>
Aggiungere un intent di riserva
Gli intent di riserva gestiscono le situazioni in cui una query utente non può essere completata perché mancano i parametri richiesti dalla funzionalità. La funzionalità GET_EXERCISE_OBSERVATION richiede il parametro exerciseObservation.aboutExercise.name, specificato dall'attributo android:required="true". In queste situazioni, l'assistente richiede di definire un intent di riserva per consentire alla richiesta di andare a buon fine, anche se nella query non vengono forniti parametri.
- In
shortcuts.xml, aggiungi un intent di riserva alla funzionalitàGET_EXERCISE_OBSERVATIONutilizzando questa configurazione:<!-- 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>
In questa configurazione di esempio, il fulfillment di fallback è un intent Android senza parametri nei dati Extra.
5. Attivare il widget per l'assistente
Una volta stabilita la funzionalità GET_EXERCISE_OBSERVATION, aggiorna la classe del widget per supportare l'invocazione vocale delle Azioni app.
Aggiungere la libreria dell'estensione Widget
La libreria di estensioni dei widget di Azioni app migliora i tuoi widget per le esperienze dell'assistente basate sulla voce. In particolare, ti consente di fornire un'introduzione TTS personalizzata per i tuoi widget.
- Aggiungi la dipendenza della libreria dell'estensione Widgets alla risorsa
/app/build.gradledell'app di esempio: Fai clic su Sincronizza ora nella casella di avviso visualizzata in Android Studio. La sincronizzazione dopo ogni modifica di// app/build.gradle dependencies { //... implementation "com.google.assistant.appactions:widgets:0.0.1" }build.gradleti aiuta a evitare errori durante la creazione dell'app.
Aggiungere il servizio widget
Un servizio è un componente dell'applicazione che può eseguire operazioni a lunga esecuzione in background. La tua app deve fornire un servizio per elaborare le richieste dei widget.
- Aggiungi un servizio alla risorsa
AndroidManifest.xmldell'app di esempio con questa configurazione:<!-- 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 query vocale che attiva il completamento del widget, l'assistente utilizza questo servizio per inviare richieste all'app. Il servizio riceve la richiesta insieme ai dati BII. Il servizio utilizza questi dati per generare un oggetto widget RemoteView da visualizzare all'interno dell'assistente.
Aggiornare la classe del widget
La tua app ora è configurata per indirizzare le richieste di funzionalità GET_EXERCISE_OBSERVATION alla classe del widget. Successivamente, aggiorna la classe StatsWidget.kt per generare un'istanza del widget personalizzata in base alla richiesta dell'utente, utilizzando i valori dei parametri dell'intent integrato.
- Apri la classe
StatsWidget.kte importa la libreria dell'estensione del widget Azioni app:// StatsWidget.kt // ... Other import statements import com.google.assistant.appactions.widgets.AppActionsWidgetExtension - Aggiungi queste variabili private, che utilizzi per determinare le informazioni da inserire nel widget:
// StatsWidget.kt private val hasBii: Boolean private val isFallbackIntent: Boolean private val aboutExerciseName: String private val exerciseType: FitActivity.Type - Aggiungi la funzione
initper consentire alla classe di utilizzare i dati delle opzioni del widget passati dall'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) }
Vediamo in che modo questi aggiornamenti consentono alla classe StatsWidget.kt di rispondere agli intent Android generati dalla funzionalità GET_EXERCISE_OBSERVATION:
optionsBundle= Bundle- I bundle sono oggetti destinati a essere utilizzati oltre i limiti del processo, tra attività con intent e per archiviare lo stato temporaneo tra le modifiche alla configurazione. L'assistente utilizza gli oggetti
Bundleper trasferire i dati di configurazione al widget.
- I bundle sono oggetti destinati a essere utilizzati oltre i limiti del processo, tra attività con intent e per archiviare lo stato temporaneo tra le modifiche alla configurazione. L'assistente utilizza gli oggetti
bii=actions.intent.GET_EXERCISE_OBSERVATION- Il nome dell'intent integrato è disponibile dal bundle utilizzando
AppActionsWidgetExtension.
- Il nome dell'intent integrato è disponibile dal bundle utilizzando
hasBii=true- Controlla se esiste un intent integrato.
params=Bundle[{aboutExerciseName=running}]- Un bundle speciale, generato da Azioni app, è nidificato all'interno delle opzioni del widget
Bundle. Contiene le coppie chiave/valore dell'intent integrato. In questo caso, il valorerunningè stato estratto dalla query di esempio "Hey Google, mostra le mie statistiche di corsa su ExampleApp".
- Un bundle speciale, generato da Azioni app, è nidificato all'interno delle opzioni del widget
isFallbackIntent=false- Verifica la presenza dei parametri BII obbligatori nell'intent
Extras.
- Verifica la presenza dei parametri BII obbligatori nell'intent
aboutExerciseName=running- Ottiene il valore dell'intent
ExtrasperaboutExerciseName.
- Ottiene il valore dell'intent
exerciseType=RUNNING- Utilizza
aboutExerciseNameper cercare l'oggetto del tipo di database corrispondente.
- Utilizza
Ora che la classe StatsWidget può elaborare i dati intent Android delle Azioni app in entrata, aggiorna la logica del flusso di creazione dei widget per verificare se il widget è stato attivato da un'Azione app.
- In
StatsWidget.kt, sostituisci la funzioneupdateAppWidget()con questo codice:// 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() }
Il codice precedente fa riferimento a una nuova funzione, observeAndUpdateRequestedExercise. Questa funzione genera i dati del widget utilizzando i dati del parametro exerciseType passati dall'intent Android Azioni app.
- Aggiungi la funzione
observeAndUpdateRequestedExercisecon questo codice:// 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() } } }
Nel codice precedente, utilizza una classe repository esistente trovata nell'app per recuperare i dati di fitness dal database locale dell'app. Questa classe fornisce un'API che semplifica l'accesso al database. Il repository funziona esponendo un oggetto LiveData durante l'esecuzione di query sul database. Nel codice osservi questo LiveData per recuperare l'ultima attività di fitness.
Abilitare la sintesi vocale
Puoi fornire una stringa TTS che l'assistente annuncerà quando visualizzerà il widget. Ti consigliamo di includerlo per fornire un contesto uditivo con i widget. Questa funzionalità è fornita dalla libreria di estensioni dei widget Azioni app, che ti consente di impostare il testo e le introduzioni TTS che accompagnano i widget nell'assistente.
Un buon punto per fornire l'introduzione TTS è la funzione formatDataAndSetWidget, che formatta i dati di attività restituiti dal database dell'app.
- In
StatsWidget.kt, aggiungi questo codice alla funzioneformatDataAndSetWidget:// 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) } }
Il codice precedente fa riferimento a due risorse stringa: una per il parlato e l'altra per il testo. Per consigli sulla sintesi vocale, guarda la sezione Consigli sullo stile di sintesi vocale del nostro video sui widget. L'esempio fa riferimento anche a setTts, una nuova funzione che fornisce le informazioni TTS all'istanza del widget.
- Aggiungi questa nuova funzione
setTtsaStatsWidget.ktutilizzando questo codice:// 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) }
Infine, completa la logica di sintesi vocale impostando le informazioni di sintesi vocale quando il database degli allenamenti restituisce dati vuoti per un tipo di allenamento richiesto.
- Aggiorna la funzione
setNoActivityDataWidget()inStatsWidget.ktcon questo codice:// 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. Testare l'Azione app
Durante lo sviluppo, utilizza il plug-in dell'Assistente Google per visualizzare l'anteprima delle Azioni app dell'assistente su un dispositivo di test. Puoi modificare i parametri di intent per un'Azione app con lo strumento per testare il modo in cui l'azione gestisce i vari modi in cui un utente potrebbe chiedere all'assistente di eseguirla.
Creare un'anteprima
Per testare l'Azione app con il plug-in:
- Vai a Strumenti > Assistente Google > Strumento di test delle Azioni app. Ti potrebbe essere chiesto di accedere ad Android Studio utilizzando il tuo Account Google.
- Fai clic su Crea anteprima. Se richiesto, leggi e accetta le norme e i termini di servizio di Azioni app.
Testare un tipo di allenamento previsto
Restituisci un widget che mostra informazioni sull'ultima corsa completata nell'app seguendo questi passaggi nello strumento di test:
- Nel primo passaggio in cui lo strumento ti chiede di selezionare e configurare un intent integrato, seleziona
actions.intent.GET_EXERCISE_OBSERVATION. - Nella casella exerciseObservation, aggiorna il nome dell'esercizio predefinito da
climbingarun. - Fai clic su Esegui azione app.

Testare un tipo di allenamento imprevisto
Per testare un tipo di esercizio imprevisto nello strumento di test:
- Nella casella exerciseObservation, aggiorna il valore
namedaRunaClimbing. - Fai clic su Esegui azione app.
L'assistente dovrebbe restituire un widget con il messaggio "Nessuna attività trovata".

Testa l'intent di riserva
Le query che attivano l'intent di riserva devono restituire un widget che mostra informazioni sull'ultima attività registrata di qualsiasi tipo di allenamento.
Per testare l'intent di riserva:
- Nella casella exerciseObservation, elimina l'oggetto
aboutExercise. - Fai clic su Esegui azione app.
L'assistente dovrebbe restituire un widget che mostra le informazioni sull'ultimo allenamento completato.

7. Passaggi successivi
Complimenti!
Ora puoi soddisfare le query degli utenti utilizzando un widget per Android con l'assistente.
Argomenti trattati
In questo codelab hai imparato a:
- Aggiungere un widget dell'app a un intent integrato.
- Modifica un widget per accedere ai parametri di Android Extras.
Passaggi successivi
Da qui, puoi provare a perfezionare ulteriormente la tua app per il fitness. Per fare riferimento al progetto completato, consulta il repository principale su GitHub.
Ecco alcuni suggerimenti per approfondire l'estensione di questa app con Azioni app:
- Visita il riferimento agli intent integrati di Azioni app per scoprire altri modi per estendere le tue app all'assistente.
Per continuare il tuo percorso con Azioni su Google, esplora queste risorse:
- developers.google.com/assistant/app: sito di documentazione ufficiale per le Azioni app dell'Assistente Google.
- Indice di esempio delle Azioni app: app ed esempi di codice per esplorare le funzionalità delle Azioni app.
- Repository GitHub di Azioni su Google: codice di esempio e librerie.
- r/GoogleAssistantDev: community ufficiale di Reddit per gli sviluppatori che lavorano con l'Assistente Google.
Seguici su Twitter @ActionsOnGoogle per rimanere al corrente sui nostri ultimi annunci e twitta con l'hashtag #appactions per condividere ciò che hai creato.
Sondaggio di feedback
Infine, compila questo sondaggio per fornire un feedback sulla tua esperienza con questo codelab.