Utilisation de notifications Android

Cet atelier de programmation fait partie du cours "Advanced Android" en langage Kotlin. Vous tirerez pleinement parti de ce cours si vous suivez les ateliers en séquence, mais ce n'est pas obligatoire. Tous les ateliers de programmation du cours sont répertoriés sur la page de destination des ateliers de programmation Android avancés sur Kotlin.

Introduction

Les notifications sont des messages présentés à l'utilisateur en dehors de l'interface utilisateur de votre application. Les notifications s'affichent en haut de l'écran si l'appareil est déverrouillé ou, en fonction des paramètres de sécurité, sur l'écran de verrouillage lorsque l'appareil est verrouillé.

Une notification comprend généralement un titre, une description et une icône. Une notification peut également inclure des actions cliquables, une réponse rapide, du contenu extensible et des images.

Les notifications peuvent fournir des informations à temps et comporter des boutons permettant à l'utilisateur d'effectuer des actions rapides, comme envoyer une réponse ou répéter une alarme. Lorsqu'un internaute clique sur une notification, il est redirigé vers une vue de votre application associée au contenu de la notification.

Les notifications sont un moyen utile de rappeler aux utilisateurs une tâche importante, de les informer d'un événement ou de communiquer les informations importantes dont ils ont besoin immédiatement lorsque votre application est en arrière-plan. Utilisez les notifications avec parcimonie. Non seulement cela respecte les utilisateurs, mais cela rend également votre notification plus susceptible d'attirer l'attention qu'elle mérite.

Dans cet atelier de programmation, vous apprendrez à créer et à utiliser des notifications dans une application Android.

Ce que vous devez déjà savoir

Vous devez être au fait:

  • Créer des applications Android en mode Kotlin et plus particulièrement le SDK Android.
  • Concevoir des applications à l'aide des composants d'architecture et de la liaison de données
  • Comprendre les bases de BroadcastReceivers
  • Connaissances de base sur AlarmManager

Points abordés

  • Découvrez comment créer une notification, en définir le style et l'envoyer.
  • Comment annuler des notifications
  • Créer des canaux de notification
  • Découvrez comment ajouter des actions rapides aux notifications.
  • Comment afficher les badges de notification sur l'icône de l'application

Objectifs de l'atelier

  • Ajoutez une notification à l'application de départ.
  • Annulez la notification que vous avez envoyée.
  • Créer différents types de notifications
  • Personnalisez les notifications dans l'application de départ.
  • Ajoutez des actions rapides pour rendre votre notification interactive.
  • Désactivez les badges de notification.

La recette des œufs est simple, mais elle peut s'avérer compliquée si vous ne parvenez pas à mesurer l'heure. Dans cet atelier de programmation, vous allez utiliser une application de minuteur et la rendre parfaite, comme vos futurs œufs. Vous allez commencer par une application de minuteur qui permet à l'utilisateur de régler différents paramètres de temps de cuisson pour différents styles d'œufs. Le minuteur prend en compte l'intervalle de temps sélectionné et affiche un toast lorsque les œufs sont prêts.

Cela peut sembler fonctionnel, mais cette solution est loin d'être parfaite et n'est pas vraiment conviviale. Dans un premier temps, le message reste visible pendant un court instant. Il est donc facile à manquer. De plus, si l'application n'est pas au premier plan ou si l'appareil est verrouillé, aucun indicateur visuel ne s'affiche pour signaler la fin du message.

Idéalement, le minuteur de l'œuf devrait utiliser les notifications pour avertir les utilisateurs lorsque le temps est écoulé. L'utilisateur a vraiment besoin de savoir que les œufs sont prêts immédiatement, sinon les œufs seront écrasés. Les notifications sont visuelles, incluent des sons et peuvent faire vibrer l'appareil. Toutes les façons d'attirer l'attention de l'utilisateur Cela vous permet d'atteindre des œufs parfaits et d'avoir des utilisateurs satisfaits et bien nourris.

Pour obtenir l'exemple d'application, vous pouvez:

Clonez le dépôt depuis GitHub et passez à la branche starter.

$  git clone https://github.com/googlecodelabs/android-kotlin-notifications


Vous pouvez également télécharger le dépôt sous forme de fichier ZIP, le décompresser et l'ouvrir dans Android Studio.

Télécharger le fichier ZIP

  1. Ouvrez et exécutez l'application dans Android Studio.

Vous verrez une image d'œuf et un menu déroulant avec une liste d'intervalles de temps prédéfinis pour cuisiner un œuf. Cliquez sur le triangle dans le menu déroulant Régulière. La première option de la liste est proposée à des fins de test et définit l'alarme sur 10 secondes seulement. Un minuteur est associé à la liste pour lancer le minuteur. Vous pouvez utiliser ce bouton pour démarrer et arrêter le minuteur à tout moment. Le code de départ est entièrement fonctionnel. Vous pouvez donc configurer le minuteur et le démarrer à zéro. Une fois le minuteur terminé, un message de toast s'affiche, comme illustré ci-dessous.

  1. Inspectez le code source. L'application de départ se compose d'une seule activité nommée MainActivity. Il y a trois sous-packages nommés receiver, ui et util.

  • /receiver : le package receiver contient deux récepteurs de diffusion nommés AlarmReceiver et SnoozeReceiver. AlarmReceiver est déclenché par le AlarmManager pour envoyer la notification lorsque le minuteur défini par l'utilisateur est terminé. SnoozeReceiver gère les clics d'utilisateur pour répéter la notification.
  • /ui : contient l'élément EggTimerFragment qui fait partie de la partie UI de l'application. EggTimerViewModel est chargé de démarrer et d'annuler le minuteur ainsi que d'autres tâches liées au cycle de vie de l'application.
  • /util : ce package contient deux fichiers. BindingUtils.kt dispose d'adaptateurs de liaison pour activer la liaison de données entre l'interface utilisateur de l'application et ViewModel. NotificationUtils.kt propose des méthodes d'extension sur NotificationManager.

Les notifications sont un excellent moyen d'attirer l'attention de vos utilisateurs dans votre application. Que votre application ne soit pas exécutée ou ne s'exécute pas au premier plan, une notification devrait apparaître dans une fenêtre pop-up en haut de l'écran, avec éventuellement un son ou une vibration. Pour créer une notification, vous devez utiliser un outil de création de notifications, et fournir un titre, un texte de contenu et une icône. Une fois que l'outil de création dispose de tous les champs nécessaires, le service système NotificationManager vous aide à afficher ce contenu sous forme de notification. NotificationManager est chargé d'envoyer une notification, de mettre à jour son contenu et de l'annuler. Dans les étapes suivantes, vous allez ajouter des méthodes d'extension à NotificationManager. Ainsi, chaque fois que vous aurez besoin d'utiliser NotificationManager, vous pourrez utiliser ces fonctions d'extension pour obtenir la fonctionnalité souhaitée.

Étape 1: Créez une notification de base

Dans cette tâche, vous allez créer une notification, définir un message pour votre utilisateur et envoyer la notification.

  1. Ouvrez la classe NotificationUtils.kt et recherchez TODO: Step 1.1. Vous trouverez les tâches correspondantes dans cet atelier de programmation et le code de l'application.
  2. Examinez la fonction sendNotification() donnée. Vous étendrez cette fonction d'extension à NotificationManager pour envoyer des notifications.
//NotificationUtils.kt
// TODO: Step 1.1 extension function to send messages (GIVEN)
/**
 * Builds and delivers a notification.
 *
 * @param messageBody, notification text.
 * @param context, activity context.
 */
fun NotificationManager.sendNotification(messageBody: String, applicationContext: Context) {
  1. Obtenez une instance de l'outil de création de notifications, transmettez le contexte de l'application et un ID de chaîne. L'ID de la chaîne est une valeur de chaîne de la chaîne.

Les canaux de notification permettent de regrouper les notifications. En regroupant les types de notifications similaires, les développeurs et les utilisateurs peuvent contrôler toutes les notifications sur la chaîne. Une fois la chaîne créée, elle peut servir à envoyer un nombre illimité de notifications.

//NotificationUtils.kt
// TODO: Step 1.2 get an instance of NotificationCompat.Builder
val builder = NotificationCompat.Builder(
        applicationContext,
        applicationContext.getString(R.string.egg_notification_channel_id)
)
  1. Définissez l'icône de notification pour représenter votre application, un titre et le texte du message que vous souhaitez transmettre à l'utilisateur. Vous verrez davantage d'options pour personnaliser votre notification dans l'atelier de programmation, mais il s'agit de la quantité minimale de données que vous devez définir pour envoyer une notification.
//NotificationUtils.kt
   // TODO: Step 1.3 set title, text and icon to builder
   .setSmallIcon(R.drawable.cooked_egg)
   .setContentTitle(applicationContext.getString(R.string.notification_title))
   .setContentText(messageBody)
  1. Vous devez ensuite appeler notify() avec un identifiant unique pour votre notification et avec l'objet Notification de votre compilateur.

Cet ID représente l'instance de notification actuelle. Il est nécessaire pour mettre à jour ou annuler cette notification. Étant donné que votre application n'a qu'une seule notification active à la fois, vous pouvez utiliser le même ID pour toutes vos notifications. Vous avez déjà reçu la constante NOTIFICATION_ID correspondante dans NotificationUtils.kt. Notez que vous pouvez appeler directement notify(), car vous effectuez l'appel à partir d'une fonction d'extension de la même classe.

//NotificationUtils.kt
   // TODO: Step 1.4 call notify to send the notification
    // Deliver the notification
    notify(NOTIFICATION_ID, builder.build())
  1. Ouvrez ui/EggTimerViewModel.kt et recherchez la fonction startTimer(). Cette fonction crée une alarme avec l'intervalle de temps sélectionné lorsque l'utilisateur active le minuteur.
  2. Vous déclencherez une notification dans cette fonction lorsque l'utilisateur lancera le minuteur. Pour appeler la fonction sendNotification() que vous avez précédemment implémentée, vous avez besoin d'une instance de NotificationManager. NotificationManager est un service système qui fournit toutes les fonctions exposées pour l'API Notifications, y compris la fonction d'extension que vous avez ajoutée. Chaque fois que vous souhaitez envoyer, annuler ou mettre à jour une notification, vous devez demander une instance du NotificationManager au système. Appelez la fonction sendNotification()| avec le message de notification et le contexte.
// EggTimerViewModel.kt
// TODO: Step 1.5 get an instance of NotificationManager 
// and call sendNotification

val notificationManager = ContextCompat.getSystemService(
    app, 
    NotificationManager::class.java
) as NotificationManager
                notificationManager.sendNotification(app.getString(R.string.timer_running), app)

Vous avez presque terminé. Cependant, si vous exécutez l'application maintenant et définissez le minuteur, vous ne recevrez pas de notification.

  1. Ouvrez logcat et recherchez "No Channel found". Vous devriez voir un message d'erreur indiquant que egg_channel n'existe pas. La procédure suivante vous permettra d'en savoir plus sur les canaux de notification et de résoudre le problème.

Étape 2: Canaux de notification

À partir du niveau d'API 26, toutes les notifications doivent être attribuées à une chaîne. Si vous appuyez de manière prolongée sur l'icône du lanceur d'applications, sélectionnez "Informations sur l'application", puis appuyez sur "Notifications". La liste des canaux de notification associés à l'application s'affiche pour le moment. La liste est vide, car votre application n'a créé aucune chaîne.

Les canaux représentent un type de notification. Par exemple, votre minuteur peut envoyer une notification lorsque l'œuf est cuit, et vous pouvez utiliser un autre canal pour envoyer des notifications quotidiennes afin de vous rappeler d'ajouter des œufs au petit-déjeuner. Toutes les notifications d'une chaîne sont regroupées, et les utilisateurs peuvent configurer les paramètres de notification pour l'ensemble de leur chaîne. Ainsi, les utilisateurs peuvent personnaliser les paramètres de notification en fonction du type de notification qui les intéresse. Par exemple, vos utilisateurs peuvent désactiver les notifications concernant le petit-déjeuner, mais continuer à les consulter depuis le minuteur.

Les développeurs définissent les paramètres initiaux, l'importance et le comportement, à appliquer à toutes les notifications d'une chaîne. Une fois les paramètres initiaux définis, les utilisateurs peuvent les remplacer.

À l'étape 1.1, vous avez utilisé egg_notification_channel_id comme canal de notification. Vous devez donc créer et personnaliser les paramètres de notification et le comportement de ce canal.

  1. Ouvrez EggTimerFragment.kt et recherchez la fonction createChannel().
  2. Transmettez l'ID de chaîne unique au constructeur de NotificationChannel.
  3. Transmettez le nom du canal de notification que les utilisateurs verront également dans leur écran Paramètres.
  4. En tant que dernier paramètre, transmettez le niveau d'importance du canal de notification. Les niveaux d'importance seront abordés dans la suite de cet atelier de programmation. Pour le moment, vous pouvez utiliser NotificationManager.IMPORTANCE_LOW.
  5. Sur l'objet notificationChannel, définissez enableLights sur "true". Ce paramètre active les voyants lorsqu'une notification s'affiche.
  6. Sur l'objet notificationChannel, définissez lightColor sur rouge pour afficher une lumière rouge lorsqu'une notification s'affiche.
  7. Sur l'objet notificationChannel, définissez enableVibration sur "true" pour activer la vibration.
  8. Sur l'objet notificationChannel, définissez la description de la chaîne sur ‘Time for breakfast'.
  9. Obtenez une instance de NotificationManager en appelant getSystemService().
  10. Appelez createNotificationChannel() sur NotificationManager et transmettez l'objet notificationChannel que vous avez créé à l'étape précédente.
//EggTimerFragment.kt
private fun createChannel(channelId: String, channelName: String) {
    // TODO: Step 1.6 START create a channel
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        val notificationChannel = NotificationChannel(
            channelId,
            channelName,
            // TODO: Step 2.4 change importance
            NotificationManager.IMPORTANCE_LOW
        )
        // TODO: Step 2.6 disable badges for this channel

        notificationChannel.enableLights(true)
        notificationChannel.lightColor = Color.RED
        notificationChannel.enableVibration(true)
        notificationChannel.description = "Time for breakfast"

        val notificationManager = requireActivity().getSystemService(
            NotificationManager::class.java
        )
        notificationManager.createNotificationChannel(notificationChannel)
    }
    // TODO: Step 1.6 END create channel
}
  1. Ensuite, pour créer un canal, vous devez appeler la fonction createChannel() que vous venez d'écrire (étape 1.7). Cette fonction utilise deux paramètres : l'ID de la chaîne et son nom. Vous devez rechercher l'ID et le nom de la chaîne à partir des ressources de chaîne déjà fournies dans votre projet.
// EggTimerFragment.kt
    // TODO: Step 1.7 call createChannel
    createChannel(
          getString(R.string.egg_notification_channel_id),
          getString(R.string.egg_notification_channel_name)
    )
  1. Vous devez transmettre l'ID de la chaîne à l'outil de création de notifications. Vous l'avez déjà fait à l'étape 1.2. Si vous définissez une valeur incorrecte pour l'ID de la chaîne, la notification échouera. Ouvrez NotificationUtils.kt pour vérifier que l'ID de la chaîne que vous avez précédemment défini est correct.
// NotificationUtils.kt
val builder = NotificationCompat.Builder(
        applicationContext,
       // TODO: Step 1.8 verify the notification channel name
        applicationContext.getString(R.string.egg_notification_channel_id)
)
  1. Exécutez l'application. L'application envoie une notification à chaque fois que vous lancez le minuteur.
  2. Tirez sur la barre d'état et observez comment vous avez défini le titre, le contenu et l'icône de la notification lors des étapes précédentes.
  3. Pour faire valider votre chaîne, fermez l'application et repérez l'icône correspondante. Appuyez de manière prolongée sur l'icône de l'application, puis sélectionnez Infos sur l'appli.

  1. Dans la liste des paramètres, sélectionnez Notifications. Vous devriez voir une nouvelle chaîne intitulée Egg, juste en dessous du paramètre Show notifications (Afficher les notifications).

Lorsque vous exécutez l'application, la notification s'affiche. En tant que développeur de l'application, vous pouvez personnaliser vos paramètres et votre comportement pour toutes les notifications envoyées sur cette chaîne. Félicitations, vous avez créé une notification !

Étape 3: Ajoutez des notifications à votre application

Jusqu'à présent, cela montre l'utilisation de base de l'API Notifications, mais l'envoi d'une notification juste après le démarrage du minuteur n'a pas de sens. Il est probable que les utilisateurs reçoivent une notification lorsque l'œuf est prêt. Dans la partie suivante de l'atelier de programmation, vous allez résoudre ce problème et remplacer le message de toast par une notification.

Vous avez déjà envoyé la notification et observé sa présentation aux utilisateurs, mais il ne s'agissait que de la première étape pour créer des notifications de qualité. Dans cette étape, vous allez modifier votre notification pour l'envoyer à un moment plus approprié.

Votre appli utilise AlarmManager pour configurer une alarme. Le code associé à AlarmManager est déjà indiqué dans le code de démarrage et utilisé pour afficher le message de toast. AlarmManager effectue le suivi de l'heure sélectionnée et déclenche la fonction onReceive() de AlarmReceiver.kt lorsque la durée est écoulée. Si vous ouvrez AlarmReceiver.kt et accédez à onReceive(), vous devez voir le message perdu s'afficher chaque fois que vous configurez un minuteur.

  1. Ouvrez AlarmReceiver.kt, une instance de NotificationManager, puis appelez la fonction sendNotification() avec le texte du message et les paramètres de contexte.
// AlarmReceiver.kt
   // TODO: Step 1.9 add call to sendNotification
   val notificationManager = ContextCompat.getSystemService(
       context, 
       NotificationManager::class.java
   ) as NotificationManager
             
   notificationManager.sendNotification(
       context.getText(R.string.eggs_ready).toString(), 
       context
   )
  1. Vous pouvez également supprimer le toast, car votre application enverra une notification lorsque le minuteur sera terminé.
// AlarmReceiver.kt
     // TODO: Step 1.10 [Optional] remove toast
//   Toast.makeText(
//       context, 
//       context.getText(R.string.eggs_ready),
//       Toast.LENGTH_SHORT
//   ).show()
  1. Exécutez votre application . Vous devriez voir une notification chaque fois que vous lancez le minuteur et chaque fois qu'il est écoulé.

Ce n'est pas idéal. Vous ne souhaitez pas envoyer trop de notifications à vos utilisateurs. Vous pouvez supprimer la première notification envoyée au démarrage du minuteur.

  1. Ouvrez EggTimerFragment.kt et supprimez le code de notification pour l'étape 1.5.
// EggTimeViewModel.kt

// TODO: Step 1.5 get an instance of NotificationManager 
// and call sendNotification
// val notificationManager = ContextCompat.getSystemService(
//      app,
//      NotificationManager::class.java
// ) as NotificationManager
// notificationManager.sendNotification(app.getString(R.string.eggs_ready), app)
  1. Exécutez à nouveau l'application.
  2. Définissez un minuteur, mettez-le en arrière-plan et attendez que l'opération se termine. Une notification s'affiche. Cette notification est bien plus utile.

Étape 4: Ajoutez un intent de contenu

  1. Exécutez à nouveau l'application, si elle n'est pas déjà en cours d'exécution.
  2. Cliquez sur la notification. Il ne se passe rien !

Afficher la notification et informer l'utilisateur est une bonne idée. Toutefois, lorsqu'un utilisateur clique sur une notification, il s'attend à revenir à l'application correspondante. Dans cette partie de l'atelier de programmation, vous allez ajouter un intent à votre notification pour le renvoyer à l'écran du minuteur.

Un Intent est un objet de messagerie que vous pouvez utiliser pour demander une action à partir d'un autre composant d'application. Les intents peuvent être utilisés pour démarrer une activité, un service ou diffuser une diffusion. Dans ce cas, cet intent sert à indiquer au système d'ouvrir MainActivity lorsque l'utilisateur appuie sur la notification. Étant donné que votre application ne comporte qu'une seule vue, vous n'avez pas beaucoup d'options ici. Toutefois, dans une application plus large, la notification devrait permettre de créer une expérience fluide en redirigeant l'utilisateur vers un écran logique.

  1. Ouvrez NotificationUtils.kt et recherchez la fonction d'extension sendNotification().
  2. Créez un Intent avec votre applicationContext et l'activité à lancer, MainActivity::class.java.
// NotificationUtils.kt

fun NotificationManager.sendNotification(messageBody: String, applicationContext: Context) {
    // Create the content intent for the notification, which launches
    // this activity
   // TODO: Step 1.11 create intent
    val contentIntent = Intent(applicationContext, MainActivity::class.java)

Vous avez créé l'intent, mais la notification s'affiche en dehors de votre appli. Pour que l'intent fonctionne en dehors de votre appli, vous devez créer un autre PendingIntent.

PendingIntent accorde des droits à une autre application ou au système pour effectuer une opération au nom de votre application. Un PendingIntent lui-même est simplement une référence à un jeton géré par le système qui décrit les données d'origine utilisées pour le récupérer. Cela signifie que même si le processus d'application propriétaire est tué, le PendingIntent lui-même pourra être utilisé pour les autres processus auxquels il a été attribué. Dans ce cas, le système utilise l'intent en attente pour ouvrir l'application en votre nom, que l'application de minuteur soit ou non en cours d'exécution.

  1. Créez un PendingIntent avec applicationContext, NOTIFICATION_ID, le contentIntent que vous avez créé à l'étape précédente et l'indicateur PendingIntent. L'option PendingIntent spécifie l'option permettant de créer un objet PendingIntent ou d'en utiliser un existant. Vous devez définir PendingIntent.FLAG_UPDATE_CURRENT comme indicateur, car vous ne souhaitez pas créer de notification s'il en existe une. De cette façon, vous modifierez le PendingIntent actuel associé à l'intent que vous fournissez.
// NotificationUtils.kt
   // TODO: Step 1.12 create PendingIntent
    val contentPendingIntent = PendingIntent.getActivity(
        applicationContext, 
        NOTIFICATION_ID,
        contentIntent,
        PendingIntent.FLAG_UPDATE_CURRENT
    )
  1. Transmettez l'PendingIntent à votre notification. Pour ce faire, appelez setContentIntent() sur le NotificationBuilder. Désormais, lorsque vous cliquez sur la notification, le PendingIntent est déclenché, ce qui ouvre votre MainActivity.
  2. Définissez également l'option setAutoCancel() sur true. Ainsi, lorsque l'utilisateur appuie sur la notification, la notification s'arrête et accède à l'application.
// NotificationUtils.kt
    // TODO: Step 1.13 set content intent
    .setContentIntent(contentPendingIntent)
    .setAutoCancel(true)
  1. Exécutez à nouveau l'application.
  2. Définissez un minuteur, mettez l'application en arrière-plan et attendez que la notification s'affiche.
  3. Lorsque la notification s'affiche, cliquez dessus en faisant glisser la barre d'état vers le bas et observez comment l'application est exécutée au premier plan.

Étape 5: Annulez la notification

Vous disposez d'un minuteur opérationnel avec des notifications, mais il y a un petit problème. Si vous réglez le minuteur, recevez une notification et définissez de nouveau le minuteur, la notification précédente reste dans la barre d'état pendant que le nouveau minuteur est en cours d'exécution. Cela peut perturber votre utilisateur si l'application est en arrière-plan, et cela peut entraîner une baisse du nombre d'œufs.

Pour résoudre ce problème, vous devez effacer la notification précédente lorsque vous démarrez un nouveau minuteur. Commencez par créer une autre fonction d'extension dans NotificationUtils.kt. NotificationManager dispose d'une API pour annuler toutes les notifications actives appelées cancelAll().

  1. Ouvrez NotificationsUtil.kt.
  2. Ajoutez sur NotificationManager une fonction d'extension qui appelle cancelAll().
// NotificationUtils.kt

// TODO: Step 1.14 Cancel all notifications
/**
 * Cancels all notifications.
 *
 */
fun NotificationManager.cancelNotifications() {
    cancelAll()
}
  1. Ouvrez EggTimerViewModel.kt et accédez à la fonction startTimer().
  2. Dans startTimer(), obtenez une instance de NotificationManager à partir du système et appelez cancelNotifications().
//  EggTimerViewModel.kt
   //TODO Step 1.15 call cancel notification
    val notificationManager =
       ContextCompat.getSystemService(
            app,
            NotificationManager::class.java
        ) as NotificationManager
    notificationManager.cancelNotifications()       
  1. Exécutez l'application et lancez le minuteur.
  2. Une fois la notification affichée, redémarrez le minuteur et observez comment notre application supprime automatiquement la notification précédente de la barre d'état.

Le framework de notifications offre aux développeurs différentes options de personnalisation, permettant de définir des actions personnalisées et de styliser les notifications selon leurs besoins. Pendant cette tâche, vous allez apprendre à personnaliser les notifications du minuteur.

Étape 1: Définissez le style de vos notifications

Si vous donnez un style à votre notification en fonction de vos besoins et de son contenu, le contenu de vos notifications se démarque et ressemble à une extension de votre application. Le framework de notification intègre plusieurs styles conçus pour vous aider. Vous pouvez toujours créer les vôtres.

NotificationCompat propose des styles intégrés pour:

  • BigTextStyle, qui peut afficher un grand bloc de texte (par exemple, l'affichage d'un contenu lorsqu'il est développé).
  • BigPictureStyle, qui affiche des notifications en grand format incluant une pièce jointe volumineuse.
  • InboxStyle, qui affiche un contenu textuel de style conversation.
  • MediaStyle, qui affiche les commandes de lecture de contenus multimédias.
  • MessagingStyle, qui affiche des notifications en mode grand format incluant plusieurs messages entre un nombre de personnes.

Pour en savoir plus sur les autres styles, consultez la documentation Créer une notification extensible. Dans cette étape, vous allez utiliser NotificationCompat.BigPictureStyle pour créer une notification extensible qui affiche une grande image de l'œuf lors de son expansion.

  1. Ouvrez NotificationUtils.kt et recherchez la fonction sendNotification().
  2. Commencez par charger une image à partir de resources à l'aide de BitmapFactory.
// NotificationUtils.kt

// TODO: Step 2.0 add style
val eggImage = BitmapFactory.decodeResource(
     applicationContext.resources, 
     R.drawable.cooked_egg
)
  1. Créez un objet BigPictureStyle et définissez votre image.
  2. Définissez bigLargeIcon() sur null pour que la grande icône disparaît lorsque la notification est développée.
// NotificationUtils.kt

// TODO: Step 2.0 add style
val eggImage = BitmapFactory.decodeResource(
     applicationContext.resources, 
     R.drawable.cooked_egg
)
val bigPicStyle = NotificationCompat.BigPictureStyle()
        .bigPicture(eggImage)
        .bigLargeIcon(null)
  1. Définissez le style avec setStyle() sur bigPicStyle.
  2. Définissez l'icône représentant setLargeIcon() sur eggImage. Ainsi, l'image s'affichera en plus petite taille lorsque la notification sera réduite.
// NotificationUtils.kt
// TODO: Step 2.1 add style to builder
.setStyle(bigPicStyle)
.setLargeIcon(eggImage)
  1. Exécutez l'application et définissez un minuteur. Lorsque la notification s'affiche pour la première fois, elle est réduite dans le panneau des notifications. Si vous développez la notification, une grande image s'affiche dans la zone de notification étendue.

Étape 2: Actions de notification

Les actions de notification sont une autre personnalisation que vous pouvez ajouter à vos notifications. Actuellement, vos notifications redirigent les utilisateurs vers votre application lorsque les utilisateurs cliquent dessus. Vous pouvez également ajouter des boutons d'action permettant d'effectuer une tâche liée à une application depuis la notification.

Une notification peut proposer jusqu'à trois boutons d'action qui permettent à l'utilisateur de répondre rapidement, par exemple pour mettre en attente un rappel ou répondre à un SMS. Ces boutons d'action ne doivent pas dupliquer l'action effectuée lorsque l'utilisateur appuie sur la notification.

Pour ajouter un bouton d'action, transmettez un PendingIntent à la fonction addAction() de l'outil de création. Cette action est semblable à la configuration d'une pression par défaut de la notification en appelant setContentIntent(), sauf qu'au lieu de lancer une activité, vous pouvez effectuer plusieurs autres tâches, par exemple lancer une BroadcastReceiver qui exécute une tâche en arrière-plan afin que l'action n'interrompt pas l'application déjà ouverte.

Dans cet atelier de programmation, un BoadcastReceiver nommé SnoozeReceiver vous est déjà attribué. Vous allez utiliser SnoozeReceiver pour que l'utilisateur clique sur l'action "Notification". Dans les étapes suivantes, vous allez ajouter du code pour répéter la notification du minuteur pendant 60 secondes lorsque l'utilisateur cliquera sur le bouton de mise en attente. Lorsque l'utilisateur clique sur l'action "Répéter", SnoozeReceiver reçoit un intent et crée une alarme pour envoyer une nouvelle notification au bout de 60 secondes.

  1. Ouvrez SnoozeReceiver.kt. Cette classe est semblable à AlarmReceiver que vous avez utilisée précédemment. Dans les étapes suivantes, vous allez ajouter du code qui déclenchera la fonction onReceive() de SnoozeReceiver. En résumé, le code de SnoozeReceiver créera une alarme pour envoyer une nouvelle notification une minute plus tard. Faites défiler vers le bas la fonction onReceive, obtenez une instance de notificationManager à partir du système, puis appelezcancelAll.
// SnoozeReceiver.kt
        val notificationManager = ContextCompat.getSystemService(
            context,
            NotificationManager::class.java
        ) as NotificationManager
        notificationManager.cancelAll()
  1. Pour utiliser SnoozeReceiver, ouvrez NotificationUtils.kt.
  2. Créez un Intent snoozeIntent pour le SnoozeReceiver juste après le style dans la fonction sendNotification().
  3. Créez un intent en attente en appelant la méthode getBroadcast() sur PendingIntent, qui attend les paramètres des étapes suivantes. PendingIntent Permet au système de configurer une nouvelle alarme pour publier une nouvelle notification au bout de 60 secondes lorsque l'utilisateur appuiera sur le bouton de répétition.
  4. Le premier paramètre est le contexte de l'application dans lequel PendingIntent doit démarrer l'activité.
  5. Le deuxième paramètre est le code de requête, qui est le code de requête de cet intent en attente. Pour mettre à jour ou annuler cet intent en attente, vous devez accéder à l'intent en attente à l'aide de ce code.
  6. Ensuite, ajoutez l'objet snoozeIntent, qui correspond à l'intent de l'activité à lancer.
  7. Enfin, ajoutez la valeur de l'indicateur #FLAG_ONE_SHOT, car l'intent n'est utilisé qu'une seule fois. L'action rapide et la notification disparaissent après le premier appui. C'est pourquoi l'intent ne peut être utilisé qu'une seule fois.
// NotificationUtils.kt

// TODO: Step 2.2 add snooze action
val snoozeIntent = Intent(applicationContext, SnoozeReceiver::class.java)
val snoozePendingIntent: PendingIntent = PendingIntent.getBroadcast(
    applicationContext, 
    REQUEST_CODE, 
    snoozeIntent, 
    FLAGS
)
  1. Ensuite, appelez la fonction addAction() sur notificationBuilder. Elle attend une icône et un texte pour décrire votre action à l'utilisateur. Vous devez également ajouter snoozeIntent. Cet intent sera utilisé pour déclencher le boadcastReceiver correct lorsqu'un utilisateur clique sur votre action.
// NotificationUtils.kt
// TODO: Step 2.3 add snooze action
.addAction(
    R.drawable.egg_icon, 
    applicationContext.getString(R.string.snooze),
    snoozePendingIntent
)
  1. Exécutez le minuteur pour tester l'action de mise en attente.
  2. Exécutez le minuteur et mettez l'application en arrière-plan. Une fois le délai dépassé, développez la notification. Vous verrez alors qu'un bouton d'action de mise en attente permet de répéter le minuteur pour une nouvelle minute.

Étape 3: Importance des notifications

L'importance détermine dans quelle mesure la notification doit interrompre l'utilisateur de façon visuelle et audible. Les notifications d'une importance plus élevée interrompront davantage l'activité des utilisateurs.

Vous devez spécifier le niveau d'importance dans le constructeur NotificationChannel. Vous avez initialement défini un niveau d'importance faible pour l'application de minuteur. Vous pouvez utiliser l'un des cinq niveaux d'importance, de IMPORTANCE_NONE(0) à IMPORTANCE_HIGH(4). Le niveau d'importance que vous attribuez à une chaîne s'applique à tous les messages de notification que vous publiez.

Niveaux d'importance des chaînes

Niveau d'importance visible par l'utilisateur

Importance (Android 8.0 ou version ultérieure)

Priorité (Android 7.1 ou version antérieure)

Émet un son et se présente sous la forme d'un avertissement (apparaît en haut de l'écran)

IMPORTANCE_HIGH

PRIORITY_HIGH / PRIORITY_MAX

Émet un son

IMPORTANCE_DEFAULT

PRIORITY_DEFAULT

Aucun son

IMPORTANCE_BAS

PRIORITY_LOW

Aucun son et n'apparaît pas dans la barre d'état

IMPORTANCE_MIN

PRIORITY_MIN

Pour en savoir plus sur le choix d'un niveau de priorité approprié, consultez la section "Niveaux de priorité" dans le guide de conception des notifications. Soyez prudent lorsque vous sélectionnez un niveau d'importance pour les notifications dans votre application. Choisissez le niveau d'importance de la chaîne en tenant compte du temps et de l'attention de l'utilisateur. Lorsqu'une notification sans importance est déguisée en urgence, elle peut déclencher une alarme inutile et être gênante. Les utilisateurs contrôlent totalement le niveau d'importance de leurs notifications. Par conséquent, si vous créez une notification gênante, ils peuvent désactiver complètement votre canal de notification.

Lorsque vous avez créé la notification à l'étape 1.6, le minuteur était défini pour envoyer des notifications avec une priorité faible, car il était conçu pour ne pas déranger l'utilisateur avec des notifications. Il peut toutefois être judicieux d'attirer l'attention de l'utilisateur avant que les œufs dépassent. Pour modifier l'importance de la notification, commencez par définir les paramètres de la chaîne. L'importance de la chaîne affecte le niveau d'interruption de toutes les notifications publiées sur la chaîne. Vous devez la spécifier dans le constructeur NotificationChannel.

  1. Pour modifier le niveau d'importance du canal de notification de votre application, ouvrez EggTimerFragment.kt et accédez à createChannel(). Modifiez le niveau d'importance de IMPORTANCE_LOW en IMPORTANCE_HIGH.
// EggTimerFragment.kt
    val notificationChannel = NotificationChannel(
        channelId,
        channelName,
        // TODO: Step 2.4 change importance
        NotificationManager.IMPORTANCE_HIGH
    )

Pour prendre en charge les appareils fonctionnant sous Android 7.1 (API niveau 25) ou une version antérieure, vous devez également appeler setPriority() pour chaque notification, en utilisant une constante de priorité de la classe NotificationCompat.

  1. Ouvrez NotificationUtils.kt et ajoutez ce qui suit à l'objet du générateur de notifications.
// NotificationUtils.kt
   .addAction(
       R.drawable.common_google_signin_btn_icon_dark,
       applicationContext.getString(R.string.snooze),
       snoozePendingIntent
    )
   // TODO: Step 2.5 set priority
    .setPriority(NotificationCompat.PRIORITY_HIGH)
  1. Avant d'exécuter l'application, appuyez de manière prolongée sur l'icône de l'application installée sur votre appareil ou l'émulateur, puis sélectionnez "Désinstaller" pour effacer les paramètres de chaîne précédents. Si vous ne désinstallez pas l'application, les paramètres de priorité de la chaîne ne sont pas modifiés, et le comportement reste inchangé lors de la publication de la notification.
  2. Exécutez de nouveau l'application et lancez le minuteur. Cette fois, une notification devrait s'afficher en haut de l'écran lorsque la notification est envoyée, que l'application soit exécutée au premier plan ou en arrière-plan.

Étape 4: Badges de notification

Les badges de notification sont de petits points qui s'affichent sur l'icône du lanceur de l'application associée lorsque celle-ci comporte une notification active. Les utilisateurs peuvent appuyer de manière prolongée sur l'icône de l'application pour afficher les notifications.

Ces points, appelés badges, s'affichent par défaut et votre application n'a aucune action à effectuer. Cependant, il peut arriver que les badges ne soient pas pertinents pour vos notifications. Vous pouvez donc les désactiver pour chaque chaîne en appelant setShowBadge(false) sur votre objet NotificationChannel. Étant donné que le minuteur ne comporte qu'une notification active à la fois, le badge affiché sur l'icône de votre application ne présente pas d'intérêt majeur pour vos utilisateurs. Dans les étapes suivantes, vous allez désactiver le badge et n'afficher qu'une notification pour le minuteur.

  1. Ajoutez setShowBadge(false) au code de création de la chaîne pour désactiver les badges dans le minuteur.
// EggTimerFragment.kt

    ).apply {
        // TODO: Step 2.6 disable badges for this channel
        setShowBadge(false)
    }
  1. Exécutez de nouveau l'application, démarrez le minuteur et regardez l'icône de l'application. Aucun badge ne doit s'afficher sur l'icône de l'application.

Le code de la solution se trouve dans la branche principale du code téléchargé.

Cours Udacity:

Documentation pour les développeurs Android:

Pour obtenir des liens vers d'autres ateliers de programmation dans ce cours, consultez la page de destination "Avancé Android" dans les ateliers de programmation Kotlin.