Écouteur de notification : accéder à toutes les notificationsNotification listener: Access all notifications

L’écouteur de notification fournit l’accès aux notifications d’un utilisateur.The notification listener provides access to a user's notifications. Smartwatches et d’autres appareils, peuvent utiliser l’écouteur de notification pour envoyer les notifications du téléphone à l’appareil portable.Smartwatches and other wearables can use the notification listener to send the phone's notifications to the wearable device. Les applications domotiques peuvent utiliser l’écouteur de notification pour effectuer des actions spécifiques lors de la réception de notifications, par exemple faire clignoter les voyants quand vous recevez un appel.Home automation apps can use notification listener to perform specific actions when notifications are received, such as making the lights blink when you receive a call.

Important

Nécessite une mise à jour anniversaire : vous devez cibler le SDK 14393 et exécuter Build 14393 ou version ultérieure pour utiliser l’écouteur de notification.Requires Anniversary Update : You must target SDK 14393 and be running build 14393 or higher to use Notification Listener.

API importantes : classe UserNotificationListener, classe UserNotificationChangedTriggerImportant APIs : UserNotificationListener class, UserNotificationChangedTrigger class

Activer l’écouteur en ajoutant la fonctionnalité de notification de l’utilisateurEnable the listener by adding the User Notification capability

Pour utiliser l’écouteur de notification, vous devez ajouter la fonctionnalité d’écouteur de notification utilisateur au manifeste de votre application.To use the notification listener, you must add the User Notification Listener capability to your app manifest.

  1. Dans Visual Studio, dans la Explorateur de solutions, double-cliquez sur votre Package.appxmanifest fichier pour ouvrir le concepteur de manifeste.In Visual Studio, in the Solution Explorer, double click your Package.appxmanifest file to open the manifest designer.
  2. Ouvrez l’onglet Capacités.Open the Capabilities tab.
  3. Vérifiez la capacité de l' écouteur de notification utilisateur .Check the User Notification Listener capability.

Vérifier si l’écouteur est pris en chargeCheck whether the listener is supported

Si votre application prend en charge des versions antérieures de Windows 10, vous devez utiliser la classe ApiInformation pour vérifier si l’écouteur est pris en charge.If your app supports older versions of Windows 10, you need to use the ApiInformation class to check whether the listener is supported. Si l’écouteur n’est pas pris en charge, évitez d’exécuter des appels aux API d’écouteur.If the listener isn't supported, avoid executing any calls to the listener APIs.

if (ApiInformation.IsTypePresent("Windows.UI.Notifications.Management.UserNotificationListener"))
{
    // Listener supported!
}
 
else
{
    // Older version of Windows, no Listener
}

Demande d’accès à l’écouteurRequesting access to the listener

Étant donné que l’écouteur autorise l’accès aux notifications de l’utilisateur, les utilisateurs doivent accorder à votre application l’autorisation d’accéder à leurs notifications.Since the listener allows access to the user's notifications, users must give your app permission to access their notifications. Lors de la première exécution de votre application, vous devez demander l’accès pour utiliser l’écouteur de notification.During your app's first-run experience, you should request access to use the notification listener. Si vous le souhaitez, vous pouvez afficher une interface utilisateur préliminaire qui explique pourquoi votre application a besoin d’accéder aux notifications de l’utilisateur avant d’appeler RequestAccessAsync, afin que l’utilisateur comprenne la raison pour laquelle il doit autoriser l’accès.If you want, you can show some preliminary UI that explains why your app needs access to the user's notifications before you call RequestAccessAsync, so that the user understands why they should allow access.

// Get the listener
UserNotificationListener listener = UserNotificationListener.Current;
 
// And request access to the user's notifications (must be called from UI thread)
UserNotificationListenerAccessStatus accessStatus = await listener.RequestAccessAsync();
 
switch (accessStatus)
{
    // This means the user has granted access.
    case UserNotificationListenerAccessStatus.Allowed:
 
        // Yay! Proceed as normal
        break;
 
    // This means the user has denied access.
    // Any further calls to RequestAccessAsync will instantly
    // return Denied. The user must go to the Windows settings
    // and manually allow access.
    case UserNotificationListenerAccessStatus.Denied:
 
        // Show UI explaining that listener features will not
        // work until user allows access.
        break;
 
    // This means the user closed the prompt without
    // selecting either allow or deny. Further calls to
    // RequestAccessAsync will show the dialog again.
    case UserNotificationListenerAccessStatus.Unspecified:
 
        // Show UI that allows the user to bring up the prompt again
        break;
}

L’utilisateur peut révoquer l’accès à tout moment via les paramètres Windows.The user can revoke access at any time via Windows Settings. Par conséquent, votre application doit toujours vérifier l’état de l’accès à l’aide de la méthode GetAccessStatus avant d’exécuter du code qui utilise l’écouteur de notification.Therefore, your app should always check the access status via the GetAccessStatus method before executing code that uses the notification listener. Si l’utilisateur révoque l’accès, les API échouent silencieusement au lieu de lever une exception (par exemple, l’API pour obtenir toutes les notifications renverra simplement une liste vide).If the user revokes access, the APIs will silently fail rather than throwing an exception (for example, the API to get all notifications will simply return an empty list).

Accéder aux notifications de l’utilisateurAccess the user's notifications

Avec l’écouteur de notification, vous pouvez obtenir la liste des notifications actuelles de l’utilisateur.With the notification listener, you can get a list of the user's current notifications. Appelez simplement la méthode GetNotificationsAsync et spécifiez le type de notifications que vous souhaitez obtenir (actuellement, le seul type de notifications prises en charge sont les notifications Toast).Simply call the GetNotificationsAsync method, and specify the type of notifications you want to get (currently, the only type of notifications supported are toast notifications).

// Get the toast notifications
IReadOnlyList<UserNotification> notifs = await listener.GetNotificationsAsync(NotificationKinds.Toast);

Affichage des notificationsDisplaying the notifications

Chaque notification est représentée sous la forme d’un UserNotification, qui fournit des informations sur l’application dont provient la notification, l’heure à laquelle la notification a été créée, l’ID de la notification et la notification elle-même.Each notification is represented as a UserNotification, which provides information about the app that the notification is from, the time the notification was created, the notification's ID, and the notification itself.

public sealed class UserNotification
{
    public AppInfo AppInfo { get; }
    public DateTimeOffset CreationTime { get; }
    public uint Id { get; }
    public Notification Notification { get; }
}

La propriété appinfo fournit les informations dont vous avez besoin pour afficher la notification.The AppInfo property provides the info you need to display the notification.

Notes

Nous vous recommandons de placer tout votre code pour traiter une seule notification dans un bloc try/catch, si une exception inattendue se produit lorsque vous capturez une seule notification.We recommend surrounding all your code for processing a single notification in a try/catch, in case an unexpected exception occurs when you are capturing a single notification. Vous ne devriez pas complètement faire échouer l’affichage d’autres notifications en raison d’un problème avec une notification spécifique.You shouldn't completely fail to display other notifications just because of an issue with one specific notification.

// Select the first notification
UserNotification notif = notifs[0];
 
// Get the app's display name
string appDisplayName = notif.AppInfo.DisplayInfo.DisplayName;
 
// Get the app's logo
BitmapImage appLogo = new BitmapImage();
RandomAccessStreamReference appLogoStream = notif.AppInfo.DisplayInfo.GetLogo(new Size(16, 16));
await appLogo.SetSourceAsync(await appLogoStream.OpenReadAsync());

Le contenu de la notification lui-même, tel que le texte de notification, est contenu dans la propriété de notification .The content of the notification itself, such as the notification text, is contained in the Notification property. Cette propriété contient la partie visuelle de la notification.This property contains the visual portion of the notification. (Si vous êtes familiarisé avec l’envoi de notifications sur Windows, vous remarquerez que les propriétés visuelles et visuelles . Bindings de l’objet de notification correspondent à ce que les développeurs envoient lorsqu’ils dépassent une notification.)(If you are familiar with sending notifications on Windows, you will notice that the Visual and Visual.Bindings properties in the Notification object correspond to what developers send when popping a notification.)

Nous souhaitons Rechercher la liaison Toast (pour le code de vérification d’erreur, vous devez vérifier que la liaison n’est pas null).We want to look for the toast binding (for error-proof code, you should check that the binding isn't null). À partir de la liaison, vous pouvez obtenir les éléments de texte.From the binding, you can obtain the text elements. Vous pouvez choisir d’afficher autant d’éléments de texte que vous le souhaitez.You can choose to display as many text elements as you would like. (Idéalement, vous devriez les afficher tous.) Vous pouvez choisir de traiter les éléments de texte différemment. par exemple, considérez la première comme un texte de titre et les éléments suivants comme corps de texte.(Ideally, you should display them all.) You can choose to treat the text elements differently; for example, treat the first one as title text, and subsequent elements as body text.

// Get the toast binding, if present
NotificationBinding toastBinding = notif.Notification.Visual.GetBinding(KnownNotificationBindings.ToastGeneric);
 
if (toastBinding != null)
{
    // And then get the text elements from the toast binding
    IReadOnlyList<AdaptiveNotificationText> textElements = toastBinding.GetTextElements();
 
    // Treat the first text element as the title text
    string titleText = textElements.FirstOrDefault()?.Text;
 
    // We'll treat all subsequent text elements as body text,
    // joining them together via newlines.
    string bodyText = string.Join("\n", textElements.Skip(1).Select(t => t.Text));
}

Supprimer une notification spécifiqueRemove a specific notification

Si votre service ou portable autorise l’utilisateur à ignorer les notifications, vous pouvez supprimer la notification proprement dite afin que l’utilisateur ne l’affiche plus par la suite sur son téléphone ou sur son PC.If your wearable or service allows the user to dismiss notifications, you can remove the actual notification so the user doesn't see it later on their phone or PC. Il vous suffit de fournir l’ID de notification (obtenu à partir de l’objet UserNotification ) de la notification que vous souhaitez supprimer :Simply provide the notification ID (obtained from the UserNotification object) of the notification you'd like to remove:

// Remove the notification
listener.RemoveNotification(notifId);

Effacer toutes les notificationsClear all notifications

La méthode UserNotificationListener. ClearNotifications efface toutes les notifications de l’utilisateur.The UserNotificationListener.ClearNotifications method clears all the user's notifications. Utilisez cette méthode avec précaution.Use this method with caution. Vous ne devez effacer que toutes les notifications si votre service ou portable affiche toutes les notifications.You should only clear all notifications if your wearable or service displays ALL notifications. Si votre service ou portable affiche uniquement certaines notifications, lorsque l’utilisateur clique sur le bouton « Effacer les notifications », l’utilisateur ne s’attend à supprimer que les notifications spécifiques. Toutefois, l’appel de la méthode ClearNotifications entraînerait la suppression de toutes les notifications, y compris celles que votre service ou portable n’affichait pas.If your wearable or service only displays certain notifications, when the user clicks your "Clear notifications" button, the user is only expecting those specific notifications to be removed; however, calling the ClearNotifications method would actually cause all the notifications, including ones that your wearable or service wasn't displaying, to be removed.

// Clear all notifications. Use with caution.
listener.ClearNotifications();

Tâche en arrière-plan pour la notification ajoutée/ferméeBackground task for notification added/dismissed

Une méthode courante pour permettre à une application d’écouter les notifications consiste à configurer une tâche en arrière-plan, afin que vous puissiez savoir quand une notification a été ajoutée ou fermée, que votre application soit en cours d’exécution ou non.A common way to enable an app to listen to notifications is to set up a background task, so that you can know when a notification was added or dismissed regardless of whether your app is currently running.

Grâce au modèle à processus unique ajouté dans la mise à jour anniversaire, l’ajout de tâches en arrière-plan est relativement simple.Thanks to the single process model added in the Anniversary Update, adding background tasks is fairly simple. Dans le code de votre application principale, après avoir obtenu l’accès de l’utilisateur à l’écouteur de notifications et obtenu l’accès pour exécuter des tâches en arrière-plan, il vous suffit d’enregistrer une nouvelle tâche en arrière-plan et de définir UserNotificationChangedTrigger à l’aide du type de notification Toast.In your main app's code, after you have obtained the user's access to Notification Listener and obtained access to run background tasks, simply register a new background task, and set the UserNotificationChangedTrigger using the Toast notification kind.

// TODO: Request/check Listener access via UserNotificationListener.Current.RequestAccessAsync
 
// TODO: Request/check background task access via BackgroundExecutionManager.RequestAccessAsync
 
// If background task isn't registered yet
if (!BackgroundTaskRegistration.AllTasks.Any(i => i.Value.Name.Equals("UserNotificationChanged")))
{
    // Specify the background task
    var builder = new BackgroundTaskBuilder()
    {
        Name = "UserNotificationChanged"
    };
 
    // Set the trigger for Listener, listening to Toast Notifications
    builder.SetTrigger(new UserNotificationChangedTrigger(NotificationKinds.Toast));
 
    // Register the task
    builder.Register();
}

Ensuite, dans votre App.xaml.cs, remplacez la méthode OnBackgroundActivated si vous ne l’avez pas encore fait, et utilisez une instruction switch sur le nom de la tâche pour déterminer lequel de vos nombreux déclencheurs de tâche en arrière-plan a été appelé.Then, in your App.xaml.cs, override the OnBackgroundActivated method if you haven't yet, and use a switch statement on the task name to determine which of your many background task triggers was invoked.

protected override async void OnBackgroundActivated(BackgroundActivatedEventArgs args)
{
    var deferral = args.TaskInstance.GetDeferral();
 
    switch (args.TaskInstance.Task.Name)
    {
        case "UserNotificationChanged":
            // Call your own method to process the new/removed notifications
            // The next section of documentation discusses this code
            await MyWearableHelpers.SyncNotifications();
            break;
    }
 
    deferral.Complete();
}

La tâche en arrière-plan est simplement un « robinet d’épaule » : elle ne fournit pas d’informations sur la notification spécifique qui a été ajoutée ou supprimée.The background task is simply a "shoulder tap": it doesn't provide any information about which specific notification was added or removed. Lorsque votre tâche en arrière-plan est déclenchée, vous devez synchroniser les notifications sur votre portable afin qu’elles reflètent les notifications dans la plateforme.When your background task is triggered, you should sync the notifications on your wearable so that they reflect the notifications in the platform. Cela garantit que si votre tâche en arrière-plan échoue, les notifications sur votre portable peuvent toujours être récupérées lors de la prochaine exécution de la tâche en arrière-plan.This ensures that if your background task fails, notifications on your wearable can still be recovered the next time your background task executes.

SyncNotifications est une méthode que vous implémentez ; la section suivante montre comment procéder.SyncNotifications is a method you implement; the next section shows how.

Détermination des notifications qui ont été ajoutées et suppriméesDetermining which notifications were added and removed

Dans votre SyncNotifications méthode, pour déterminer quelles notifications ont été ajoutées ou supprimées (en synchronisant des notifications avec votre portable), vous devez calculer le delta entre votre collection de notifications actuelle et les notifications dans la plateforme.In your SyncNotifications method, to determine which notifications have been added or removed (syncing notifications with your wearable), you have to calculate the delta between your current notification collection, and the notifications in the platform.

// Get all the current notifications from the platform
IReadOnlyList<UserNotification> userNotifications = await listener.GetNotificationsAsync(NotificationKinds.Toast);
 
// Obtain the notifications that our wearable currently has displayed
IList<uint> wearableNotificationIds = GetNotificationsOnWearable();
 
// Copy the currently displayed into a list of notification ID's to be removed
var toBeRemoved = new List<uint>(wearableNotificationIds);
 
// For each notification in the platform
foreach (UserNotification userNotification in userNotifications)
{
    // If we've already displayed this notification
    if (wearableNotificationIds.Contains(userNotification.Id))
    {
        // We want to KEEP it displayed, so take it out of the list
        // of notifications to remove.
        toBeRemoved.Remove(userNotification.Id);
    }
 
    // Otherwise it's a new notification
    else
    {
        // Display it on the Wearable
        SendNotificationToWearable(userNotification);
    }
}
 
// Now our toBeRemoved list only contains notification ID's that no longer exist in the platform.
// So we will remove all those notifications from the wearable.
foreach (uint id in toBeRemoved)
{
    RemoveNotificationFromWearable(id);
}

Événement de premier plan pour la notification ajoutée/ignoréeForeground event for notification added/dismissed

Important

Problème connu : dans les builds antérieures à la version 17763/octobre 2018 mise à jour/version 1809, l’événement de premier plan entraîne une boucle d’UC et/ou n’a pas fonctionné.Known issue: In builds before Build 17763 / October 2018 Update / Version 1809, The foreground event will cause a CPU loop and/or didn't work. Si vous avez besoin d’une prise en charge sur ces versions antérieures, utilisez la tâche en arrière-plan à la place.If you need support on those earlier builds, use the background task instead.

Vous pouvez également écouter les notifications à partir d’un gestionnaire d’événements en mémoire...You can also listen to notifications from an in-memory event handler...

// Subscribe to foreground event
listener.NotificationChanged += Listener_NotificationChanged;
 
private void Listener_NotificationChanged(UserNotificationListener sender, UserNotificationChangedEventArgs args)
{
    // Your code for handling the notification
}

Comment corriger des retards dans la tâche en arrière-planHow to fix delays in the background task

Lorsque vous testez votre application, vous remarquerez peut-être que la tâche en arrière-plan est parfois retardée et ne se déclenche pas pendant plusieurs minutes.When testing your app, you might notice that the background task is sometimes delayed and doesn't trigger for several minutes. Pour résoudre ce problème, invitez l’utilisateur à accéder aux paramètres système-> système-> > l’utilisation de la batterie par l’application, recherchez votre application dans la liste, sélectionnez-la, puis définissez-la comme « toujours autorisée en arrière-plan ».To fix the delay, prompt the user to go to the system settings -> System -> Battery -> Battery usage by app, find your app in the list, select it, and set it to be "Always allowed in background." Après cela, la tâche en arrière-plan doit toujours être déclenchée dans environ une seconde de la notification en cours de réception.After this, the background task should always be triggered within around a second of the notification being received.