1. Présentation
Dans l'atelier de programmation précédent, vous avez utilisé des raccourcis statiques pour implémenter des intents intégrés couramment utilisés dans une application exemple. Les développeurs Android utilisent les actions dans les applications pour intégrer les fonctionnalités de l'application à l'Assistant Google.
Les raccourcis statiques sont regroupés avec une application et ne peuvent être modifiés qu'en publiant de nouvelles versions de celle-ci. Si vous souhaitez activer des fonctionnalités vocales pour les éléments dynamiques dans une application, comme le contenu généré par l'utilisateur, vous devez utiliser des raccourcis dynamiques. Les applications envoient des raccourcis dynamiques lorsque les utilisateurs effectuent certaines actions, comme créer une note dans une application de suivi des tâches. Avec les actions dans les applications, vous activez ces raccourcis vocaux en les associant à un intent intégré, ce qui permet aux utilisateurs d'accéder à leur contenu à partir de l'Assistant en disant, par exemple, "Hey Google, ouvre ma liste de courses sur ExampleApp".
Figure 1. Trois écrans progressifs montrant une tâche créée par l'utilisateur et l'Assistant Google qui lance un raccourci dynamique sur cette tâche.
Objectifs de l'atelier
Dans cet atelier de programmation, vous allez activer des raccourcis dynamiques pour les commandes vocales dans une application Android exemple permettant de dresser des listes de tâches. Les utilisateurs pourront ainsi demander à l'Assistant d'ouvrir les éléments de la liste qu'ils créent dans l'application. Pour ce faire, vous utilisez des modèles d'architecture Android, en particulier repository, service locator et ViewModel.
Conditions préalables
Cet atelier de programmation s'appuie sur les concepts des actions dans l'application abordés dans l'atelier de programmation précédent, en particulier les intents intégrés et les raccourcis statiques. Si vous ne connaissez pas les actions dans les applications, nous vous recommandons de suivre l'atelier de programmation à leur sujet avant de continuer.
Vérifiez également que la configuration de votre environnement de développement dispose des éléments de configuration suivants :
- Un terminal permettant d'exécuter des commandes shell et avec git installé
- La dernière version stable d'Android Studio
- Un appareil Android physique ou virtuel connecté à Internet
- Un compte Google connecté à Android Studio, à l'appli Google et à l'application Assistant Google
2. Principes de fonctionnement
Pour activer un raccourci dynamique avec Voice Access, vous devrez :
- associer un raccourci dynamique à un intent intégré éligible ;
- autoriser l'Assistant à ingérer les raccourcis en ajoutant la bibliothèque d'intégration des raccourcis Google ;
- transmettre un raccourci chaque fois qu'un utilisateur effectue l'action souhaitée dans l'application.
Lier des raccourcis
Pour qu'un raccourci dynamique soit accessible depuis l'Assistant, il doit être lié à un intent intégré. Lorsqu'un intent intégré avec un raccourci est déclenché, l'Assistant associe les paramètres de la requête utilisateur aux mots clés définis dans le raccourci lié. Exemple :
- Un raccourci lié à l'intent intégré
GET_THING
pourrait permettre aux utilisateurs de demander un contenu spécifique dans l'application directement à l'Assistant. * "Hey Google, ouvre ma liste de courses sur ExampleApp." - Un raccourci lié à l'intent intégré
ORDER_MENU_ITEM
pourrait permettre aux utilisateurs de répéter les commandes précédentes. * "Hey Google, commande ce que je prends d'habitude chez ExampleApp."
Consultez la documentation de référence sur les intents intégrés pour obtenir la liste complète des intents intégrés classés par catégorie.
Fournir des raccourcis à l'Assistant
Après avoir lié vos raccourcis à un intent intégré, l'étape suivante consiste à autoriser l'Assistant à ingérer ces raccourcis en ajoutant la bibliothèque d'intégration des raccourcis Google à votre projet. Une fois cette bibliothèque en place, l'Assistant connaîtra tous les raccourcis transmis par votre application. Les utilisateurs pourront alors lancer ces raccourcis grâce à l'expression de déclenchement du raccourci dans l'Assistant.
3. Préparer votre environnement de développement
Cet atelier de programmation utilise une application exemple pour Android permettant de dresser liste de tâches conçue. Cette application permet aux utilisateurs d'ajouter des éléments à des listes, de faire des recherches par catégorie et de les filtrer par état. Téléchargez et préparez l'application exemple en remplissant cette section.
Télécharger vos fichiers de base
Exécutez la commande suivante pour cloner le dépôt GitHub de l'exemple d'application :
git clone https://github.com/actions-on-google/app-actions-dynamic-shortcuts.git
Une fois le dépôt cloné, procédez comme suit pour l'ouvrir dans Android Studio :
- Dans la boîte de dialogue Welcome to Android Studio (Bienvenue dans Android Studio), cliquez sur Import project (Importer un projet).
- Sélectionnez le dossier dans lequel vous avez cloné le dépôt.
Vous pouvez également afficher une version de l'application exemple telle qu'elle est à la fin de l'atelier de programmation en clonant la branche codelab-complete
de son dépôt GitHub :
git clone https://github.com/actions-on-google/app-actions-dynamic-shortcuts.git --branch codelab-complete
Modifier l'ID d'application Android
Modifier l'ID de l'application permet d'identifier de manière unique l'application sur votre appareil de test et d'éviter une erreur "Duplicate package name" (Nom de package en double) si l'application est importée dans la Play Console. Pour modifier l'ID application, ouvrez app/build.gradle
:
android {
...
defaultConfig {
applicationId "com.MYUNIQUENAME.android.fitactions"
...
}
}
Dans le champ applicationId
, remplacez "MYUNIQUENAME" par un nom qui vous est propre.
Ajouter les dépendances de l'API Shortcuts
Ajoutez les bibliothèques Jetpack suivantes au fichier de ressources 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'
...
}
Tester l'application sur votre appareil
Avant d'apporter d'autres modifications au code de l'application, il peut être utile de la tester pour vous faire une idée de ses fonctionnalités. Pour exécuter l'application sur votre émulateur, procédez comme suit :
- Dans Android Studio, sélectionnez "Run" > "Run app" (Exécuter > Exécuter l'application) ou cliquez sur Run (Exécuter) dans la barre d'outils.
- Dans la boîte de dialogue Select Deployment Target (Sélectionner une cible de déploiement), sélectionnez un appareil, puis cliquez sur OK. La version d'OS recommandée est Android 10 (niveau d'API 30) ou version ultérieure, bien que les actions dans l'application fonctionnent sur des appareils à partir d'Android 5 (niveau d'API 21).
- Appuyez de manière prolongée sur le bouton Accueil pour configurer l'Assistant et vérifier qu'il fonctionne. Vous devrez vous connecter à l'Assistant sur votre appareil si ce n'est pas déjà fait.
Pour en savoir plus sur les appareils virtuels Android, consultez Créer et gérer des appareils virtuels.
Parcourez l'application pour voir ses fonctionnalités. Appuyez sur l'icône Plus pour créer une tâche. Les éléments de menu en haut à droite vous permettent de rechercher et de filtrer les tâches par état.
4. Créer une classe de dépôt de raccourcis
Plusieurs classes de notre application exemple appelleront l'API ShortcutManagerCompat
pour transférer et gérer des raccourcis dynamiques. Afin de réduire la redondance du code, vous allez implémenter un dépôt permettant à vos classes de projet de gérer facilement les raccourcis dynamiques.
Le modèle de conception du dépôt fournit une API propre pour gérer les raccourcis. Utiliser un dépôt permet aux détails de l'API sous-jacente d'être éliminés de manière uniforme derrière une API minimale. Implémentez le dépôt comme suit :
- Créez une classe
ShortcutsRepository
pour éliminer l'APIShortcutManagerCompat
. - Ajoutez des méthodes
ShortcutsRepository
à l'outil de localisation de services de l'application. - Enregistrez le service
ShortcutRepository
dans l'application principale.
Créer le dépôt
Créez une classe Kotlin nommée ShortcutsRepository
dans le package com.example.android.architecture.blueprints.todoapp.data.source
. Il se trouve dans le dossier app/src/main/java
. Vous allez implémenter dans cette classe une interface fournissant un ensemble réduit de méthodes couvrant notre cas d'utilisation de l'atelier de programmation.
Figure 2. Fenêtre "Fichiers de projet" d'Android Studio affichant l'emplacement de la classe ShortcutsRepository.
Collez le code suivant dans la nouvelle classe :
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>) {
//...
}
}
Ensuite, modifiez la méthode pushShortcut
pour appeler l'API ShortcutManagerCompat
. Remplacez la classe ShortcutsRepository
avec le code suivant :
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))
}
Dans l'exemple de code précédent, nous avons transmis appContext
à l'API. Il s'agit d'une propriété de classe contenant un contexte d'application. Il est important d'utiliser un contexte d'application (par opposition à un contexte d'activité) pour éviter les fuites de mémoire. En effet, le contexte peut être conservé plus longtemps que le cycle de vie de l'activité de l'hôte.
De plus, l'API nécessite la transmission d'un objet ShortcutInfoCompat
pour l'objet Task. Dans l'exemple de code précédent, nous effectuons cette opération en appelant la méthode privée createShortcutCompat
, que nous allons modifier pour créer et renvoyer un objet ShortcutInfoCompat
. Pour ce faire, modifiez le bouchon createShortcutCompat
avec le code suivant :
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()
}
Les bouchons de fonction restants de cette classe concernent la modification et la suppression des raccourcis dynamiques. Pour activer ces fonctions, utilisez le code suivant :
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 })
}
Ajouter une classe à l'outil de localisation de services
Une fois la classe ShortcutsRepository
créée, l'étape suivante consiste à mettre les objets instanciés de cette classe à la disposition du reste de l'application. Cette application gère les dépendances de classe en implémentant le modèle de localisation de services. Ouvrez la classe de l'outil de localisation de services à l'aide du navigateur de classe dans Android Studio. Pour ce faire, accédez à Navigate > Class (Naviguer > Classe) et saisissez "ServiceLocator". Cliquez sur le fichier Kotlin obtenu pour l'ouvrir dans votre IDE.
En haut de ServiceLocator.kt
, collez le code suivant pour importer les packages ShortcutsRepository
et 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
Ajoutez les méthodes et les membres du service ShortcutRepository
en collant le code suivant dans le corps de 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)
}
}
}
Enregistrer le service de raccourcis
La dernière étape consiste à enregistrer votre nouveau service ShortcutsRepository
auprès de l'application. Dans Android Studio, ouvrez TodoApplication.kt
et copiez le code suivant en haut du fichier :
TodoApplication.kt
package com.example.android.architecture.blueprints.todoapp
/// ... Other import statements
import com.example.android.architecture.blueprints.todoapp.data.source.ShortcutsRepository
Ensuite, enregistrez le service en ajoutant le code suivant au corps de la classe :
TodoApplication.kt
//...
class TodoApplication : Application() {
//...
val shortcutsRepository: ShortcutsRepository
get() = ServiceLocator.provideShortcutsRepository(this)
//...
}
Créez l'application et vérifiez qu'elle continue de fonctionner.
5. Transmettre un nouveau raccourci
Une fois votre service de raccourcis créé, vous pouvez commencer à transmettre les raccourcis. Étant donné que les utilisateurs génèrent du contenu (tâches) dans cette application et s'attendent à pouvoir y accéder ultérieurement, nous allons activer l'accès à ce contenu par commande vocale. Pour ce faire, nous allons transférer un raccourci dynamique associé à l'intent intégré GET_THING
chaque fois qu'un utilisateur crée une tâche. Cela permet à l'Assistant de rediriger les utilisateurs directement vers la tâche demandée lorsqu'ils déclenchent l'intent intégré en disant, par exemple, "Hey Google, ouvre ma liste de courses sur SampleApp".
Pour activer cette fonctionnalité dans l'application exemple, procédez comme suit :
- Importez le service
ShortcutsRepository
dans la classeAddEditTaskViewModel
, qui sert à gérer les objets de la liste de tâches. - Transférez un raccourci dynamique lorsque l'utilisateur crée une tâche.
Importer ShortcutsRepository
Nous devons d'abord mettre le service ShortcutsRepository
à la disposition de AddEditTaskViewModel
. Pour ce faire, importez le service vers ViewModelFactory
. Il s'agit de la classe d'usine utilisée par l'application pour instancier des objets ViewModel, y compris AddEditTaskViewModel
.
Ouvrez le navigateur de classe dans Android Studio en accédant à Navigate > Class (Naviguer > Classe), puis saisissez "ViewModelFactory". Cliquez sur le fichier Kotlin obtenu pour l'ouvrir dans votre IDE.
En haut de ViewModelFactory.kt
, collez le code suivant pour importer les packages ShortcutsRepository
et SuppressLint
:
ViewModelFactory.kt
package com.example.android.architecture.blueprints.todoapp
// ...Other import statements
import com.example.android.architecture.blueprints.todoapp.data.source.ShortcutsRepository
Ensuite, remplacez le corps de ViewModelFactory
par le code suivant :
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
}
Finalisez les modifications de ViewModelFactory
en remontant d'une couche et transmettez ShortcutsRepository
au constructeur de la fabrique. Ouvrez l'explorateur de fichiers d'Android Studio en accédant à Navigate > File (Navigation > Fichier), puis en saisissant "FragmentExt.kt". Cliquez sur le fichier Kotlin obtenu dans le package util pour l'ouvrir dans votre IDE.
Remplacez le corps de FragmentExt.kt
par le code suivant :
fun Fragment.getViewModelFactory(): ViewModelFactory {
val taskRepository = (requireContext().applicationContext as TodoApplication).taskRepository
val shortcutsRepository = (requireContext().applicationContext as TodoApplication).shortcutsRepository
return ViewModelFactory(taskRepository, shortcutsRepository, this)
}
Utiliser un raccourci
Avec la classe d'abstraction ShortcutsRepository
disponible pour les classes ViewModel
de l'application exemple, vous modifiez AddEditTaskViewModel
(la classe ViewModel
chargée de créer des notes) afin d'envoyer un raccourci dynamique chaque fois qu'un utilisateur crée une note.
Dans Android Studio, ouvrez le navigateur de classe, puis saisissez "AddEditTaskViewModel". Cliquez sur le fichier Kotlin obtenu pour l'ouvrir dans votre IDE.
D'abord, ajoutez le package ShortcutsRepository
à cette classe avec l'instruction d'importation suivante :
package com.example.android.architecture.blueprints.todoapp.addedittask
//Other import statements
import com.example.android.architecture.blueprints.todoapp.data.source.ShortcutsRepository
Ensuite, ajoutez la propriété de classe shortcutsRepository
en remplaçant le constructeur de la classe par le code suivant :
AddEditTaskViewModel.kt
//...
/**
* ViewModel for the Add/Edit screen.
*/
class AddEditTaskViewModel(
private val tasksRepository: TasksRepository,
private val shortcutsRepository: ShortcutsRepository
) : ViewModel() {
//...
Une fois la classe ShortcutsRepository
ajoutée, créez une fonction, pushShortcut()
, pour appeler cette classe. Collez la fonction privée suivante dans le corps de AddEditTaskViewModel
:
AddEditTaskViewModel.kt
//...
private fun pushShortcut(newTask: Task) = viewModelScope.launch {
shortcutsRepository.pushShortcut(newTask)
}
Enfin, transmettez un nouveau raccourci dynamique chaque fois qu'une tâche est créée. Remplacez le contenu de la fonction saveTask()
par le code suivant :
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)
}
}
Tester votre code
Nous sommes enfin prêts à tester notre code. Au cours de cette étape, vous allez transmettre un raccourci dynamique à commande vocale et l'inspecter à l'aide de l'application Assistant Google.
Créer un aperçu
Lorsque vous créez un aperçu à l'aide du plug-in Assistant Google, vos raccourcis dynamiques apparaissent dans l'Assistant sur votre appareil de test.
Installer le plug-in de test
Si vous n'avez pas encore installé le plug-in Assistant Google, accédez à Android Studio et procédez comme suit :
- Accédez à **File > Settings (Fichier > Paramètres), ou à Android Studio > Preferences (Android Studio > Préférences) sous macOS.
- Dans la section Plugins (Plug-ins), accédez à Marketplace et recherchez "Google Assistant" (Assistant Google).
- Si vous ne trouvez pas le plug-in sur Marketplace, téléchargez-le manuellement et suivez les instructions figurant sur la page Installer le plug-in depuis un disque.
- Installez l'outil, puis redémarrez Android Studio.
Créer l'aperçu
Pour créer un aperçu, accédez à Android Studio et procédez comme suit :
- Cliquez sur Tools > Google Assistant > "App Actions Test Tool" (Outils > Assistant Google > Outil de test des actions dans l'application).
- Dans le champ App name (nom de l'application), saisissez un nom (par exemple, "Liste de tâches").
- Cliquez sur Create Preview (Créer un aperçu). Si vous y êtes invité, lisez et acceptez les règles et les conditions d'utilisation des actions dans les applications.
Figure 3. Volet de création d'aperçu de l'outil de test des actions dans l'application.
Pendant le test, les raccourcis dynamiques que vous transmettez à l'Assistant y figureront classés selon le nom de l'application que vous avez fourni pour l'aperçu.
Transmettre et inspecter un raccourci
Relancez l'application exemple sur votre appareil de test, puis procédez comme suit :
- Créez une tâche intitulée "Démarrer l'atelier de programmation".
- Ouvrez l'application Assistant Google et dites ou saisissez "Mes raccourcis".
- Appuyez sur l'onglet Explore (Explorer) : l'exemple de raccourci devrait s'afficher.
- Appuyez sur le raccourci pour l'appeler. L'application devrait se lancer avec le nom du raccourci inséré dans la zone de filtre, ce qui facilite la recherche de l'élément de tâche demandé.
6. (Facultatif) Modifier et supprimer un raccourci
En plus de pouvoir transmettre de nouveaux raccourcis dynamiques au moment de l'exécution, votre application peut les modifier pour refléter l'état actuel du contenu et des préférences de l'utilisateur. Il est recommandé de modifier les raccourcis existants chaque fois qu'un utilisateur change l'élément de destination (par exemple, en renommant une tâche dans l'application exemple). De même, lorsqu'une ressource de destination est supprimée, vous devez supprimer le raccourci correspondant afin d'empêcher les raccourcis non fonctionnels d'être présentés à l'utilisateur.
Modifier un raccourci
Apportez des changements à AddEditTaskViewModel
pour modifier un raccourci dynamique chaque fois qu'un utilisateur modifie les détails d'un élément de tâche. Tout d'abord, remplacez le corps de la classe par le code suivant pour ajouter une fonction de modification utilisant notre classe de dépôt :
AddEditTaskViewModel.kt
private fun updateShortcut(newTask: Task) = viewModelScope.launch {
shortcutsRepository.updateShortcuts(listOf(newTask))
}
Modifiez ensuite la fonction saveTask()
pour appeler notre nouvelle méthode chaque fois qu'une tâche existante est modifiée.
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)
}
}
Testez votre code en redémarrant l'application et en procédant comme suit :
- Renommez le titre de votre tâche existante "Terminer l'atelier de programmation".
- Ouvrez l'Assistant Google en disant "Hey Google, mes raccourcis".
- Appuyez sur l'onglet Explore (Explorer) : vous devriez voir un nouveau libellé pour votre raccourci de test.
Supprimer un raccourci
Lorsque l'utilisateur retire une tâche, les raccourcis correspondants doivent être supprimés. Dans l'application, la logique de suppression des tâches se trouve dans la classe TaskDetailViewModel
. Avant d'apporter des changements cette classe, nous devons à nouveau modifier ViewModelFactory
afin de transmettre shortcutsRepository
dans TaskDetailViewModel
.
Ouvrez ViewModelFactory
et remplacez le contenu de la méthode constructeur par le code suivant :
//...
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
}
Ensuite, ouvrez TaskDetailViewModel
. Importez le module ShortcutsRepository
et déclarez une variable d'instance pour celui-ci à l'aide du code suivant :
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() {
...
}
Enfin, modifiez la fonction deleteTask()
pour appeler shortcutsRepository
afin de supprimer un raccourci basé sur son ID chaque fois qu'une tâche avec un taskId
correspondant est supprimée :
TaskDetailViewModel.kt
fun deleteTask() = viewModelScope.launch {
_taskId.value?.let {
//...
shortcutsRepository.removeShortcutsById(listOf(it))
}
}
Pour tester votre code, relancez l'application et procédez comme suit :
- Supprimez votre tâche de test.
- Renommez le titre de votre tâche existante "Terminer l'atelier de programmation".
- Ouvrez l'Assistant Google en disant "Hey Google, mes raccourcis".
- Appuyez sur l'onglet Explore (Explorer) : vérifiez que votre raccourci de test ne s'affiche plus.
7. Étapes suivantes
Félicitations ! Désormais, les utilisateurs de notre application exemple peuvent facilement revenir aux notes qu'ils créent grâce à l'Assistant en disant, par exemple, "Hey Google, ouvre ma liste de courses sur ExampleApp". Les raccourcis favorisent l'engagement des utilisateurs en facilitant la répétition des actions fréquemment effectuées dans votre application.
Points abordés
Dans cet atelier de programmation, vous avez appris à :
- identifier les cas d'utilisation permettant de transmettre des raccourcis dynamiques à une application ;
- réduire la complexité du code à l'aide des modèles de dépôt, d'injection de dépendances et de localisation de services ;
- transmettre des raccourcis dynamiques à commande vocale dans le contenu de l'application généré par l'utilisateur ;
- modifier et supprimer des raccourcis existants.
Étapes suivantes
À présent, vous pouvez essayer d'affiner votre application de liste de tâche. Pour référencer le projet terminé, consultez le dépôt –codelab-complete branch sur GitHub.
Voici quelques suggestions pour en savoir plus sur l'intégration d'actions dans l'application :
- Consultez l'exemple de liste de tâches avec Google Analytics pour Firebase pour découvrir comment suivre les performances de vos actions dans les applications.
- Consultez la documentation de référence sur les intents intégrés concernant les actions dans les applications et découvrez d'autres façons d'intégrer l'Assistant à vos applications.
Pour poursuivre votre parcours Actions on Google, consultez les ressources suivantes :
- actions.google.com : site de documentation officiel d'Actions on Google
- Exemple d'index des actions dans l'application : exemples d'applications et de code pour découvrir les fonctionnalités des actions dans les applications
- Dépôt GitHub sur Actions on Google : exemples de code et de bibliothèques
- r/GoogleAssistantDev : communauté Reddit officielle des développeurs qui utilisent l'Assistant Google
Suivez-nous sur Twitter (@ActionsOnGoogle) pour connaître les dernières informations, et tweetez avec le #appActions pour montrer votre création.
Enquête
Pour terminer, veuillez répondre à cette enquête afin de nous faire part de vos commentaires sur cet atelier de programmation.