Rozszerzaj dynamiczne skróty do Asystenta Google za pomocą działań w aplikacji

Rozszerzaj dynamiczne skróty do Asystenta Google za pomocą działań w aplikacji

Informacje o tym ćwiczeniu (w Codelabs)

subjectOstatnia aktualizacja: wrz 12, 2024
account_circleAutorzy: Google Assistant Developer Relations

1. Omówienie

poprzednim ćwiczeniu Codelab używaliśmy skrótów statycznych do implementowania w przykładowej aplikacji często używanych wbudowanych intencji. Deweloperzy Androida używają działań aplikacji, aby rozszerzać funkcjonalność aplikacji o Asystenta Google.

Skróty statyczne są połączone z aplikacją i można je aktualizować tylko po opublikowaniu nowych wersji aplikacji. W przypadku elementów dynamicznych w aplikacji, takich jak treści użytkowników, funkcje głosowe można włączyć za pomocą skrótów dynamicznych. Aplikacje przekazują dynamiczne skróty po wykonaniu przez użytkownika odpowiednich działań, np. utworzeniu nowej notatki w aplikacji do śledzenia zadań. Akcje w aplikacji umożliwiają włączanie poleceń głosowych w tych skrótach. Aby umożliwić użytkownikom dostęp do treści z pomocy Asystenta, wystarczy, że powiesz na przykład „OK Google, otwórz moją listę zakupów w ExampleApp”.

3 ekrany progresywne pokazujące Asystenta Google uruchamiającego dynamiczny skrót.

Rysunek 1. Trzy ekrany pokazujące zadanie utworzone przez użytkownika i Asystenta Google uruchamiającego dynamiczny skrót do tego zadania

Co utworzysz

W tym laboratorium programistycznym włączysz dynamiczne skróty głosowe w przykładowej aplikacji na Androida do tworzenia listy zadań. Dzięki temu użytkownicy będą mogli prosić Asystenta o otwieranie elementów listy zadań utworzonych w aplikacji. Aby to zrobić, użyjesz wzorów architektury Androida, w szczególności wzorów repozytorium, lokalizatora usługiViewModel.

Wymagania wstępne

To ćwiczenie w Codelabs opiera się na pojęciach związanych z działaniami w aplikacji omówionymi w poprzednim ćwiczeniu z programowania, w szczególności o BII i statycznych skrótach. Jeśli nie masz doświadczenia z aplikowanymi działaniami, przed kontynuowaniem zalecamy ukończenie tego laboratorium kodu.

Zanim przejdziesz dalej, upewnij się, że środowisko programistyczne ma następującą konfigurację:

  • terminal do uruchamiania poleceń powłoki z zainstalowanym gitem;
  • najnowsza stabilna wersja Android Studio.
  • Fizyczne lub wirtualne urządzenie z Androidem z dostępem do internetu.
  • konto Google zalogowane w Android Studio, aplikacji Google i aplikacji Asystent Google;

2. Jak to działa

Aby włączyć dynamiczny skrót dostępu głosowego, wykonaj te czynności:

  • Powiązanie dynamicznego skrótu z odpowiednim kluczem BII.
  • Włączanie Asystenta do przetwarzania skrótów przez dodanie biblioteki integracji skrótów Google.
  • Wypchnięcie skrótu za każdym razem, gdy użytkownik wykona odpowiednie zadanie w aplikacji.

Skróty powiązań

Aby skrót dynamiczny był dostępny z poziomu Asystenta, musi być powiązany z odpowiednim BII. Po wywołaniu funkcji BII ze skrótem Asystent dopasowuje parametry w żądaniu użytkownika do słów kluczowych zdefiniowanych w powiązanym skrócie. Na przykład:

  • Skrót powiązany z blokiem dostępu do GET_THING BII może umożliwiać użytkownikom wysyłanie próśb o dostęp do określonych treści w aplikacji bezpośrednio z poziomu Asystenta. * „OK Google, otwórz moją listę zakupów w aplikacji ExampleApp”
  • Skrót powiązany z START_EXERCISE BII pozwala użytkownikom wyświetlać sesje ćwiczeń. * „OK Google, poproś ExampleApp o rozpoczęcie zwykłego ćwiczenia”

Pełną listę kategorii BIIs znajdziesz w dokumentacji dotyczącej wbudowanych intencji.

Udostępniam skróty do Asystenta

Po powiązaniu skrótów z interfejsem BII należy umożliwić Asystentowi przetwarzanie tych skrótów. W tym celu dodaj do projektu bibliotekę integracji skrótów Google. Dzięki tej bibliotece Asystent będzie wiedzieć o każdym skrótach przesłanym przez Twoją aplikację, co umożliwi użytkownikom uruchamianie tych skrótów za pomocą odpowiedniego słowa-klucza w Asystencie.

3. Przygotowanie środowiska programistycznego

W tym ćwiczeniu używamy przykładowej aplikacji do listy zadań utworzonej na Androida. Dzięki tej aplikacji użytkownicy mogą dodawać elementy do list, wyszukiwać elementy listy zadań według kategorii i filtrować zadania według stanu ukończenia. Pobierz i przygotuj przykładową aplikację, wykonując czynności opisane w tej sekcji.

Pobieranie plików podstawowych

Aby skopiować przykładowe repozytorium GitHub, uruchom to polecenie:

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

Po sklonowaniu repozytorium wykonaj te czynności, aby otworzyć je w Android Studio:

  1. W oknie Welcome to Android Studio (Witamy w Android Studio) kliknij Import project (Importuj projekt).
  2. Wybierz folder, do którego sklonowano repozytorium.

Możesz też wyświetlić wersję przykładowej aplikacji reprezentującej ukończone ćwiczenia z programowania, sklonując gałąź codelab-complete swojego repozytorium GitHub:

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

Aktualizowanie identyfikatora aplikacji na Androida

Aktualizowanie identyfikatora aplikacji jednoznacznie identyfikuje aplikację na urządzeniu testowym i unika „zduplikowanej nazwy pakietu”. występuje wtedy, gdy aplikacja została przesłana do Konsoli Play. Aby zaktualizować identyfikator aplikacji, otwórz app/build.gradle:

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

Zastąp „MYUNIQUENAME” w polu applicationId.

Dodawanie zależności interfejsu Shortcuts API

Dodaj te biblioteki Jetpack do pliku zasobów app/build.gradle:

app/build.gradle

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

Testowanie aplikacji na urządzeniu

Zanim wprowadzisz dalsze zmiany w aplikacji, warto zapoznać się z jej możliwościami. Aby uruchomić aplikację na emulatorze, wykonaj te czynności:

  1. W Android Studio wybierz Uruchom > Uruchom aplikację lub kliknij UruchomIkona aplikacji z Androidem Studio na pasku narzędzi.
  2. W oknie Wybierz cel wdrożenia wybierz urządzenie i kliknij OK. Zalecana wersja systemu operacyjnego to Android 10 (poziom interfejsu API 30) lub nowszy, chociaż akcje w aplikacji działają już na urządzeniach z Androidem 5 (poziom interfejsu API 21).
  3. Przytrzymaj przycisk ekranu głównego, aby skonfigurować Asystenta i sprawdzić, czy działa. Jeśli jeszcze tego nie zrobisz, musisz zalogować się w Asystencie na urządzeniu.

Więcej informacji o urządzeniach wirtualnych z Androidem znajdziesz w artykule Tworzenie urządzeń wirtualnych i zarządzanie nimi.

Omów krótko aplikację, aby poznać jej możliwości. Kliknięcie ikony plusa powoduje utworzenie nowego zadania. Elementy menu w prawym górnym rogu umożliwiają wyszukiwanie i filtrowanie elementów zadania według stanu ukończenia.

4. Tworzenie klasy repozytorium skrótów

Kilka klas w naszej przykładowej aplikacji będzie wywoływać interfejs API ShortcutManagerCompat, aby przesyłać dynamiczne skróty i nimi zarządzać. Aby ograniczyć nadmiarowość kodu, wdrożysz repozytorium, które umożliwi klasom projektu łatwe zarządzanie dynamicznymi skrótami.

Wzór repozytorium udostępnia przejrzysty interfejs API do zarządzania skrótami. Zaletą repozytorium jest to, że szczegóły bazowego interfejsu API są równomiernie wyodrębniane za pomocą minimalnego interfejsu API. Aby wdrożyć repozytorium, wykonaj te czynności:

  1. Utwórz klasę ShortcutsRepository, aby zastąpić abstrakcyjnie interfejs API ShortcutManagerCompat.
  2. Dodaj metody ShortcutsRepository do lokalizatora usług aplikacji.
  3. Zarejestruj usługę ShortcutRepository w głównej aplikacji.

Tworzenie repozytorium

Utwórz nową klasę Kotlin o nazwie ShortcutsRepository w pakiecie com.example.android.architecture.blueprints.todoapp.data.source. Znajdziesz ten pakiet w folderze app/src/main/java. Wykorzystasz tę klasę do wdrożenia interfejsu zapewniającego minimalny zestaw metod obejmujących nasz przypadek użycia.

Okno Android Studio z lokalizacją klasy ShortcutsRepository

Rysunek 2. Okno Pliki projektu w Android Studio wyświetlające lokalizację klasy ShortcutsRepository.

Wklej ten kod do nowych zajęć:

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>) {
       
//...
   
}
}

Następnie zaktualizuj metodę pushShortcut tak, aby wywoływała interfejs API ShortcutManagerCompat. Zaktualizuj klasę ShortcutsRepository za pomocą tego kodu:

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))
}

W poprzednim przykładzie kodu przekazaliśmy do interfejsu API wartość appContext. To jest właściwość klasy zawierająca kontekst aplikacji. Aby uniknąć wycieków pamięci, używaj kontekstu aplikacji (a nie kontekstu aktywności), ponieważ kontekst może być przechowywany dłużej niż czas trwania aktywności hosta.

Dodatkowo interfejs API wymaga, aby obiekt Task był przekazywany jako obiekt ShortcutInfoCompat. W poprzednim przykładzie kodu robimy to, wywołując prywatną metodę createShortcutCompat, którą zaktualizujemy, aby tworzyć i zwracać obiekt ShortcutInfoCompat. W tym celu zaktualizuj fragment kodu createShortcutCompat za pomocą tego kodu:

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()
}

Pozostałe szablony funkcji w tej klasie dotyczą aktualizowania i usuwania dynamicznych skrótów. Włącz te funkcje, dodając do nich ten kod:

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 })
}

Dodawanie klasy do lokalizatora usług

Po utworzeniu klasy ShortcutsRepository kolejnym krokiem jest udostępnienie obiektów tej klasy w innych częściach aplikacji. Aplikacja zarządza zależnościami klasy, wdrażając wzór lokalizatora usługi. Otwórz klasę lokalizatora usługi za pomocą przeglądarki klas w Android Studio. W tym celu kliknij Nawiguj > Klasa i wpisz „ServiceLocator”. Kliknij utworzony plik Kotlin, aby otworzyć go w IDE.

Na górze ServiceLocator.kt wklej ten kod, aby zaimportować pakiety ShortcutsRepository i SuppressLint:

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

Dodaj członków usługi i metody ShortcutRepository, wklejając ten kod w treści ServiceLocator.kt:

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)
       }
   }
 }

Rejestrowanie usługi skrótu

Ostatnim krokiem jest zarejestrowanie nowej usługi ShortcutsRepository w aplikacji. W Android Studio otwórz TodoApplication.kt i skopiuj ten kod u góry pliku:

TodoApplication.kt

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

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

Następnie zarejestruj usługę, dodając do treści klasy ten kod:

TodoApplication.kt

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

   //...

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

   //...
}

Skompiluj aplikację i upewnij się, że działa ona prawidłowo.

5. Przekaż nowy skrót

Po utworzeniu usługi skrótów możesz zacząć używać skrótów. Użytkownicy generują w tej aplikacji treści (elementy zadania) i spodziewają się, że będą mogli do nich później wrócić. Dlatego za każdym razem, gdy użytkownik utworzy nowe zadanie, będziemy włączać dostęp do tych treści za pomocą dynamicznego skrótu powiązanego z GET_THING BII. Dzięki temu Asystent może przekierowywać użytkowników bezpośrednio do żądanego zadania, gdy uruchamiają one BII, prosząc o coś takiego jak „Hej Google, otwórz moją listę zakupów w SampleApp”.

Tę funkcję możesz włączyć w przykładowej aplikacji, wykonując te czynności:

  1. Importuję usługę ShortcutsRepository do klasy AddEditTaskViewModel. Odpowiada ona za zarządzanie obiektami listy zadań.
  2. Przekazywanie dynamicznego skrótu, gdy użytkownik tworzy nowe zadanie.

Importuj repozytorium skrótów

Najpierw musimy udostępnić usługę ShortcutsRepository użytkownikom usługi AddEditTaskViewModel. Aby to zrobić, zaimportuj usługę do ViewModelFactory, klasy fabrycznej, której aplikacja używa do tworzenia instancji obiektów ViewModel, w tym AddEditTaskViewModel.

Otwórz przeglądarkę zajęć w Android Studio. W tym celu kliknij Nawigacja > Class i wpisz „ViewModelFactory”. Kliknij wynikowy plik Kotlin, aby otworzyć go w swoim IDE.

Na górze ViewModelFactory.kt wklej ten kod, aby zaimportować pakiety ShortcutsRepository i SuppressLint:

ViewModelFactory.kt

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

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

Następnie zastąp treść pola ViewModelFactory tym kodem:

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
}

Zakończ wprowadzanie zmian w ViewModelFactory, przechodząc o jeden poziom wyżej i przekazując ShortcutsRepository konstruktorowi fabryki. Otwórz przeglądarkę plików Android Studio, wybierając Nawigacja > File (Plik) i wpisz „FragmentExt.kt”. Kliknij wynikowy plik Kotlin znajdujący się w pakiecie util, aby otworzyć go w swoim IDE.

Zastąp treść pola FragmentExt.kt tym kodem:

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

Wypchnij skrót

Gdy klasa abstrakcji ShortcutsRepository jest dostępna dla klas przykładowej aplikacji ViewModel, zaktualizujesz AddEditTaskViewModel (klasę ViewModel odpowiedzialną za tworzenie notatek), tak aby przy każdym tworzeniu nowej notatki przez użytkownika wypchnięto dynamiczny skrót.

W Android Studio otwórz przeglądarkę zajęć i wpisz „AddEditTaskViewModel”. Kliknij wynikowy plik Kotlin, aby otworzyć go w swoim IDE.

Najpierw dodaj do tej klasy pakiet ShortcutsRepository za pomocą tego polecenia importu:

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

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

Następnie dodaj właściwość klasy shortcutsRepository, aktualizując konstruktor klasy za pomocą tego kodu:

AddEditTaskViewModel.kt

//...

/**
*
ViewModel for the Add/Edit screen.
*/

class AddEditTaskViewModel(
   private val tasksRepository: TasksRepository,
   private val shortcutsRepository: ShortcutsRepository
) : ViewModel() {

    //...

Po dodaniu klasy ShortcutsRepository utwórz nową funkcję pushShortcut(), aby wywołać tę klasę. Wklej tę prywatną funkcję w ciele funkcji AddEditTaskViewModel:

AddEditTaskViewModel.kt

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

Na koniec wysyłaj nowy dynamiczny skrót za każdym razem, gdy zostanie utworzone zadanie. Zastąp zawartość funkcji saveTask() tym kodem:

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)
   
}
}

Testowanie kodu

Możemy wreszcie przetestować nasz kod! W tym kroku musisz nacisnąć dynamiczny skrót z obsługą głosu i sprawdzić go za pomocą aplikacji Asystent Google.

Tworzenie wersji przedpremierowej

Utworzenie podglądu przy użyciu wtyczki Asystenta Google umożliwia wyświetlanie dynamicznych skrótów w Asystencie na urządzeniu testowym.

Instalowanie wtyczki testowej

Jeśli nie masz jeszcze wtyczki Asystenta Google, zainstaluj ją w Android Studio, wykonując te czynności:

  1. Wybierz **Plik > Ustawienia (w systemie macOS Android Studio > Ustawienia).
  2. W sekcji Wtyczki kliknij Marketplace i wyszukaj „Asystent Google”.
  3. Zainstaluj narzędzie i ponownie uruchom Android Studio.

Tworzenie podglądu

Aby utworzyć podgląd, wykonaj te czynności w Android Studio:

  1. Kliknij Narzędzia > Asystent Google > „Narzędzie do testowania działań aplikacji”.
  2. W polu Nazwa aplikacji wpisz nazwę, na przykład „Lista zadań”.
  3. Kliknij Utwórz podgląd. Gdy pojawi się prośba, przeczytaj i zaakceptuj zasady i warunki korzystania z akcji w aplikacji.

Panel tworzenia podglądu w narzędziu do testowania działań w aplikacji

Rysunek 3. Panel tworzenia podglądu w narzędziu Testowanie działań w aplikacji.

Podczas testowania dynamiczne skróty wysyłane do Asystenta będą w nim widoczne, uporządkowane według nazwy aplikacji, którą podano w ramach podglądu.

Przesyłanie i sprawdzanie skrótu

Uruchom ponownie przykładową aplikację na urządzeniu testowym i wykonaj te czynności :

  1. Utwórz nowe zadanie o nazwie „Rozpocznij ćwiczenia z programowania”
  2. Otwórz aplikację Asystent Google i powiedz lub wpisz „Moje skróty”.
  3. Kliknij kartę Odkrywaj. Powinien być widoczny przykładowy skrót.
  4. Kliknij skrót, aby go uruchomić. Po uruchomieniu aplikacji w polu filtra powinna pojawić się nazwa skrótu, co ułatwi znalezienie żądanego elementu zadania.

6. (Opcjonalnie) Aktualizowanie i usuwanie skrótu

Aplikacja może nie tylko wysyłać nowe dynamiczne skróty w czasie działania, ale też aktualizować je, aby odzwierciedlały aktualny stan treści i ustawień użytkownika. Dobrą praktyką jest aktualizowanie istniejących skrótów, gdy użytkownik zmodyfikuje element docelowy, np. zmieni nazwę zadania w naszej przykładowej aplikacji. Należy też usunąć odpowiedni skrót, gdy usuniesz zasób docelowy, aby uniknąć wyświetlania niedziałających skrótów użytkownikowi.

Aktualizowanie skrótu

Zmodyfikuj AddEditTaskViewModel, aby aktualizować skrót dynamiczny za każdym razem, gdy użytkownik zmieni szczegóły elementu zadania. Najpierw zaktualizuj treść klasy przy użyciu następującego kodu, aby dodać funkcję aktualizacji, która korzysta z klasy repozytorium:

AddEditTaskViewModel.kt

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

Następnie zmień funkcję saveTask(), aby wywoływała naszą nową metodę po każdej aktualizacji istniejącego zadania.

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)
   }
}

Aby przetestować kod, uruchom ponownie aplikację i wykonaj te czynności:

  1. Zmień nazwę istniejącego elementu zadania na „Zakończ ćwiczenia w programowaniu”.
  2. Aby otworzyć Asystenta Google, powiedz „OK Google, moje skróty”.
  3. Kliknij kartę Odkrywaj. Powinieneś zobaczyć zaktualizowaną krótką etykietę testowego skrótu.

Usuwanie skrótu

Nasze przykładowe skróty do aplikacji powinny być usuwane, gdy użytkownik usunie zadanie. W przykładowej aplikacji logika usuwania zadań znajduje się w klasie TaskDetailViewModel. Zanim zaktualizujemy te zajęcia, musimy ponownie zaktualizować zasadę ViewModelFactory, aby przekazać shortcutsRepository do zajęć TaskDetailViewModel.

Otwórz plik ViewModelFactory i zastąp zawartość jego metody konstruktora tym kodem:

//...
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
}

Następnie otwórz TaskDetailViewModel. Zaimportuj moduł ShortcutsRepository i zadeklaruj dla niego zmienną instancji za pomocą tego kodu:

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() {
...
}

Na koniec zmień funkcję deleteTask() tak, aby wywoływała funkcję shortcutsRepository, co spowoduje usunięcie skrótu na podstawie jego identyfikatora za każdym razem, gdy zostanie usunięte zadanie z odpowiednim identyfikatorem taskId:

TaskDetailViewModel.kt

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

Aby przetestować kod, uruchom ponownie aplikację i wykonaj te czynności:

  1. usunąć zadanie testowe.
  2. Zmień nazwę istniejącego elementu zadania na „Zakończ ćwiczenia w programowaniu”.
  3. Aby otworzyć Asystenta Google, powiedz „OK Google, moje skróty”.
  4. Kliknij kartę Odkrywaj. Sprawdź, czy skrót testowy już się nie wyświetla.

7. Dalsze kroki

Gratulacje! Dzięki Tobie użytkownicy naszej przykładowej aplikacji mogą łatwo wracać do tworzonych przez siebie notatek, prosząc Asystenta o coś takiego jak „OK Google, otwórz moją listę zakupów w ExampleApp”. Skróty zwiększają zaangażowanie użytkowników, ponieważ ułatwiają im ponowne odtwarzanie często używanych działań w aplikacji.

Omówione zagadnienia

Z tego ćwiczenia na temat programowania dowiesz się, jak:

  • Określ przypadki użycia przesyłania dynamicznych skrótów w aplikacji.
  • Zmniejsz złożoność kodu przy użyciu wzorców projektowych repozytorium, wstrzykiwania zależności i lokalizatora usług.
  • Dodawaj do treści aplikacji użytkowników dynamiczne skróty z obsługą głosu.
  • aktualizować i usuwać istniejące skróty.

Co dalej?

Tutaj możesz dokonać dalszych poprawek w aplikacji Lista zadań. Aby zapoznać się z ukończonym projektem, otwórz repozytorium –gałęzi codelab-complete na GitHubie.

Oto kilka sugestii, jak dowiedzieć się więcej o rozszerzaniu tej aplikacji za pomocą akcji w aplikacji:

Aby dalej korzystać z Actions on Google, zapoznaj się z tymi materiałami:

Obserwuj nas na Twitterze @ActionsOnGoogle, aby być na bieżąco z najnowszymi informacjami. Aby poinformować o swoich dokonaniach, opublikuj tweeta z hashtagiem #appActions.

Ankieta dotycząca opinii

Na koniec wypełnij tę ankietę, aby przekazać nam swoją opinię na temat tego ćwiczenia z programowania.