Offrir aux utilisateurs Wear OS de nouvelles approches avec l'API Ongoing Activity

1. Introduction

a3457956a1735674.gif

Regardez l'animation ci-dessus (démonstration "Activité en cours"). Remarque : Les GIF animés ne peuvent être animés qu'une seule fois. Si vous avez manqué l'animation, actualisez la page.

Sur le cadran, une icône animée apparaît (pour le minuteur). Si l'utilisateur appuie dessus, il lance l'application qui l'actionne.

L'activité en cours est une nouvelle fonctionnalité de Wear OS qui permet d'afficher une notification en cours sur d'autres surfaces au sein de l'interface utilisateur de Wear OS. Elle permet aux utilisateurs de poursuivre leurs interactions en cas d'activités de longue durée.

Les notifications en cours sont généralement utilisées pour indiquer qu'une notification comporte une tâche en arrière-plan avec laquelle l'utilisateur interagit activement (p. ex. écouter de la musique), ou qui est en attente et occupe donc l'appareil (p. ex. téléchargement de fichier, opération de synchronisation ou connexion réseau active).

Par exemple, un utilisateur de Wear OS peut utiliser une application de minuteur pour chronométrer un événement, puis quitter cette application pour lancer une autre tâche (consulter la météo, démarrer une séance de sport, etc.).

Lorsque l'utilisateur quitte l'application de minuteur, celle-ci envoie généralement une notification en cours liée à des tâches en arrière-plan (services, gestionnaires d'alarmes, etc.) afin de l'informer du temps qu'il reste sur le minuteur.

L'utilisateur peut consulter l'information en temps réel grâce à la notification, et interagir avec elle.

Toutefois, pour afficher la notification, l'utilisateur devra toujours faire glisser son doigt vers la barre de notification située sous le cadran et trouver la notification appropriée, ce qui est moins pratique que sur d'autres surfaces.

Grâce à l'API Ongoing Activity (Activité en cours), une application peut afficher des informations sur plusieurs nouvelles surfaces pratiques sur Wear OS afin de maintenir l'intérêt des utilisateurs.

Dans l'application Minuteur, les informations peuvent s'afficher sur le cadran de l'utilisateur sous la forme d'une icône tactile (indicateur d'activité au bas de la capture d'écran) :

b65ade9bf43c526e.png

L'application Minuteur peut également apparaître dans la section Récents du lanceur d'applications global, qui répertorie les activités en cours :

1bc84dd2bd2d2b5d.png

Lanceur global

Cerise sur le gâteau, seules 10 lignes de code supplémentaires suffisent !

Ce que vous allez apprendre

  • Créer et personnaliser une activité en cours.
  • Associer une activité en cours à une notification en cours.
  • Tester une activité en cours sur un appareil/émulateur.
  • Ajouter une interaction à votre activité en cours (appuyer).

Objectif de l'atelier

Vous développerez une application de suivi de la marche existante en lui ajoutant une activité en cours personnalisée qui affichera les points de marche pour une marche active sur le cadran principal et dans la section Récents du lanceur d'applications.

Conditions préalables

2. Configuration

Au cours de cette étape, vous configurerez votre environnement et téléchargerez le projet de démarrage.

Ce dont vous avez besoin

  • Android Studio
  • L'émulateur Wear OS (niveau d'API 30 ou supérieur).
  • Les activités en cours ne sont disponibles qu'à partir du niveau d'API 30.
  • Vous découvrez les émulateurs ? Voici comment faire.

Télécharger le code

Si git est installé, vous pouvez simplement exécuter la commande ci-dessous pour cloner le code à partir de ce dépôt. Pour vérifier s'il est installé, saisissez git --version dans le terminal ou la ligne de commande, et vérifiez qu'il fonctionne correctement.

git clone https://github.com/android/codelab-ongoing-activity.git
cd ongoing-activity

Si vous n'avez pas git, cliquez sur le bouton ci-dessous pour télécharger l'ensemble du code de cet atelier de programmation :

Télécharger le fichier ZIP

À tout moment, vous pouvez exécuter l'un ou l'autre de ces modules en modifiant la configuration d'exécution dans la barre d'outils Android Studio.

b059413b0cf9113a.png

Ouvrir un projet dans Android Studio

  1. Dans la fenêtre "Welcome to Android Studio" (Bienvenue dans Android Studio), sélectionnez Open (Ouvrir).
  2. Sélectionnez le dossier [Download Location]
  3. Une fois qu'Android Studio a importé le projet, vérifiez que vous pouvez exécuter les modules start et finished sur un appareil physique ou un émulateur Wear OS.
  4. Le module start doit ressembler à la capture d'écran ci-dessous. C'est dans cet espace que vous allez travailler.

a40cc0c7e7e28bcf.png

Commencez une séance de marche pour essayer l'application. Vous devriez commencer à gagner des points toutes les trois secondes environ. L'application utilise des données fictives, vous n'avez donc pas à vous déplacer.

Balayez l'écran pour sortir de l'application. Si vous naviguez sous le cadran de la montre jusqu'à la barre de navigation, vous devriez trouver la notification en cours qui continue de suivre vos points de marche.

Voici ce qui se produit si vous appuyez dessus :

ac48b3ddc2a093bb.png

36fed11735ef4807.png

N'hésitez pas à arrêter la marche.

À la fin de cet atelier de programmation, les mêmes informations de marche s'afficheront sur le cadran et dans la section Récents du lanceur d'applications global.

Application qui s'affiche sur le cadran (voir Indicateur d'activité en bas de l'écran) :

59747518d70b053a.png

Application qui s'affiche dans la section Récents du lanceur d'applications :

4817a55e6722629d.png

Se familiariser avec le code de démarrage

Dans le module start :

  • build.gradle contient la configuration de base d'une application, y compris les dépendances requises pour la création d'une activité en cours.
  • manifest > AndroidManifest.xml inclut les éléments nécessaires pour identifier cette application comme une application Wear OS.
  • java > ... > data > WalkingWorkoutsRepository.kt renvoie vers la classe WalkingWorkoutsDataStore.kt pour enregistrer les points de marche et l'état d'une séance de marche. Ne vous souciez pas des détails, vous n'aurez pas besoin de suivre ces classes dans cet atelier de programmation.
  • java > ... > MainApplication.kt crée un singleton du dépôt. Ne vous souciez pas des détails, vous n'aurez pas besoin de suivre ces classes dans cet atelier de programmation.
  • java > ... > ForegroundOnlyWalkingWorkoutService.kt contient le code permettant de démarrer et d'arrêter un entraînement de marche à pied. Si une séance de sport est en cours et l'utilisateur quitte l'application, la séance se détache de l'activité et envoie une notification en cours pour que l'utilisateur soit informé de ses points d'entraînement (à l'aide de données fictives). Nous ajouterons alors le code de votre activité en cours (près du code de notification).
  • java > ... > MainActivity.kt contient une UI permettant à l'utilisateur de démarrer ou d'arrêter un entraînement de marche à pied. L'activité se lie au service ci-dessus pour permettre à celui-ci de gérer toutes les tâches d'entraînement.
  • java > ... > MainViewModel.kt est un ViewModel simple permettant de gérer le code qui ne concerne pas l'interface utilisateur dans MainActivity.kt. Ne vous souciez pas des détails, vous n'aurez pas besoin de suivre ces classes dans cet atelier de programmation.

3. Examiner l'application

L'application est déjà une application de marche à pied.

Comme nous l'avons vu précédemment, vous pouvez lancer l'application et démarrer/arrêter une séance de marche à pied. Au fil du temps, vous gagnez des points de marche lors d'une séance de sport active.

Les points sont réinitialisés à chaque nouvelle séance.

Si vous quittez l'application pendant une séance active, vous pouvez balayer l'écran vers le bas pour voir une notification en cours qui vous informe de votre progression.

Depuis cette notification, vous pouvez arrêter la séance en cours ou ouvrir l'application.

Habituellement, vous calculez les points de marche à partir de données de localisation et de capteurs à l'aide d'un algorithme propriétaire. Dans notre cas, il s'agit simplement de simuler les données.

Comment ça marche ?

MainActivity crée l'interface utilisateur, renvoie vers ViewModel pour obtenir des informations sur l'état de l'entraînement et les points de marche, et s'associe à un service.

Lorsqu'une séance de sport démarre ou s'arrête, la méthode MainActivity appelle une méthode de démarrage ou d'arrêt équivalente dans le service pour gérer le suivi global de l'entraînement.

Si l'utilisateur quitte l'application, la MainActivity est simplement dissociée du service.

C'est dans ForegroundOnlyWalkingWorkoutService qu'a lieu toute la magie, ou presque. Voici la classe qui sert à démarrer ou arrêter les entraînements, et à enregistrer les modifications d'état ou les points de marche dans le dépôt.

Le service devient également un service de premier plan et se lie à une notification en cours si l'utilisateur quitte la MainActivity pendant une session.

La notification en cours continue de suivre l'entraînement, et est associée au service ci-dessus en tant que service au premier plan.

Ne vous inquiétez pas si vous ne comprenez pas tous les détails. Vous devez surtout comprendre qu'il s'agit d'une application opérationnelle, avec une notification déjà créée. Nous souhaitons seulement étendre cette notification à d'autres surfaces avec une activité en cours.

Ce code de notification se trouve dans ForegroundOnlyWalkingWorkoutService, et c'est là que vous effectuerez toutes les tâches de cet atelier de programmation.

4. Créer une activité en cours

Examiner les dépendances

Au cours de cette étape, nous ne coderons pas. À la place, nous examinerons les dépendances des activités en cours.

Ouvrez le fichier app/build.gradle dans le module start et recherchez "TODO: Review dependencies for Ongoing Activity".

Votre écran devrait ressembler à ceci :

Étape 1

    // TODO: Review dependencies for Ongoing Activity.
    implementation libs.androidx.wear.ongoing
    // Includes LocusIdCompat and new Notification categories for Ongoing Activity.
    implementation libs.androidx.core.ktx

La première dépendance est requise pour utiliser l'API Wear OS Ongoing Activity (activité en cours).

La deuxième dépendance consiste à obtenir les dernières fonctionnalités des API de notification. Elles prennent en charge différentes fonctionnalités utilisées en association avec une activité en cours. Les deux fonctionnalités suivantes peuvent s'appliquer aux notifications en cours et, par conséquent, aux activités en cours :

  • Catégorie : Android utilise des catégories prédéfinies à l'échelle du système pour déterminer s'il faut déranger l'utilisateur en lui présentant une notification spécifique lorsque celui-ci a activé le mode Ne pas déranger. La catégorie détermine la priorité de l'activité en cours sur le cadran. Récemment, de nouvelles catégories ont été rendues compatibles avec Wear.
  • ID Locus : Locus est un nouveau concept introduit dans Android 10 (niveau d'API 29). Il permet au système Android de corréler les états de différents sous-systèmes, tels que la capture de contenu, les raccourcis et les notifications. Si vous avez plusieurs lanceurs d'applications, vous pouvez utiliser l'ID de locus pour associer votre activité en cours à un Shortcut dynamique spécifique, afin qu'il s'affiche correctement dans la section Récents du lanceur d'applications.

Examiner le code de notification en cours

Au cours de cette étape, nous ne coderons pas. Nous nous contenterons d'examiner le code de notification.

Ouvrez le fichier ForegroundOnlyWalkingWorkoutService.kt dans le module start et recherchez "TODO: Review Notification builder code".

Votre écran devrait ressembler à ceci :

Étape 2

// TODO: Review Notification builder code.
val notificationBuilder = notificationCompatBuilder
    .setStyle(bigTextStyle)
    .setContentTitle(titleText)
    .setContentText(mainText)
    .setSmallIcon(R.mipmap.ic_launcher)
    .setDefaults(NotificationCompat.DEFAULT_ALL)
    // Makes Notification an Ongoing Notification (a Notification with a background task).
    .setOngoing(true)
    // Android uses some pre-defined system-wide categories to determine whether to
    // disturb the user with a given notification when the user has enabled Do Not Disturb
    // mode. The Category determines the priority of the Ongoing Activity and new
    // categories were added recently to support Wear
    .setCategory(NotificationCompat.CATEGORY_WORKOUT)
    .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
    .addAction(
        R.drawable.ic_walk, getString(R.string.launch_activity),
        activityPendingIntent
    )
    .addAction(
        R.drawable.ic_cancel,
        getString(R.string.stop_walking_workout_notification_text),
        servicePendingIntent
    )

// TODO: Create an Ongoing Activity.
// SKIP TODO FOR REVIEW STEP

return notificationBuilder.build()

Lisez le code ci-dessus, ainsi que les commentaires (ignorez la section "À faire", que vous verrez dans une prochaine étape).

Le code de notification au-dessus de ce fragment, qui permet de tout configurer pour ce compilateur, est plus développé.

Toutefois, dans cet atelier de programmation, nous nous bornerons à l'appel setOngoing() et à setCategory() dans le compilateur de notifications.

La catégorie permet à Wear OS de déterminer la priorité de la notification sur le cadran.

L'appel setOngoing() transforme notre notification en notification en cours, c'est-à-dire une notification avec une tâche en arrière-plan avec laquelle l'utilisateur interagit activement (p. ex. le suivi d'une séance de marche à pied).

Nous créons cette notification lorsque l'utilisateur fait une séance de marche active et qu'il quitte la MainActivity.

Créer une activité en cours

Une activité en cours doit être associée à une notification en cours. Nous avons déjà notre notification en cours. Nous allons donc créer une activité en cours.

Recherchez "TODO: Create an Ongoing Activity" et remplacez la ligne "// SKIP TODO FOR REVIEW STEP" par le code ci-dessous.

Étape 4

// TODO: Create an Ongoing Activity.
val ongoingActivityStatus = Status.Builder()
    // Sets the text used across various surfaces.
    .addTemplate(mainText)
    .build()

val ongoingActivity =
    OngoingActivity.Builder(applicationContext, NOTIFICATION_ID, notificationBuilder)
        // Sets icon that will appear on the watch face in active mode. If it isn't set,
        // the watch face will use the static icon in active mode.
        .setAnimatedIcon(R.drawable.animated_walk)
        // Sets the icon that will appear on the watch face in ambient mode.
        // Falls back to Notification's smallIcon if not set. If neither is set,
        // an Exception is thrown.
        .setStaticIcon(R.drawable.ic_walk)
        // Sets the tap/touch event, so users can re-enter your app from the
        // other surfaces.
        // Falls back to Notification's contentIntent if not set. If neither is set,
        // an Exception is thrown.
        .setTouchIntent(activityPendingIntent)
        // In our case, sets the text used for the Ongoing Activity (more options are
        // available for timers and stop watches).
        .setStatus(ongoingActivityStatus)
        .build()

// Applies any Ongoing Activity updates to the notification builder.
// This method should always be called right before you build your notification,
// since an Ongoing Activity doesn't hold references to the context.
ongoingActivity.apply(applicationContext)

Avant de créer une activité en cours, commencez par créer une activité en cours Status qui inclura le texte qui s'affichera sur les différentes surfaces Wear OS.

Nous avons défini le texte à l'aide de .addTemplate() sur le Status.Builder de sorte qu'il corresponde au texte principal de notre notification.

Vous pouvez personnaliser l'apparence du texte (spécifiez les couleurs, la police en gras, etc.), mais nous nous contenterons d'un texte simple dans cet atelier. Cependant, si vous souhaitez en savoir plus, consultez le guide relatif aux activités en cours.

Nous allons ensuite créer le OngoingActivity lui-même. Nous transmettons le contexte, un ID de notification et le compilateur de notifications que nous avons créés au-dessus de ce code, directement dans le compilateur de OngoingActivity.Builder().

L'ID de notification et l'instance NotificationCompat.Builder sont importants pour lier la OngoingActivity à la notification en cours.

Nous commençons par définir une icône animée (pour le cadran en mode Actif) et une icône statique (pour le cadran en mode Veille).

Ensuite, nous définissons un événement tactile, puis le texte à l'aide de l'objet Status que nous avons créé précédemment avant de terminer l'instruction avec .build().

L'UI de OngoingActivity est fournie à l'aide de l'icône et du texte du Status. Grâce à l'événement tactile, l'utilisateur peut à nouveau appuyer sur l'application à partir du cadran ou de la section Récents du lanceur d'applications global.

Enfin, nous appelons apply() sur l'activité en cours et transmettons le contexte. Lors de cette dernière étape, les modifications apportées à l'activité en cours sont appliquées à l'outil de création des notifications.

Et voilà !

Lorsque notificationManager.notify(NOTIFICATION_ID, notification) est appelé avec cette notification, il apparaît désormais sur les nouvelles surfaces.

Exécutez maintenant votre application sur le nouvel émulateur ou le nouvel appareil Wear OS.

Lancez l'application et balayez l'écran pour la quitter.

Sur le cadran de la montre, vous devriez maintenant voir une petite icône représentant une personne en train de marcher, comme illustré ci-dessous :

59747518d70b053a.png

Appuyez sur l'icône pour revenir à l'application.

Quittez à nouveau l'application, puis appuyez sur le bouton du lanceur d'applications de votre appareil Wear OS.

Voici un exemple :

4817a55e6722629d.png

Si vous cliquez sur l'application de marche dans la section Récents, vous devriez retourner dans l'application !

5. Félicitations

Félicitations ! Vous avez appris à créer une activité en cours sur Wear OS.

Les activités en cours sont un excellent moyen de faire en sorte que les utilisateurs interagissent sur de nouvelles surfaces dans Wear.

Et maintenant ?

Consultez les autres ateliers de programmation Wear OS :

Complément d'informations