Dynamische Verknüpfungen mit App Actions auf Google Assistant erweitern

1. Übersicht

Im vorherigen Codelab haben Sie statische Tastenkombinationen verwendet, um häufig verwendete integrierte Intents (integrierte Intents) in einer Beispiel-App zu implementieren. Android-Entwickler nutzen App Actions, um ihre App-Funktionen auf Google Assistant auszuweiten.

Statische Verknüpfungen sind mit einer App gebündelt und können nur aktualisiert werden, wenn neue Versionen der App veröffentlicht werden. Sprachfunktionen für dynamische Elemente wie von Nutzern erstellte Inhalte in einer App können über dynamische Verknüpfungen aktiviert werden. Apps senden dynamische Verknüpfungen, nachdem Nutzer relevante Aktionen ausgeführt haben, z. B. das Erstellen einer neuen Notiz in einer Aufgabenverfolgungs-App. Mit App Actions kannst du diese Verknüpfungen für Sprachbefehle aktivieren, indem du sie mit einem BII verknüpfst. So können Nutzer beispielsweise auf ihre Inhalte über Assistant zugreifen, indem sie sagen: „Hey Google, öffne meine Einkaufsliste in ExampleApp.“

Drei progressive Bildschirme, auf denen Google Assistant eine dynamische Verknüpfung startet.

Abbildung 1. Drei progressive Bildschirme, auf denen eine vom Nutzer erstellte Aufgabe zu sehen ist. Google Assistant startet eine dynamische Verknüpfung zu dieser Aufgabe.

Aufgaben

In diesem Codelab aktivieren Sie dynamische Kurzbefehle für die Spracheingabe in einer Beispiel-App für To-do-Listen in der Android-App, damit Nutzer Assistant bitten können, die von ihnen erstellten Aufgabenlisten in der App zu öffnen. Dazu verwenden Sie Android-Architekturmuster, insbesondere die Muster Repository, Service Locator und ViewModel.

Vorbereitung

Dieses Codelab basiert auf den App Actions-Konzepten, die im vorherigen Codelab behandelt wurden, insbesondere auf BIIs und statischen Tastenkombinationen. Wenn du noch nicht mit App Actions vertraut bist, empfehlen wir dir, dieses Codelab durchzuarbeiten, bevor du fortfährst.

Prüfen Sie außerdem, ob Ihre Entwicklungsumgebung die folgende Konfiguration hat, bevor Sie fortfahren:

  • Ein Terminal zum Ausführen von Shell-Befehlen mit installiertem Git.
  • Die neueste stabile Version von Android Studio.
  • Ein physisches oder virtuelles Android-Gerät mit Internetzugang
  • Ein Google-Konto, mit dem Sie in Android Studio, in der Google App und in der Google Assistant App angemeldet sind.

2. Funktionsweise

So aktivieren Sie eine dynamische Verknüpfung für den Sprachzugriff:

  • Eine dynamische Verknüpfung an einen zulässigen BII binden.
  • Assistant erlauben, die Verknüpfungen durch Hinzufügen der Google Shortcuts Integration Library aufzunehmen.
  • Senden einer Verknüpfung, sobald ein Nutzer die entsprechende In-App-Aufgabe ausführt.

Tastenkombinationen für Bindungen

Damit über Assistant auf eine dynamische Verknüpfung zugegriffen werden kann, muss sie an einen relevanten BII gebunden sein. Wenn ein BII mit einer Tastenkombination ausgelöst wird, gleicht Assistant Parameter in der Nutzeranfrage mit den Keywords ab, die in der gebundenen Verknüpfung definiert sind. Beispiel:

  • Über eine mit dem BII GET_THING verknüpfte Verknüpfung können Nutzer bestimmte In-App-Inhalte direkt über Assistant anfordern. * „Hey Google, öffne meine Einkaufsliste in ExampleApp.“
  • Über eine Verknüpfung, die mit dem BII ORDER_MENU_ITEM verknüpft ist, können Nutzer frühere Bestellungen noch einmal wiedergeben. * „Hey Google, bestelle meine Bestellung bei ExampleApp.“

Eine vollständige kategorisierte Liste der BIIs finden Sie in der Referenz zu integrierten Intents.

Verknüpfungen für Assistant bereitstellen

Nachdem Sie Ihre Verknüpfungen mit einem BII verknüpft haben, müssen Sie Assistant erlauben, diese Verknüpfungen aufzunehmen. Fügen Sie dazu Ihrem Projekt die Google Shortcuts Integration Library hinzu. Wenn diese Bibliothek vorhanden ist, erkennt Assistant jede Verknüpfung, die von deiner App ausgelöst wird. So können Nutzer diese über den entsprechenden Trigger in Assistant starten.

3. Bereiten Sie Ihre Entwicklungsumgebung vor

In diesem Codelab wird eine für Android entwickelte Beispiel-App für To-do-Listen verwendet. Mit dieser App können Nutzer Listen Elemente hinzufügen, Aufgaben in Aufgabenlisten nach Kategorie suchen und Aufgaben nach Erledigungsstatus filtern. Laden Sie die Beispiel-App herunter und bereiten Sie sie vor. Füllen Sie dazu diesen Abschnitt aus.

Basisdateien herunterladen

Führen Sie den folgenden Befehl aus, um das GitHub-Repository der Beispiel-App zu klonen:

git clone https://github.com/actions-on-google/app-actions-dynamic-shortcuts.git

Gehen Sie nach dem Klonen des Repositorys folgendermaßen vor, um es in Android Studio zu öffnen:

  1. Klicken Sie im Dialogfeld Welcome to Android Studio (Willkommen bei Android Studio) auf Import project (Projekt importieren).
  2. Wählen Sie den Ordner aus, in den Sie das Repository geklont haben.

Alternativ können Sie eine Version der Beispiel-App aufrufen, die das abgeschlossene Codelab darstellt. Klonen Sie dazu den codelab-complete-Zweig des GitHub-Repositorys:

git clone https://github.com/actions-on-google/app-actions-dynamic-shortcuts.git --branch codelab-complete

Android-App-ID aktualisieren

Durch die Aktualisierung der App-ID wird die App auf Ihrem Testgerät eindeutig identifiziert. „Doppelte Paketnamen“ werden vermieden. wenn die App in die Play Console hochgeladen wird. Öffnen Sie app/build.gradle, um die Anwendungs-ID zu aktualisieren:

android {
...
  defaultConfig {
    applicationId "com.MYUNIQUENAME.android.fitactions"
    ...
  }
}

Ersetzen Sie "MYUNIQUENAME". im Feld applicationId in ein für Sie einzigartiges Feld ein.

Shortcuts API-Abhängigkeiten hinzufügen

Fügen Sie der Ressourcendatei app/build.gradle die folgenden Jetpack-Bibliotheken hinzu:

app/build.gradle

dependencies {
   ...
   // Shortcuts library
   implementation "androidx.core:core:1.6.0"
   implementation 'androidx.core:core-google-shortcuts:1.0.1'
   ...
}

App auf dem Gerät testen

Bevor Sie weitere Änderungen an der App vornehmen, sollten Sie sich ein Bild davon machen, was die Beispiel-App leisten kann. So führen Sie die App in Ihrem Emulator aus:

  1. Wählen Sie in Android Studio Run > Führen Sie die App aus oder klicken Sie in der Symbolleiste auf AusführenApp-Symbol in Android Studio ausführen.
  2. Wählen Sie im Dialogfeld Select Deployment Target (Bereitstellungsziel auswählen) ein Gerät aus und klicken Sie auf OK. Wir empfehlen Android 10 (API-Level 30) oder höher. App Actions funktionieren jedoch auch auf Geräten ab Android 5 (API-Level 21).
  3. Halte die Startbildschirmtaste lange gedrückt, um Assistant einzurichten und zu prüfen, ob er funktioniert. Dazu musst du dich auf deinem Gerät in Assistant anmelden.

Weitere Informationen zu virtuellen Android-Geräten finden Sie unter Virtuelle Android-Geräte erstellen und verwalten.

Sehen Sie sich kurz die App an, um zu sehen, was sie alles kann. Wenn Sie auf das Plussymbol tippen, wird ein neues Aufgabenelement erstellt. Über die Menüpunkte oben rechts können Sie Aufgabenelemente suchen und nach dem Bearbeitungsstatus filtern.

4. Verknüpfungs-Repository-Klasse erstellen

Mehrere Klassen in unserer Beispiel-App rufen die ShortcutManagerCompat API auf, um dynamische Verknüpfungen zu übertragen und zu verwalten. Um Coderedundanz zu reduzieren, implementieren Sie ein Repository, damit Ihre Projektklassen dynamische Verknüpfungen einfach verwalten können.

Das Repository-Designmuster bietet eine saubere API zum Verwalten von Verknüpfungen. Der Vorteil eines Repositorys besteht darin, dass die Details der zugrunde liegenden API einheitlich hinter einer minimalen API abstrahiert werden. Implementieren Sie das Repository mithilfe der folgenden Schritte:

  1. Erstellen Sie eine ShortcutsRepository-Klasse, um die ShortcutManagerCompat API zu abstrahieren.
  2. Fügen Sie der Dienstsuche der App ShortcutsRepository-Methoden hinzu.
  3. Registrieren Sie den ShortcutRepository-Dienst in der Hauptanwendung.

Repository erstellen

Erstellen Sie im Paket com.example.android.architecture.blueprints.todoapp.data.source eine neue Kotlin-Klasse mit dem Namen ShortcutsRepository. Du findest dieses Paket im Ordner app/src/main/java. Mit dieser Klasse implementieren Sie eine Schnittstelle, die eine minimale Reihe von Methoden bietet, die unseren Codelab-Anwendungsfall abdecken.

Android Studio-Fenster, in dem der Speicherort der Klasse „ShortcutsRepository“ angezeigt wird.

Abbildung 2: Android Studio-Fenster „Project Files“ mit dem Speicherort der ShortcutsRepository-Klasse.

Fügen Sie den folgenden Code in die neue Klasse ein:

package com.example.android.architecture.blueprints.todoapp.data.source

import android.content.Context
import android.content.Intent
import androidx.annotation.WorkerThread
import androidx.core.content.pm.ShortcutInfoCompat
import androidx.core.content.pm.ShortcutManagerCompat
import com.example.android.architecture.blueprints.todoapp.data.Task
import com.example.android.architecture.blueprints.todoapp.tasks.TasksActivity

private const val GET_THING_KEY = "q"

/**
* ShortcutsRepository provides an interface for managing dynamic shortcuts.
*/
class ShortcutsRepository(val context: Context) {

   private val appContext = context.applicationContext

   /**
    * Pushes a dynamic shortcut. The task ID is used as the shortcut ID.
    * The task's title and description are used as shortcut's short and long labels.
    * The resulting shortcut corresponds to the GET_THING capability with task's
    * title used as BII's "name" argument.
    *
    * @param task Task object for which to create a shortcut.
    */
   @WorkerThread
   fun pushShortcut(task: Task) {
      // TODO
   }

   private fun createShortcutCompat(task: Task): ShortcutInfoCompat {
      //...
   }

   /**
    *  Updates a dynamic shortcut for the provided task. If the shortcut
    *  associated with this task doesn't exist, this method throws an error.
    *  This operation may take a few seconds to complete.
    *
    * @param tasks list of tasks to update.
    */
   @WorkerThread
   fun updateShortcuts(tasks: List<Task>) {
       //...
   }

   /**
    * Removes shortcuts if IDs are known.
    *
    * @param ids list of shortcut IDs
    */
   @WorkerThread
   fun removeShortcutsById(ids: List<String>) {
       //...
   }

   /**
    * Removes shortcuts associated with the tasks.
    *
    * @param tasks list of tasks to remove.
    */
   @WorkerThread
   fun removeShortcuts(tasks: List<Task>) {
       //...
   }
}

Aktualisieren Sie als Nächstes die Methode pushShortcut, um die ShortcutManagerCompat API aufzurufen. Aktualisieren Sie die Klasse ShortcutsRepository mit dem folgenden Code:

ShortcutsRepository.kt

/**
* Pushes a dynamic shortcut for the task. The task's ID is used as a shortcut
* ID. The task's title and description are used as shortcut's short and long
* labels. The created shortcut corresponds to GET_THING capability with task's
* title used as BII's "name" argument.
*
* @param task Task object for which to create a shortcut.
*/


@WorkerThread
fun pushShortcut(task: Task) {
   ShortcutManagerCompat.pushDynamicShortcut(appContext, createShortcutCompat(task))
}

Im vorherigen Codebeispiel wurde appContext an die API übergeben. Dies ist eine Klasseneigenschaft, die einen Anwendungskontext enthält. Es ist wichtig, einen Anwendungskontext und nicht einen Aktivitätskontext zu verwenden, um Speicherlecks zu vermeiden, da der Kontext möglicherweise länger aufbewahrt wird als der Lebenszyklus der Hostaktivität.

Außerdem muss bei der API ein ShortcutInfoCompat-Objekt für das Task-Objekt übergeben werden. Im vorherigen Codebeispiel wird dies durch Aufrufen der privaten Methode createShortcutCompat erreicht, die wir aktualisieren, um ein ShortcutInfoCompat-Objekt zu erstellen und zurückzugeben. Aktualisieren Sie dazu den Stub createShortcutCompat mit dem folgenden Code:

ShortcutsRepository.kt

private fun createShortcutCompat(task: Task): ShortcutInfoCompat {
   val intent = Intent(appContext, TasksActivity::class.java)
   intent.action = Intent.ACTION_VIEW
   // Filtering is set based on currentTitle.
   intent.putExtra(GET_THING_KEY, task.title)

   // A unique ID is required to avoid overwriting an existing shortcut.
   return ShortcutInfoCompat.Builder(appContext, task.id)
           .setShortLabel(task.title)
           .setLongLabel(task.title)
           // Call addCapabilityBinding() to link this shortcut to a BII. Enables user to invoke a shortcut using its title in Assistant.
           .addCapabilityBinding(
                   "actions.intent.GET_THING", "thing.name", listOf(task.title))
           .setIntent(intent)
           .setLongLived(false)
       .build()
}

Bei den verbleibenden Funktions-Stubs in dieser Klasse geht es um das Aktualisieren und Löschen dynamischer Tastenkombinationen. Aktivieren Sie diese Funktionen, indem Sie sie mit dem folgenden Code aktualisieren:

ShortcutsRepository.kt

/**
* Updates a Dynamic Shortcut for the task. If the shortcut associated with this task
* doesn't exist, throws an error. This operation may take a few seconds to complete.
*
* @param tasks list of tasks to update.
*/
@WorkerThread
fun updateShortcuts(tasks: List<Task>) {
   val scs = tasks.map { createShortcutCompat(it) }
   ShortcutManagerCompat.updateShortcuts(appContext, scs)
}

/**
* Removes shortcuts if IDs are known.
* @param ids list of shortcut IDs
*/
@WorkerThread
fun removeShortcutsById(ids: List<String>) {
   ShortcutManagerCompat.removeDynamicShortcuts(appContext, ids)
}

/**
* Removes shortcuts associated with the tasks.
*
* @param tasks list of tasks to remove.
*/
@WorkerThread
fun removeShortcuts(tasks: List<Task>) {
   ShortcutManagerCompat.removeDynamicShortcuts (appContext,
           tasks.map { it.id })
}

Klasse zu Service Locator hinzufügen

Nachdem die Klasse ShortcutsRepository erstellt wurde, besteht der nächste Schritt darin, instanziierte Objekte dieser Klasse für den Rest der App verfügbar zu machen. Diese Anwendung verwaltet Klassenabhängigkeiten, indem sie das Muster Service Locator implementiert. Öffnen Sie die Service Locator-Klasse im Kursbrowser in Android Studio. Klicken Sie dazu auf Navigation > Class und geben Sie "ServiceLocator" ein. Klicken Sie auf die resultierende Kotlin-Datei, um sie in Ihrer IDE zu öffnen.

Fügen Sie oben in ServiceLocator.kt den folgenden Code ein, um die Pakete ShortcutsRepository und SuppressLint zu importieren:

ServiceLocator.kt

package com.example.android.architecture.blueprints.todoapp

// ...Other import statements
import com.example.android.architecture.blueprints.todoapp.data.source.ShortcutsRepository
import android.annotation.SuppressLint

Fügen Sie die ShortcutRepository-Dienstmitglieder und -Methoden hinzu, indem Sie den folgenden Code in den Text von ServiceLocator.kt einfügen:

ServiceLocator.kt

object ServiceLocator {

   // ...
   // Only the code immediately below this comment needs to be copied and pasted
   // into the body of ServiceLocator.kt:

   @SuppressLint("StaticFieldLeak")
   @Volatile
   var shortcutsRepository: ShortcutsRepository? = null


   private fun createShortcutsRepository(context: Context): ShortcutsRepository {
       val newRepo = ShortcutsRepository(context.applicationContext)
       shortcutsRepository = newRepo
       return newRepo
   }

   fun provideShortcutsRepository(context: Context): ShortcutsRepository {
       synchronized(this) {
           return shortcutsRepository ?: shortcutsRepository ?: createShortcutsRepository(context)
       }
   }
 }

Verknüpfungsdienst registrieren

Im letzten Schritt registrieren Sie den neuen ShortcutsRepository-Dienst bei der Anwendung. Öffnen Sie TodoApplication.kt in Android Studio und kopieren Sie den folgenden Code am Anfang der Datei:

TodoApplication.kt

package com.example.android.architecture.blueprints.todoapp
/// ... Other import statements

import com.example.android.architecture.blueprints.todoapp.data.source.ShortcutsRepository

Registrieren Sie als Nächstes den Dienst, indem Sie den folgenden Code in den Hauptteil der Klasse einfügen:

TodoApplication.kt

//...
class TodoApplication : Application() {

   //...

   val shortcutsRepository: ShortcutsRepository
       get() = ServiceLocator.provideShortcutsRepository(this)

   //...
}

Erstellen Sie die App und stellen Sie sicher, dass sie weiterhin ausgeführt wird.

5. Neue Verknüpfung per Push-Befehl senden

Nachdem Sie den Shortcut-Dienst erstellt haben, können Sie Verknüpfungen erstellen. Da Nutzer Inhalte (Aufgabenelemente) in dieser App generieren und erwarten, später zu ihnen zurückkehren zu können, wird jedes Mal, wenn ein Nutzer eine neue Aufgabe erstellt, eine dynamische Verknüpfung gesendet, die an den BII GET_THING gebunden ist, um den Zugriff auf diese Inhalte per Spracheingabe zu ermöglichen. So kann Assistant Nutzer direkt zur gewünschten Aufgabe weiterleiten, wenn sie den BII auslösen, indem sie beispielsweise Folgendes fragen: „Hey Google, öffne meine Einkaufsliste in SampleApp.“

So aktivieren Sie diese Funktion in der Beispiel-App:

  1. ShortcutsRepository-Dienst in die AddEditTaskViewModel-Klasse importieren, der für die Verwaltung von Aufgabenlistenobjekten zuständig ist
  2. Dynamische Verknüpfung senden, wenn der Nutzer eine neue Aufgabe erstellt.

ShortcutsRepository importieren

Zuerst muss der ShortcutsRepository-Dienst für AddEditTaskViewModel verfügbar gemacht werden. Importieren Sie dazu den Dienst in ViewModelFactory, die Factory-Klasse, mit der die App ViewModel-Objekte instanziiert, einschließlich AddEditTaskViewModel.

Öffnen Sie in Android Studio den Kursbrowser, indem Sie auf Navigation > klicken. Class und geben "ViewModelFactory" ein. Klicken Sie auf die resultierende Kotlin-Datei, um sie in Ihrer IDE zu öffnen.

Fügen Sie oben in ViewModelFactory.kt den folgenden Code ein, um die Pakete ShortcutsRepository und SuppressLint zu importieren:

ViewModelFactory.kt

package com.example.android.architecture.blueprints.todoapp

// ...Other import statements
import com.example.android.architecture.blueprints.todoapp.data.source.ShortcutsRepository

Ersetzen Sie als Nächstes den Text von ViewModelFactory durch den folgenden Code:

ViewModelFactory.kt

/**
 * Factory for all ViewModels.
 */
@Suppress("UNCHECKED_CAST")
class ViewModelFactory constructor(
    private val tasksRepository: TasksRepository,
    private val shortcutsRepository: ShortcutsRepository,
    owner: SavedStateRegistryOwner,
    defaultArgs: Bundle? = null
) : AbstractSavedStateViewModelFactory(owner, defaultArgs) {

    override fun <T : ViewModel> create(
        key: String,
        modelClass: Class<T>,
        handle: SavedStateHandle
    ) = with(modelClass) {
        when {
            isAssignableFrom(StatisticsViewModel::class.java) ->
                StatisticsViewModel(tasksRepository)
            isAssignableFrom(TaskDetailViewModel::class.java) ->
                TaskDetailViewModel(tasksRepository)
            isAssignableFrom(AddEditTaskViewModel::class.java) ->
                AddEditTaskViewModel(tasksRepository, shortcutsRepository)
            isAssignableFrom(TasksViewModel::class.java) ->
                TasksViewModel(tasksRepository, handle)
            else ->
                throw IllegalArgumentException("Unknown ViewModel class: ${modelClass.name}")
        }
    } as T
}

Schließen Sie die ViewModelFactory-Änderungen ab, indem Sie eine Ebene nach oben wechseln und ShortcutsRepository an den Factory-Konstruktor übergeben. Öffnen Sie den Dateibrowser von Android Studio. Wählen Sie dazu Navigieren > Datei und geben Sie „FragmentExt.kt“ ein. Klicken Sie auf die resultierende Kotlin-Datei im util-Paket, um sie in Ihrer IDE zu öffnen.

Ersetzen Sie den Text von FragmentExt.kt durch den folgenden Code:

fun Fragment.getViewModelFactory(): ViewModelFactory {
   val taskRepository = (requireContext().applicationContext as TodoApplication).taskRepository
   val shortcutsRepository = (requireContext().applicationContext as TodoApplication).shortcutsRepository
   return ViewModelFactory(taskRepository, shortcutsRepository, this)
}

Tastenkombination drücken

Wenn die Abstraktionsklasse ShortcutsRepository für die ViewModel-Klassen der Beispiel-App verfügbar ist, aktualisieren Sie die Klasse AddEditTaskViewModel, die für das Erstellen von Notizen verantwortlich ist, so, dass jedes Mal, wenn ein Nutzer eine neue Notiz erstellt, eine dynamische Verknüpfung gesendet wird.ViewModel

Öffnen Sie in Android Studio den Klassenbrowser und geben Sie „AddEditTaskViewModel“ ein. Klicken Sie auf die resultierende Kotlin-Datei, um sie in Ihrer IDE zu öffnen.

Fügen Sie dieser Klasse zuerst das Paket ShortcutsRepository mit der folgenden Importanweisung hinzu:

package com.example.android.architecture.blueprints.todoapp.addedittask

//Other import statements
import com.example.android.architecture.blueprints.todoapp.data.source.ShortcutsRepository

Fügen Sie als Nächstes das Klassenattribut shortcutsRepository hinzu, indem Sie den Klassenkonstruktor mit dem folgenden Code aktualisieren:

AddEditTaskViewModel.kt

//...

/**
* ViewModel for the Add/Edit screen.
*/
class AddEditTaskViewModel(
   private val tasksRepository: TasksRepository,
   private val shortcutsRepository: ShortcutsRepository
) : ViewModel() {

    //...

Erstellen Sie mit der hinzugefügten Klasse ShortcutsRepository die neue Funktion pushShortcut(), um diese Klasse aufzurufen. Fügen Sie die folgende private Funktion in den Text von AddEditTaskViewModel ein:

AddEditTaskViewModel.kt

//...
private fun pushShortcut(newTask: Task) = viewModelScope.launch {
   shortcutsRepository.pushShortcut(newTask)
}

Schließlich können Sie bei jeder Erstellung einer Aufgabe eine neue dynamische Tastenkombination bereitstellen. Ersetzen Sie den Inhalt der Funktion saveTask() durch den folgenden Code:

AddEditTaskViewModel.kt

fun saveTask() {
    val currentTitle = title.value
    val currentDescription = description.value

    if (currentTitle == null || currentDescription == null) {
        _snackbarText.value = Event(R.string.empty_task_message)
        return
    }
    if (Task(currentTitle, currentDescription).isEmpty) {
        _snackbarText.value = Event(R.string.empty_task_message)
        return
    }

    val currentTaskId = taskId
    if (isNewTask || currentTaskId == null) {
        val task = Task(currentTitle, currentDescription)
        createTask(task)
        pushShortcut(task)
    } else {
        val task = Task(currentTitle, currentDescription, taskCompleted, currentTaskId)
        updateTask(task)
    }
}

Code testen

Endlich können wir unseren Code testen! In diesem Schritt senden Sie eine dynamische Verknüpfung mit Sprachsteuerung und prüfen sie mit der Google Assistant App.

Vorschau erstellen

Wenn Sie eine Vorschau mit dem Google Assistant-Plug-in erstellen, werden Ihre dynamischen Verknüpfungen in Assistant auf Ihrem Testgerät angezeigt.

Test-Plug-in installieren

Wenn Sie das Google Assistant-Plug-in noch nicht haben, installieren Sie es mithilfe der folgenden Schritte in Android Studio:

  1. Gehen Sie zu **Datei > Rufen Sie unter macOS „Android Studio“ > „Einstellungen“ auf.
  2. Rufen Sie im Abschnitt Plug-ins den Marketplace auf und suchen Sie nach „Google Assistant“.
  3. Installieren Sie das Tool und starten Sie Android Studio neu.

Vorschau erstellen

So erstellen Sie eine Vorschau in Android Studio:

  1. Klicken Sie auf Tools > Google Assistant > App Actions-Testtool
  2. Geben Sie im Feld App-Name einen Namen ein, z. B. „Aufgabenliste“.
  3. Klicken Sie auf Vorschau erstellen. Wenn du dazu aufgefordert wirst, lies und akzeptiere die Richtlinien und Nutzungsbedingungen für App Actions.

Vorschaubereich für das App Actions-Testtool.

Abbildung 3: Vorschaubereich des App Actions-Testtools.

Während des Tests werden dynamische Verknüpfungen, die Sie an Assistant senden, in Assistant nach dem App-Namen sortiert angezeigt, den Sie für die Vorschau angegeben haben.

Verknüpfung per Push übertragen und prüfen

Starten Sie die Beispiel-App auf Ihrem Testgerät neu und führen Sie die folgenden Schritte aus :

  1. Erstelle eine neue Aufgabe mit dem Titel „Codelab starten“
  2. Öffne die Google Assistant App und sag „Meine Verknüpfungen“ oder gib es ein.
  3. Tippe auf den Tab Entdecken. Sie sollten die Beispiel-Verknüpfung sehen.
  4. Tippe auf den Kurzbefehl, um ihn zu starten. Beim Starten der App sollte der Name der Verknüpfung im Filterfeld bereits eingetragen sein, damit Sie die gewünschte Aufgabe einfach finden können.

6. Optional: Verknüpfung aktualisieren und löschen

Ihre App kann nicht nur neue dynamische Verknüpfungen zur Laufzeit bereitstellen, sondern sie auch an den aktuellen Status Ihrer Nutzerinhalte und -einstellungen aktualisieren. Es empfiehlt sich, vorhandene Verknüpfungen jedes Mal zu aktualisieren, wenn ein Nutzer das Zielelement ändert, z. B. eine Aufgabe in unserer Beispiel-App umbenennen. Sie sollten auch eine entsprechende Verknüpfung löschen, wenn die Zielressource entfernt wird, damit dem Nutzer keine fehlerhaften Verknüpfungen angezeigt werden.

Verknüpfung aktualisieren

Sie können „AddEditTaskViewModel“ so ändern, dass eine dynamische Verknüpfung immer dann aktualisiert wird, wenn ein Nutzer die Details eines Aufgabenelements ändert. Aktualisieren Sie zuerst den Hauptteil der Klasse mit dem folgenden Code, um eine Aktualisierungsfunktion hinzuzufügen, die unsere Repository-Klasse verwendet:

AddEditTaskViewModel.kt

private fun updateShortcut(newTask: Task) = viewModelScope.launch {
   shortcutsRepository.updateShortcuts(listOf(newTask))
}

Ändern Sie nun die saveTask()-Funktion so, dass unsere neue Methode aufgerufen wird, wenn eine vorhandene Aufgabe aktualisiert wird.

AddEditTaskViewModel.kt

// Called when clicking on fab.
fun saveTask() {
   // ...
   // Note: the shortcuts are created/updated in a worker thread.
   if (isNewTask || currentTaskId == null) {
       //...
   } else {
       //...
       updateShortcut(task)
   }
}

Testen Sie Ihren Code, indem Sie die App neu starten und folgende Schritte ausführen:

  1. Benennen Sie den Titel des vorhandenen Aufgabenelements in „Codelab fertigstellen“ um.
  2. Öffne Google Assistant, indem du „Hey Google, meine Verknüpfungen“ sagst.
  3. Tippe auf den Tab Entdecken. Sie sollten ein aktualisiertes Kurzlabel für Ihre Testverknüpfung sehen.

Verknüpfung entfernen

Unsere Beispiel-App-Verknüpfungen sollten entfernt werden, wenn ein Nutzer eine Aufgabe löscht. In der Beispiel-App befindet sich die Logik für das Löschen von Aufgaben in der Klasse TaskDetailViewModel. Bevor wir diesen Kurs aktualisieren, müssen wir ViewModelFactory noch einmal aktualisieren, um shortcutsRepository an TaskDetailViewModel zu übergeben.

Öffnen Sie ViewModelFactory und ersetzen Sie den Inhalt der zugehörigen Konstruktormethode durch den folgenden Code:

//...
class ViewModelFactory constructor(
       private val tasksRepository: TasksRepository,
       private val shortcutsRepository: ShortcutsRepository,
       owner: SavedStateRegistryOwner,
       defaultArgs: Bundle? = null
) : AbstractSavedStateViewModelFactory(owner, defaultArgs) {

   override fun <T : ViewModel> create(
           key: String,
           modelClass: Class<T>,
           handle: SavedStateHandle
   ) = with(modelClass) {
       when {
           isAssignableFrom(StatisticsViewModel::class.java) ->
               StatisticsViewModel(tasksRepository)
           isAssignableFrom(TaskDetailViewModel::class.java) ->
               TaskDetailViewModel(tasksRepository, shortcutsRepository)
           isAssignableFrom(AddEditTaskViewModel::class.java) ->
               AddEditTaskViewModel(tasksRepository, shortcutsRepository)
           isAssignableFrom(TasksViewModel::class.java) ->
               TasksViewModel(tasksRepository, handle)
           else ->
               throw IllegalArgumentException("Unknown ViewModel class: ${modelClass.name}")
       }
   } as T
}

Öffnen Sie als Nächstes TaskDetailViewModel. Importieren Sie das Modul ShortcutsRepository und deklarieren Sie es mit dem folgenden Code:

TaskDetailViewModel.kt

package com.example.android.architecture.blueprints.todoapp.taskdetail

...
import com.example.android.architecture.blueprints.todoapp.data.source.ShortcutsRepository


/**
* ViewModel for the Details screen.
*/
class TaskDetailViewModel(
       //...
       private val shortcutsRepository: ShortcutsRepository
   ) : ViewModel() {
...
}

Ändern Sie schließlich die Funktion deleteTask() so, dass shortcutsRepository aufgerufen wird, um eine Verknüpfung basierend auf ihrer ID zu entfernen, wenn eine Aufgabe mit einer entsprechenden taskId gelöscht wird:

TaskDetailViewModel.kt

fun deleteTask() = viewModelScope.launch {
   _taskId.value?.let {
       //...
       shortcutsRepository.removeShortcutsById(listOf(it))
   }
}

Starten Sie die App neu und führen Sie die folgenden Schritte aus, um den Code zu testen:

  1. Löschen Sie die Testaufgabe.
  2. Benennen Sie den Titel des vorhandenen Aufgabenelements in „Codelab fertigstellen“ um.
  3. Öffne Google Assistant, indem du „Hey Google, meine Verknüpfungen“ sagst.
  4. Tippe auf den Tab Entdecken. Vergewissern Sie sich, dass die Testverknüpfung nicht mehr angezeigt wird.

7. Nächste Schritte

Glückwunsch! Dank Ihnen können Nutzer unserer Beispiel-App ganz einfach zu ihren Notizen zurückkehren, indem sie Assistant Dinge wie „Hey Google, öffne meine Einkaufsliste in ExampleApp“ sagen. Verknüpfungen fördern das Nutzer-Engagement, da sie es den Nutzern leicht machen, häufig verwendete Aktionen in Ihrer App nachzuspielen.

Behandelte Themen

In diesem Codelab haben Sie gelernt, wie Sie:

  • Identifizieren Sie Anwendungsfälle für die Übermittlung dynamischer Verknüpfungen in einer App.
  • Reduzieren Sie die Codekomplexität mithilfe von Repository, Abhängigkeitsinjektion und Designmustern für die Dienstsuche.
  • Sende sprachgesteuerte dynamische Verknüpfungen zu von Nutzern erstellten App-Inhalten.
  • Vorhandene Verknüpfungen aktualisieren und entfernen.

Nächste Schritte

Von hier aus können Sie weitere Optimierungen an Ihrer Aufgabenlisten-App vornehmen. Informationen zum abgeschlossenen Projekt finden Sie im Repository-Abschnitt –codelab-complete branch auf GitHub.

Hier sind einige Vorschläge, wie du diese App mit App Actions erweitern kannst:

Wenn Sie Actions on Google weiter nutzen möchten, sollten Sie sich die folgenden Ressourcen ansehen:

Folge uns auf Twitter (@ActionsOnGoogle), um dich über unsere neuesten Ankündigungen zu informieren, und twittere unter #appActions, was du entwickelt hast.

Feedback-Umfrage

Bitte nimm abschließend an dieser Umfrage teil, um uns Feedback zu deinen Erfahrungen mit diesem Codelab zu geben.