Créer une notification

Les notifications fournissent des informations brèves et opportunes sur les événements de votre application lorsque celle-ci n'est pas utilisée. Ce document explique comment créer une notification avec différentes fonctionnalités. Pour en savoir plus sur l'affichage des notifications sur Android, consultez la présentation des notifications. Pour obtenir un exemple de code utilisant des notifications, consultez l'exemple People (Personnes) sur GitHub.

Le code de cette page utilise les API NotificationCompat de la bibliothèque AndroidX. Ces API vous permettent d'ajouter des fonctionnalités disponibles uniquement sur les versions plus récentes d'Android, tout en offrant la compatibilité avec Android 9 (niveau d'API 28). Cependant, certaines fonctionnalités, telles que l'action de réponse intégrée, entraînent une no-op sur les versions antérieures.

Ajouter la bibliothèque principale AndroidX

Bien que la plupart des projets créés avec Android Studio incluent les dépendances nécessaires pour utiliser NotificationCompat, vérifiez que votre fichier build.gradle au niveau du module inclut la dépendance suivante:

Groovy

dependencies {
    implementation "androidx.core:core:2.2.0"
}

Kotlin

dependencies {
    implementation("androidx.core:core-ktx:2.2.0")
}

Créer une notification de base

Dans sa forme la plus basique et compacte (également appelée forme réduite), une notification affiche une icône, un titre et une petite quantité de texte. Cette section explique comment créer une notification sur laquelle l'utilisateur peut appuyer pour lancer une activité dans votre application.

Figure 1 : Une notification avec une icône, un titre et du texte.

Pour en savoir plus sur chaque partie d'une notification, consultez l'article sur l'anatomie des notifications.

Déclarer l'autorisation d'exécution

Android 13 (niveau d'API 33) ou version ultérieure est compatible avec une autorisation d'exécution pour publier des notifications non exemptées (y compris les services de premier plan) à partir d'une application.

L'autorisation que vous devez déclarer dans le fichier manifeste de votre application apparaît dans l'extrait de code suivant:

<manifest ...>
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
    <application ...>
        ...
    </application>
</manifest>

Pour en savoir plus sur les autorisations d'exécution, consultez la section Autorisation d'exécution de notification.

Définir le contenu des notifications

Pour commencer, définissez le contenu et le canal de la notification à l'aide d'un objet NotificationCompat.Builder. L'exemple suivant montre comment créer une notification avec les éléments suivants:

  • Une petite icône, définie par setSmallIcon(). Il s'agit du seul contenu visible par l'utilisateur qui soit obligatoire.

  • Un titre, défini par setContentTitle().

  • Corps du texte, défini par setContentText().

  • La priorité de notification, définie par setPriority(). La priorité détermine le niveau d'intrusion de la notification sur Android 7.1 et les versions antérieures. Pour Android 8.0 et versions ultérieures, définissez plutôt l'importance du canal comme indiqué dans la section suivante.

Kotlin

var builder = NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle(textTitle)
        .setContentText(textContent)
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)

Java

NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle(textTitle)
        .setContentText(textContent)
        .setPriority(NotificationCompat.PRIORITY_DEFAULT);

Le constructeur NotificationCompat.Builder nécessite que vous fournissiez un ID de canal. Cette étape est obligatoire pour assurer la compatibilité avec Android 8.0 (niveau d'API 26) et les versions ultérieures, mais elle est ignorée par les versions antérieures.

Par défaut, le contenu textuel de la notification est tronqué afin de tenir sur une ligne. Vous pouvez afficher des informations supplémentaires en créant une notification à développer.

Figure 2. Notification à développer dans ses formes réduites et développées.

Si vous souhaitez qu'elle soit plus longue, vous pouvez activer une notification à développer en ajoutant un modèle de style avec setStyle(). Par exemple, le code suivant crée une zone de texte plus grande:

Kotlin

var builder = NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Much longer text that cannot fit one line...")
        .setStyle(NotificationCompat.BigTextStyle()
                .bigText("Much longer text that cannot fit one line..."))
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)

Java

NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Much longer text that cannot fit one line...")
        .setStyle(new NotificationCompat.BigTextStyle()
                .bigText("Much longer text that cannot fit one line..."))
        .setPriority(NotificationCompat.PRIORITY_DEFAULT);

Pour en savoir plus sur les autres styles de notification volumineux, y compris sur l'ajout d'une image et de commandes de lecture multimédia, consultez Créer une notification à développer.

Créez un canal et définissez son importance

Avant de pouvoir envoyer la notification sur Android 8.0 ou version ultérieure, enregistrez le canal de notification de votre application auprès du système en transmettant une instance de NotificationChannel à createNotificationChannel(). Le code suivant est bloqué par une condition dans la version de SDK_INT:

Kotlin

private fun createNotificationChannel() {
    // Create the NotificationChannel, but only on API 26+ because
    // the NotificationChannel class is not in the Support Library.
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        val name = getString(R.string.channel_name)
        val descriptionText = getString(R.string.channel_description)
        val importance = NotificationManager.IMPORTANCE_DEFAULT
        val channel = NotificationChannel(CHANNEL_ID, name, importance).apply {
            description = descriptionText
        }
        // Register the channel with the system.
        val notificationManager: NotificationManager =
            getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        notificationManager.createNotificationChannel(channel)
    }
}

Java

private void createNotificationChannel() {
    // Create the NotificationChannel, but only on API 26+ because
    // the NotificationChannel class is not in the Support Library.
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        CharSequence name = getString(R.string.channel_name);
        String description = getString(R.string.channel_description);
        int importance = NotificationManager.IMPORTANCE_DEFAULT;
        NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
        channel.setDescription(description);
        // Register the channel with the system; you can't change the importance
        // or other notification behaviors after this.
        NotificationManager notificationManager = getSystemService(NotificationManager.class);
        notificationManager.createNotificationChannel(channel);
    }
}

Étant donné que vous devez créer le canal de notification avant de publier des notifications sur Android 8.0 et versions ultérieures, exécutez ce code dès le démarrage de votre application. Vous pouvez appeler cette méthode à plusieurs reprises, car la création d'un canal de notification existant n'entraîne aucune opération.

Le constructeur NotificationChannel nécessite un élément importance, en utilisant l'une des constantes de la classe NotificationManager. Ce paramètre détermine comment interrompre l'utilisateur pour toute notification appartenant à ce canal. Définissez la priorité avec setPriority() pour prendre en charge Android 7.1 et les versions antérieures, comme indiqué dans l'exemple précédent.

Bien que vous deviez définir l'importance ou la priorité des notifications comme indiqué dans l'exemple suivant, le système ne garantit pas le comportement de l'alerte que vous obtiendrez. Dans certains cas, le système peut modifier le niveau d'importance en fonction d'autres facteurs, et l'utilisateur peut toujours redéfinir le niveau d'importance pour un canal donné.

Pour en savoir plus sur la signification des différents niveaux, consultez la section Niveaux d'importance des notifications.

Définir l'action tactile de la notification

Chaque notification doit répondre à un appui, généralement pour ouvrir une activité correspondant à la notification dans votre application. Pour ce faire, spécifiez un intent de contenu défini avec un objet PendingIntent et transmettez-le à setContentIntent().

L'extrait de code suivant montre comment créer un intent de base pour ouvrir une activité lorsque l'utilisateur appuie sur la notification:

Kotlin

// Create an explicit intent for an Activity in your app.
val intent = Intent(this, AlertDetails::class.java).apply {
    flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
val pendingIntent: PendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE)

val builder = NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        // Set the intent that fires when the user taps the notification.
        .setContentIntent(pendingIntent)
        .setAutoCancel(true)

Java

// Create an explicit intent for an Activity in your app.
Intent intent = new Intent(this, AlertDetails.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE);

NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        // Set the intent that fires when the user taps the notification.
        .setContentIntent(pendingIntent)
        .setAutoCancel(true);

Ce code appelle setAutoCancel(), qui supprime automatiquement la notification lorsque l'utilisateur appuie dessus.

La méthode setFlags() illustrée dans l'exemple précédent conserve l'expérience de navigation attendue par l'utilisateur une fois qu'il a ouvert votre application à l'aide de la notification. Vous pouvez l'utiliser en fonction du type d'activité que vous lancez, par exemple:

  • Activité qui existe exclusivement pour les réponses à la notification. Il n'y a aucune raison que l'utilisateur accède à cette activité lors de l'utilisation normale de l'application. L'activité démarre donc une nouvelle tâche au lieu d'être ajoutée à la tâche et la pile "Retour" existantes de votre application. Il s'agit du type d'intent créé dans l'exemple précédent.

  • Une activité qui existe dans le flux d'application standard de votre application. Dans ce cas, le démarrage de l'activité crée une pile "Retour" afin de conserver les attentes de l'utilisateur concernant les boutons "Retour" et "Haut".

Pour en savoir plus sur les différentes façons de configurer l'intent de votre notification, consultez la section Démarrer une activité à partir d'une notification.

Afficher la notification

Pour que la notification s'affiche, appelez NotificationManagerCompat.notify() en lui transmettant un identifiant unique pour la notification et le résultat de NotificationCompat.Builder.build(). Ce processus est illustré dans l'exemple suivant :

Kotlin

with(NotificationManagerCompat.from(this)) {
    if (ActivityCompat.checkSelfPermission(
            this@MainActivity,
            Manifest.permission.POST_NOTIFICATIONS
        ) != PackageManager.PERMISSION_GRANTED
    ) {
        // TODO: Consider calling
        // ActivityCompat#requestPermissions
        // here to request the missing permissions, and then overriding
        // public fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>,
        //                                        grantResults: IntArray)
        // to handle the case where the user grants the permission. See the documentation
        // for ActivityCompat#requestPermissions for more details.

        return@with
    }
    // notificationId is a unique int for each notification that you must define.
    notify(NOTIFICATION_ID, builder.build())
}

Java

with(NotificationManagerCompat.from(this)) {
   if (ActivityCompat.checkSelfPermission(
           this@MainActivity,
           Manifest.permission.POST_NOTIFICATIONS
       ) != PackageManager.PERMISSION_GRANTED
   ) {
       // TODO: Consider calling
       // ActivityCompat#requestPermissions
       // here to request the missing permissions, and then overriding
       // public void onRequestPermissionsResult(int requestCode, String[] permissions,
       //                                        int[] grantResults)
       // to handle the case where the user grants the permission. See the documentation
       // for ActivityCompat#requestPermissions for more details.

       return
   }
   // notificationId is a unique int for each notification that you must define.
   notify(NOTIFICATION_ID, builder.build())
}

Enregistrez l'ID de notification que vous transmettez à NotificationManagerCompat.notify(), car vous en aurez besoin pour mettre à jour ou supprimer la notification.

En outre, afin de tester les notifications de base sur les appareils équipés d'Android 13 ou version ultérieure, activez les notifications manuellement ou créez une boîte de dialogue pour demander des notifications.

Ajouter des boutons d'action

Une notification peut comporter jusqu'à trois boutons d'action permettant à l'utilisateur de répondre rapidement, par exemple pour répéter un rappel ou répondre à un SMS. Toutefois, ces boutons d'action ne doivent pas reproduire l'action effectuée lorsque l'utilisateur appuie sur la notification.

Figure 3. Une notification avec un bouton d'action.

Pour ajouter un bouton d'action, transmettez un PendingIntent à la méthode addAction(). Cela revient à configurer l'action tactile par défaut de la notification, sauf qu'au lieu de lancer une activité, vous pouvez effectuer d'autres opérations, par exemple démarrer un BroadcastReceiver qui effectue une tâche en arrière-plan afin que cette action n'interrompt pas l'application déjà ouverte.

Par exemple, le code suivant montre comment envoyer une annonce à un destinataire spécifique:

Kotlin


val ACTION_SNOOZE = "snooze"

val snoozeIntent = Intent(this, MyBroadcastReceiver::class.java).apply {
    action = ACTION_SNOOZE
    putExtra(EXTRA_NOTIFICATION_ID, 0)
}
val snoozePendingIntent: PendingIntent =
    PendingIntent.getBroadcast(this, 0, snoozeIntent, 0)
val builder = NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        .setContentIntent(pendingIntent)
        .addAction(R.drawable.ic_snooze, getString(R.string.snooze),
                snoozePendingIntent)

Java


String ACTION_SNOOZE = "snooze"

Intent snoozeIntent = new Intent(this, MyBroadcastReceiver.class);
snoozeIntent.setAction(ACTION_SNOOZE);
snoozeIntent.putExtra(EXTRA_NOTIFICATION_ID, 0);
PendingIntent snoozePendingIntent =
        PendingIntent.getBroadcast(this, 0, snoozeIntent, 0);

NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        .setContentIntent(pendingIntent)
        .addAction(R.drawable.ic_snooze, getString(R.string.snooze),
                snoozePendingIntent);

Pour savoir comment créer un BroadcastReceiver afin d'exécuter des tâches en arrière-plan, consultez la section Présentation des diffusions.

Si vous essayez plutôt de créer une notification avec des boutons de lecture multimédia (pour mettre en pause et passer des titres, par exemple), découvrez comment créer une notification avec des commandes multimédias.

Ajouter une action de réponse directe

L'action de réponse directe, introduite dans Android 7.0 (niveau d'API 24), permet aux utilisateurs de saisir du texte directement dans la notification. Le texte est ensuite envoyé à votre application sans ouvrir d'activité. Par exemple, vous pouvez utiliser une action de réponse directe pour permettre aux utilisateurs de répondre à des SMS ou de mettre à jour des listes de tâches depuis la notification.

Figure 4. Appuyez sur le bouton « Répondre » ouvre la saisie de texte.

L'action de réponse directe apparaît sous la forme d'un bouton supplémentaire dans la notification qui ouvre une entrée de texte. Une fois la saisie terminée, le système joint la réponse textuelle à l'intent que vous spécifiez pour l'action de notification et envoie l'intent à votre application.

Ajouter le bouton de réponse

Pour créer une action de notification compatible avec la réponse directe, procédez comme suit:

  1. Créez une instance de RemoteInput.Builder que vous pouvez ajouter à votre action de notification. Le constructeur de cette classe accepte une chaîne que le système utilise comme clé pour l'entrée de texte. Votre application utilisera ensuite cette clé pour récupérer le texte de l'entrée.

    Kotlin

      // Key for the string that's delivered in the action's intent.
      private val KEY_TEXT_REPLY = "key_text_reply"
      var replyLabel: String = resources.getString(R.string.reply_label)
      var remoteInput: RemoteInput = RemoteInput.Builder(KEY_TEXT_REPLY).run {
          setLabel(replyLabel)
          build()
      }
      

    Java

      // Key for the string that's delivered in the action's intent.
      private static final String KEY_TEXT_REPLY = "key_text_reply";
    
      String replyLabel = getResources().getString(R.string.reply_label);
      RemoteInput remoteInput = new RemoteInput.Builder(KEY_TEXT_REPLY)
              .setLabel(replyLabel)
              .build();
      
  2. Créez un PendingIntent pour l'action de réponse.

    Kotlin

      // Build a PendingIntent for the reply action to trigger.
      var replyPendingIntent: PendingIntent =
          PendingIntent.getBroadcast(applicationContext,
              conversation.getConversationId(),
              getMessageReplyIntent(conversation.getConversationId()),
              PendingIntent.FLAG_UPDATE_CURRENT)
      

    Java

      // Build a PendingIntent for the reply action to trigger.
      PendingIntent replyPendingIntent =
              PendingIntent.getBroadcast(getApplicationContext(),
                      conversation.getConversationId(),
                      getMessageReplyIntent(conversation.getConversationId()),
                      PendingIntent.FLAG_UPDATE_CURRENT);
      
  3. Associez l'objet RemoteInput à une action à l'aide de addRemoteInput().

    Kotlin

      // Create the reply action and add the remote input.
      var action: NotificationCompat.Action =
          NotificationCompat.Action.Builder(R.drawable.ic_reply_icon,
              getString(R.string.label), replyPendingIntent)
              .addRemoteInput(remoteInput)
              .build()
      

    Java

      // Create the reply action and add the remote input.
      NotificationCompat.Action action =
              new NotificationCompat.Action.Builder(R.drawable.ic_reply_icon,
                      getString(R.string.label), replyPendingIntent)
                      .addRemoteInput(remoteInput)
                      .build();
      
  4. Appliquez l'action à une notification, puis envoyez-la.

    Kotlin

      // Build the notification and add the action.
      val newMessageNotification = Notification.Builder(context, CHANNEL_ID)
              .setSmallIcon(R.drawable.ic_message)
              .setContentTitle(getString(R.string.title))
              .setContentText(getString(R.string.content))
              .addAction(action)
              .build()
    
      // Issue the notification.
      with(NotificationManagerCompat.from(this)) {
          notificationManager.notify(notificationId, newMessageNotification)
      }
      

    Java

      // Build the notification and add the action.
      Notification newMessageNotification = new Notification.Builder(context, CHANNEL_ID)
              .setSmallIcon(R.drawable.ic_message)
              .setContentTitle(getString(R.string.title))
              .setContentText(getString(R.string.content))
              .addAction(action)
              .build();
    
      // Issue the notification.
      NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
      notificationManager.notify(notificationId, newMessageNotification);
      

Le système invite l'utilisateur à saisir une réponse lorsqu'il déclenche l'action de notification, comme illustré dans la figure 4.

Récupérer les entrées utilisateur à partir de la réponse

Pour recevoir des entrées utilisateur à partir de l'UI de réponse de la notification, appelez RemoteInput.getResultsFromIntent(), en lui transmettant le Intent reçu par votre BroadcastReceiver:

Kotlin

private fun getMessageText(intent: Intent): CharSequence? {
    return RemoteInput.getResultsFromIntent(intent)?.getCharSequence(KEY_TEXT_REPLY)
}

Java

private CharSequence getMessageText(Intent intent) {
    Bundle remoteInput = RemoteInput.getResultsFromIntent(intent);
    if (remoteInput != null) {
        return remoteInput.getCharSequence(KEY_TEXT_REPLY);
    }
    return null;
 }

Une fois le texte traité, mettez à jour la notification en appelant NotificationManagerCompat.notify() avec l'ID et la balise identiques, le cas échéant. Cela est nécessaire pour masquer l'interface utilisateur de réponse directe et confirmer à l'utilisateur que sa réponse est reçue et traitée correctement.

Kotlin

// Build a new notification, which informs the user that the system
// handled their interaction with the previous notification.
val repliedNotification = Notification.Builder(context, CHANNEL_ID)
        .setSmallIcon(R.drawable.ic_message)
        .setContentText(getString(R.string.replied))
        .build()

// Issue the new notification.
NotificationManagerCompat.from(this).apply {
    notificationManager.notify(notificationId, repliedNotification)
}

Java

// Build a new notification, which informs the user that the system
// handled their interaction with the previous notification.
Notification repliedNotification = new Notification.Builder(context, CHANNEL_ID)
        .setSmallIcon(R.drawable.ic_message)
        .setContentText(getString(R.string.replied))
        .build();

// Issue the new notification.
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
notificationManager.notify(notificationId, repliedNotification);

Lorsque vous utilisez cette nouvelle notification, utilisez le contexte transmis à la méthode onReceive() du destinataire.

Ajoutez la réponse en bas de la notification en appelant setRemoteInputHistory(). Toutefois, si vous créez une application de chat, créez une notification de type message et ajoutez le nouveau message à la conversation.

Pour plus de conseils sur les notifications provenant d'une application de chat, consultez la section Bonnes pratiques pour les applications de chat.

Ajouter une barre de progression

Les notifications peuvent inclure un indicateur de progression animé qui indique aux utilisateurs l'état d'une opération en cours.

Figure 5 : Barre de progression pendant une opération

Si vous pouvez estimer le pourcentage d'achèvement de l'opération à tout moment, appelez setProgress(max, progress, false) sous la forme "déterminée" de l'indicateur, comme illustré dans la figure 5. Le premier paramètre correspond à la valeur "complete" (100, par exemple). Le deuxième est le degré d'achèvement. Le dernier indique qu'il s'agit d'une barre de progression déterminée.

Au fur et à mesure que l'opération se poursuit, appelez setProgress(max, progress, false) en continu avec une valeur mise à jour pour progress et renvoyez la notification, comme illustré dans l'exemple suivant.

Kotlin

val builder = NotificationCompat.Builder(this, CHANNEL_ID).apply {
    setContentTitle("Picture Download")
    setContentText("Download in progress")
    setSmallIcon(R.drawable.ic_notification)
    setPriority(NotificationCompat.PRIORITY_LOW)
}
val PROGRESS_MAX = 100
val PROGRESS_CURRENT = 0
NotificationManagerCompat.from(this).apply {
    // Issue the initial notification with zero progress.
    builder.setProgress(PROGRESS_MAX, PROGRESS_CURRENT, false)
    notify(notificationId, builder.build())

    // Do the job that tracks the progress here.
    // Usually, this is in a worker thread.
    // To show progress, update PROGRESS_CURRENT and update the notification with:
    // builder.setProgress(PROGRESS_MAX, PROGRESS_CURRENT, false);
    // notificationManager.notify(notificationId, builder.build());

    // When done, update the notification once more to remove the progress bar.
    builder.setContentText("Download complete")
            .setProgress(0, 0, false)
    notify(notificationId, builder.build())
}

Java

...
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID);
builder.setContentTitle("Picture Download")
        .setContentText("Download in progress")
        .setSmallIcon(R.drawable.ic_notification)
        .setPriority(NotificationCompat.PRIORITY_LOW);

// Issue the initial notification with zero progress.
int PROGRESS_MAX = 100;
int PROGRESS_CURRENT = 0;
builder.setProgress(PROGRESS_MAX, PROGRESS_CURRENT, false);
notificationManager.notify(notificationId, builder.build());

// Do the job that tracks the progress here.
// Usually, this is in a worker thread.
// To show progress, update PROGRESS_CURRENT and update the notification with:
// builder.setProgress(PROGRESS_MAX, PROGRESS_CURRENT, false);
// notificationManager.notify(notificationId, builder.build());

// When done, update the notification once more to remove the progress bar.
builder.setContentText("Download complete")
        .setProgress(0,0,false);
notificationManager.notify(notificationId, builder.build());

À la fin de l'opération, progress doit être égal à max. Vous pouvez quitter la barre de progression pour indiquer que l'opération est terminée ou la supprimer. Dans les deux cas, mettez à jour le texte de la notification pour indiquer que l'opération est terminée. Pour supprimer la barre de progression, appelez setProgress(0, 0, false).

Pour afficher une barre de progression indéterminée (une barre qui n'indique pas le pourcentage d'achèvement), appelez setProgress(0, 0, true). Le résultat est un indicateur qui a le même style que la barre de progression précédente, sauf qu'il s'agit d'une animation continue qui n'indique pas l'achèvement. L'animation de progression s'exécute jusqu'à ce que vous appeliez setProgress(0, 0, false), puis que vous mettiez à jour la notification pour supprimer l'indicateur d'activité.

N'oubliez pas de modifier le texte de la notification pour indiquer que l'opération est terminée.

Définir une catégorie à l'échelle du système

Android utilise des catégories prédéfinies à l'échelle du système pour déterminer s'il faut déranger l'utilisateur avec une notification donnée lorsqu'il active le mode Ne pas déranger.

Si votre notification appartient à l'une des catégories définies dans NotificationCompat (CATEGORY_ALARM, CATEGORY_REMINDER, CATEGORY_EVENT ou CATEGORY_CALL, par exemple), déclarez-la en transmettant la catégorie appropriée à setCategory():

Kotlin

var builder = NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        .setCategory(NotificationCompat.CATEGORY_MESSAGE)

Java

NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        .setCategory(NotificationCompat.CATEGORY_MESSAGE);

Le système utilise ces informations sur votre catégorie de notification pour prendre des décisions concernant l'affichage de votre notification lorsque l'appareil est en mode "Ne pas déranger". Toutefois, vous n'êtes pas obligé de définir une catégorie pour l'ensemble du système. Ne le faites que si vos notifications correspondent à l'une des catégories définies dans NotificationCompat.

Afficher un message urgent

Votre application peut avoir besoin d'afficher un message urgent et urgent, tel qu'un appel téléphonique entrant ou une alarme qui sonne. Dans ces situations, vous pouvez associer un intent plein écran à votre notification.

Lorsque la notification est appelée, l'une des mentions suivantes s'affiche, selon l'état de verrouillage de l'appareil:

  • Si l'appareil de l'utilisateur est verrouillé, une activité en plein écran recouvrant l'écran de verrouillage s'affiche.
  • Si l'appareil de l'utilisateur est déverrouillé, la notification s'affiche sous une forme développée avec des options de gestion ou de fermeture.

L'extrait de code suivant montre comment associer votre notification à un intent plein écran:

Kotlin

val fullScreenIntent = Intent(this, ImportantActivity::class.java)
val fullScreenPendingIntent = PendingIntent.getActivity(this, 0,
    fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT)

var builder = NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        .setFullScreenIntent(fullScreenPendingIntent, true)

Java

Intent fullScreenIntent = new Intent(this, ImportantActivity.class);
PendingIntent fullScreenPendingIntent = PendingIntent.getActivity(this, 0,
        fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT);

NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        .setFullScreenIntent(fullScreenPendingIntent, true);

Définir visibilité écran verrouillage

Pour contrôler le niveau de détail visible dans la notification depuis l'écran de verrouillage, appelez setVisibility() et spécifiez l'une des valeurs suivantes:

  • VISIBILITY_PUBLIC : tout le contenu de la notification s'affiche sur l'écran de verrouillage.

  • VISIBILITY_SECRET : aucune partie de la notification ne s'affiche sur l'écran de verrouillage.

  • VISIBILITY_PRIVATE : seules les informations de base, telles que l'icône de la notification et le titre du contenu, s'affichent sur l'écran de verrouillage. Le contenu complet de la notification ne s'affiche pas.

Lorsque vous définissez VISIBILITY_PRIVATE, vous pouvez également fournir une autre version du contenu des notifications qui masque certains détails. Par exemple, une application de SMS peut afficher la notification "Vous avez trois nouveaux SMS", mais masquer le contenu et les expéditeurs du message. Pour fournir cette notification alternative, commencez par la créer avec NotificationCompat.Builder, comme d'habitude. Joignez ensuite la notification alternative à la notification normale avec setPublicVersion().

N'oubliez pas que l'utilisateur a toujours le contrôle final sur l'affichage de ses notifications sur l'écran de verrouillage et qu'il peut les contrôler en fonction des canaux de notification de votre application.

Mettre à jour une notification

Pour mettre à jour une notification après l'avoir envoyée, appelez à nouveau NotificationManagerCompat.notify() en lui transmettant le même ID que précédemment. Si la notification précédente est ignorée, une notification est créée à la place.

Si vous le souhaitez, vous pouvez appeler setOnlyAlertOnce() pour que l'utilisateur soit interrompu par une notification (son, vibration ou indices visuels) uniquement la première fois qu'elle s'affiche, et non pour des mises à jour ultérieures.

Supprimer une notification

Les notifications restent visibles jusqu'à ce qu'un des événements suivants se produise:

  • L'utilisateur ignore la notification.
  • L'utilisateur appuie sur la notification si vous appelez setAutoCancel() lorsque vous créez la notification.
  • Vous appelez cancel() pour un ID de notification spécifique. Cette méthode supprime également les notifications en cours.
  • Vous appelez cancelAll(), ce qui supprime toutes les notifications que vous avez précédemment émises.
  • La durée spécifiée arrive à expiration si vous définissez un délai avant expiration lors de la création de la notification à l'aide de setTimeoutAfter(). Si nécessaire, vous pouvez annuler une notification avant l'expiration du délai spécifié.

Bonnes pratiques pour les applications de chat

Tenez compte des bonnes pratiques listées ici lorsque vous créez des notifications pour vos applications de chat et de messagerie.

Utiliser MessagingStyle

À partir d'Android 7.0 (niveau d'API 24), Android fournit un modèle de style de notification spécifique au contenu de messagerie. La classe NotificationCompat.MessagingStyle vous permet de modifier plusieurs des libellés affichés dans la notification, y compris le titre de la conversation, les messages supplémentaires et la vue de contenu de la notification.

L'extrait de code suivant montre comment personnaliser le style d'une notification à l'aide de la classe MessagingStyle.

Kotlin

val user = Person.Builder()
    .setIcon(userIcon)
    .setName(userName)
    .build()

val notification = NotificationCompat.Builder(this, CHANNEL_ID)
    .setContentTitle("2 new messages with $sender")
    .setContentText(subject)
    .setSmallIcon(R.drawable.new_message)
    .setStyle(NotificationCompat.MessagingStyle(user)
        .addMessage(messages[1].getText(), messages[1].getTime(), messages[1].getPerson())
        .addMessage(messages[2].getText(), messages[2].getTime(), messages[2].getPerson())
    )
    .build()

Java

Person user = new Person.Builder()
    .setIcon(userIcon)
    .setName(userName)
    .build();

Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
    .setContentTitle("2 new messages with " + sender)
    .setContentText(subject)
    .setSmallIcon(R.drawable.new_message)
    .setStyle(new NotificationCompat.MessagingStyle(user)
        .addMessage(messages[1].getText(), messages[1].getTime(), messages[1].getPerson())
        .addMessage(messages[2].getText(), messages[2].getTime(), messages[2].getPerson())
    )
    .build();

À partir d'Android 9.0 (niveau d'API 28), vous devez également utiliser la classe Person pour obtenir un affichage optimal de la notification et de ses avatars.

Lorsque vous utilisez NotificationCompat.MessagingStyle, procédez comme suit:

  • Appelez MessagingStyle.setConversationTitle() pour définir un titre pour les chats de groupe de plus de deux personnes. Un bon titre de conversation peut être le nom du chat de groupe ou, s'il n'a pas de nom, la liste des participants à la conversation. Sans cela, le message peut être confondu avec une conversation privée avec l'expéditeur du message le plus récent de la conversation.
  • Utilisez la méthode MessagingStyle.setData() pour inclure des messages multimédias tels que des images. Les types MIME du motif image/* sont acceptés.

Utiliser la fonctionnalité Réponse directe

La fonctionnalité Réponse directe permet aux utilisateurs de répondre directement à un message.

  • Lorsqu'un utilisateur a répondu avec l'action de réponse intégrée, utilisez MessagingStyle.addMessage() pour mettre à jour la notification MessagingStyle. Ne la retirez pas et ne l'annulez pas. Ne pas annuler la notification permet à l'utilisateur d'envoyer plusieurs réponses à partir de la notification.
  • Pour rendre l'action de réponse intégrée compatible avec Wear OS, appelez Action.WearableExtender.setHintDisplayInlineAction(true).
  • Utilisez la méthode addHistoricMessage() pour fournir du contexte à une conversation de réponse directe en ajoutant des messages historiques à la notification.

Activer la fonctionnalité Réponse suggérée

  • Pour activer la fonctionnalité Réponse suggérée, appelez setAllowGeneratedResponses(true) pour l'action de réponse. Ainsi, les réponses suggérées sont accessibles aux utilisateurs lorsque la notification est pontée sur un appareil Wear OS. Les réponses suggérées sont générées par un modèle de machine learning entièrement intégré à la montre à l'aide du contexte fourni par la notification NotificationCompat.MessagingStyle. Aucune donnée n'est importée sur Internet pour générer les réponses.

Ajouter des métadonnées de notification