Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
The notification listener allows your app to access and interact with all of the user's notifications, including notifications sent by other apps. This enables scenarios such as displaying notifications on a companion device, performing actions in response to notifications from other apps, or syncing notification state across devices.
For more information about app notifications, see App notifications overview.
Note
The code examples in this article use the Windows.UI.Notifications.Management namespace for notification listener functionality and the Microsoft.Windows.AppNotifications namespace for sending notifications. These two namespaces can be used together in the same app.
Enable the listener by adding the User Notification capability
To use the notification listener, you must add the User Notification Listener capability to your app manifest.
- In Visual Studio, in the Solution Explorer, double click your
Package.appxmanifestfile to open the manifest designer. - Open the Capabilities tab.
- Check the User Notification Listener capability.
Request access to the listener
Since the listener allows access to the user's notifications, users must give your app permission to access their notifications. During your app's first-run experience, you should request access to use the notification listener. 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;
}
The user can revoke access at any time via Windows Settings. Therefore, your app should always check the access status via the GetAccessStatus method before executing code that uses the notification listener. 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).
Access the user's notifications
With the notification listener, you can get a list of the user's current notifications. Simply call the GetNotificationsAsync method, and specify the type of notifications you want to get (currently, the only type of notifications supported are app notifications).
// Get the toast notifications
IReadOnlyList<UserNotification> notifs = await listener.GetNotificationsAsync(NotificationKinds.Toast);
Displaying the notifications
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; }
}
The AppInfo property provides the info you need to display the notification.
Note
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. 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());
The content of the notification itself, such as the notification text, is contained in the Notification property. This property contains the visual portion of the notification. The Visual and Visual.Bindings properties correspond to the content that was specified when the notification was sent.
We want to look for the toast binding (for error-proof code, you should check that the binding isn't null). From the binding, you can obtain the text elements. You can 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));
}
Remove a specific notification
If your app allows the user to dismiss notifications, you can remove the actual notification so the user doesn't see it later. Provide the notification ID (obtained from the UserNotification object) of the notification you'd like to remove:
// Remove the notification
listener.RemoveNotification(notifId);
Clear all notifications
The UserNotificationListener.ClearNotifications method clears all the user's notifications. Use this method with caution. You should only clear all notifications if your app displays all notifications. If your app only displays certain notifications, the user may expect only those specific notifications to be removed when clicking a "Clear notifications" button. Calling ClearNotifications removes all notifications, including ones that your app wasn't displaying.
// Clear all notifications. Use with caution.
listener.ClearNotifications();
Background task for notification changes
You can register a background task that is triggered when a notification is added or dismissed, regardless of whether your app is currently running. Use UserNotificationChangedTrigger with the Windows App SDK BackgroundTaskBuilder to register the task.
using Windows.ApplicationModel.Background;
using Windows.UI.Notifications;
var builder = new Microsoft.Windows.ApplicationModel.Background.BackgroundTaskBuilder();
builder.Name = "UserNotificationChanged";
builder.SetTrigger(new UserNotificationChangedTrigger(NotificationKinds.Toast));
builder.SetTaskEntryPointClsid(typeof(MyBackgroundTask).GUID);
builder.Register();
The background task is triggered whenever a notification is added or dismissed but doesn't provide details about which specific notification changed. When the task runs, your code should sync the current notification state by calling GetNotificationsAsync.
For complete steps on implementing a background task, including COM server registration and manifest configuration, see Using background tasks in Windows apps.
Determining which notifications were added and removed
In your SyncNotifications method, to determine which notifications have been added or removed, calculate the delta between your app's current notification state 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);
}
Foreground event for notification added/dismissed
You can also listen to notifications from an in-memory event handler using the NotificationChanged event.
// Subscribe to foreground event
listener.NotificationChanged += Listener_NotificationChanged;
private void Listener_NotificationChanged(UserNotificationListener sender, UserNotificationChangedEventArgs args)
{
// Your code for handling the notification
}
See also
Windows developer