Freigeben über


Benachrichtigungslistener: Zugriff auf alle Benachrichtigungen

Der Benachrichtigungslistener bietet Zugriff auf die Benachrichtigungen eines Benutzers. Wearables und andere Wearables können den Benachrichtigungshörer verwenden, um die Benachrichtigungen des Telefons an das wearable Gerät zu senden. Heimautomatisierungs-Apps können Benachrichtigungslistener verwenden, um bestimmte Aktionen auszuführen, wenn Benachrichtigungen empfangen werden, z. B. blinken die Lichter, wenn Sie einen Anruf erhalten.

Wichtig

Erfordert Anniversary Update: Sie müssen sdk 14393 als Ziel verwenden und Build 14393 oder höher ausführen, um den Benachrichtigungslistener zu verwenden.

Wichtige APIs: UserNotificationListener-Klasse, UserNotificationChangedTrigger-Klasse

Aktivieren des Listeners durch Hinzufügen der Benutzerbenachrichtigungsfunktion

Um den Benachrichtigungslistener zu verwenden, müssen Sie dem App-Manifest die Funktion "Benutzerbenachrichtigungslistener" hinzufügen.

  1. Doppelklicken Sie in Visual Studio im Projektmappen-Explorer auf Ihre Package.appxmanifest Datei, um den Manifest-Designer zu öffnen.
  2. Öffnen Sie das Register Funktionen.
  3. Überprüfen Sie die Funktion " Benutzerbenachrichtigungslistener ".

Überprüfen, ob der Listener unterstützt wird

Wenn Ihre App ältere Versionen von Windows 10 unterstützt, müssen Sie die ApiInformation-Klasse verwenden, um zu überprüfen, ob der Listener unterstützt wird. Wenn der Listener nicht unterstützt wird, vermeiden Sie das Ausführen von Aufrufen der Listener-APIs.

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

Anfordern des Zugriffs auf den Listener

Da der Listener den Zugriff auf die Benachrichtigungen des Benutzers zulässt, müssen Benutzer Ihrer App die Berechtigung erteilen, auf ihre Benachrichtigungen zuzugreifen. Während der ersten Ausführung Ihrer App sollten Sie den Zugriff auf die Verwendung des Benachrichtigungslisteners anfordern. Wenn Sie möchten, können Sie eine vorläufige Benutzeroberfläche anzeigen, die erläutert, warum Ihre App Zugriff auf die Benachrichtigungen des Benutzers benötigt, bevor Sie RequestAccessAsync aufrufen, damit der Benutzer versteht, warum er den Zugriff zulassen sollte.

// 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;
}

Der Benutzer kann den Zugriff jederzeit über die Windows-Einstellungen widerrufen. Daher sollte Ihre App den Zugriffsstatus immer über die GetAccessStatus-Methode überprüfen, bevor Code ausgeführt wird, der den Benachrichtigungslistener verwendet. Wenn der Benutzer den Zugriff widerruft, schlägt die APIs im Hintergrund fehl, anstatt eine Ausnahme auszuwerfen (beispielsweise gibt die API zum Abrufen aller Benachrichtigungen einfach eine leere Liste zurück).

Zugreifen auf die Benachrichtigungen des Benutzers

Mit dem Benachrichtigungslistener können Sie eine Liste der aktuellen Benachrichtigungen des Benutzers abrufen. Rufen Sie einfach die GetNotificationsAsync-Methode auf, und geben Sie den Typ der abzurufenden Benachrichtigungen an (derzeit sind die einzigen unterstützten Benachrichtigungstypen Popupbenachrichtigungen).

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

Anzeigen der Benachrichtigungen

Jede Benachrichtigung wird als UserNotification dargestellt, die Informationen über die App bereitstellt, aus der die Benachrichtigung stammt, die Uhrzeit, an der die Benachrichtigung erstellt wurde, die ID der Benachrichtigung und die Benachrichtigung selbst.

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

Die AppInfo-Eigenschaft enthält die Informationen, die Sie zum Anzeigen der Benachrichtigung benötigen.

Hinweis

Es wird empfohlen, den gesamten Code für die Verarbeitung einer einzelnen Benachrichtigung in einem Try/Catch-Ereignis einzuschließen, falls eine unerwartete Ausnahme auftritt, wenn Sie eine einzelne Benachrichtigung erfassen. Sie sollten nicht vollständig andere Benachrichtigungen anzeigen, nur aufgrund eines Problems mit einer bestimmten Benachrichtigung.

// 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());

Der Inhalt der Benachrichtigung selbst, z. B. der Benachrichtigungstext, ist in der Eigenschaft "Notification" enthalten. Diese Eigenschaft enthält den visuellen Teil der Benachrichtigung. (Wenn Sie mit dem Senden von Benachrichtigungen unter Windows vertraut sind, werden Sie feststellen, dass die Visuelle und Visual.Bindings-Eigenschaften im Notification-Objekt entsprechen dem, was Entwickler beim Aufblättern einer Benachrichtigung senden.)

Wir möchten nach der Popupbindung suchen (für Fehlerprüfungscode sollten Sie überprüfen, ob die Bindung nicht NULL ist). Aus der Bindung können Sie die Textelemente abrufen. Sie können beliebig viele Textelemente anzeigen. (Im Idealfall sollten Sie alle anzeigen.) Sie können die Textelemente anders behandeln; Behandeln Sie z. B. den ersten text als Titeltext und nachfolgende Elemente als Textkörper.

// 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));
}

Entfernen einer bestimmten Benachrichtigung

Wenn Ihr Wearable oder Dienst es dem Benutzer ermöglicht, Benachrichtigungen zu schließen, können Sie die tatsächliche Benachrichtigung entfernen, damit der Benutzer sie später nicht auf dem Smartphone oder PC sieht. Geben Sie einfach die Benachrichtigungs-ID (abgerufen vom UserNotification-Objekt ) der Benachrichtigung an, die Sie entfernen möchten:

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

Alle Benachrichtigungen löschen

Die UserNotificationListener.ClearNotifications-Methode löscht alle Benachrichtigungen des Benutzers. Verwenden Sie diese Methode mit Vorsicht. Sie sollten nur alle Benachrichtigungen löschen, wenn Ihr Wearable oder Dienst ALLE Benachrichtigungen anzeigt. Wenn Ihr Wearable oder Dienst nur bestimmte Benachrichtigungen anzeigt, wenn der Benutzer auf die Schaltfläche "Benachrichtigungen löschen" klickt, erwartet der Benutzer nur, dass diese spezifischen Benachrichtigungen entfernt werden; Das Aufrufen der ClearNotifications-Methode würde jedoch tatsächlich dazu führen, dass alle Benachrichtigungen, einschließlich der Benachrichtigungen, die Ihr Wearable oder Dienst nicht anzeigt, entfernt werden.

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

Hintergrundaufgabe für Benachrichtigung hinzugefügt/geschlossen

Eine gängige Möglichkeit zum Abhören von Benachrichtigungen durch eine App besteht darin, eine Hintergrundaufgabe einzurichten, sodass Sie wissen können, wann eine Benachrichtigung hinzugefügt oder geschlossen wurde, unabhängig davon, ob Ihre App gerade ausgeführt wird.

Dank des einzelnen Prozessmodells, das im Anniversary Update hinzugefügt wurde, ist das Hinzufügen von Hintergrundaufgaben relativ einfach. Nachdem Sie im Code Ihrer Haupt-App zugriff auf den Benachrichtigungslistener des Benutzers erhalten und Zugriff auf die Ausführung von Hintergrundaufgaben erhalten haben, indem Sie UserNotificationListener.Current.RequestAccessAsync und BackgroundExecutionManager.RequestAccessAsync aufrufen, registrieren Sie einfach eine neue Hintergrundaufgabe, und legen Sie den UserNotificationChangedTrigger mithilfe der Toast-Benachrichtigungsart fest.

// 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();
}

Setzen Sie dann in Ihrem App.xaml.cs die OnBackgroundActivated-Methode außer Kraft, wenn sie noch nicht vorhanden ist, und verwenden Sie eine Switch-Anweisung für den Aufgabennamen, um zu bestimmen, welche ihrer vielen Hintergrundaufgabentrigger aufgerufen wurde.

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();
}

Die Hintergrundaufgabe ist einfach ein "Schultertippen": Sie enthält keine Informationen dazu, welche bestimmte Benachrichtigung hinzugefügt oder entfernt wurde. Wenn Ihre Hintergrundaufgabe ausgelöst wird, sollten Sie die Benachrichtigungen auf Ihrem Wearable synchronisieren, damit sie die Benachrichtigungen in der Plattform widerspiegeln. Dadurch wird sichergestellt, dass Benachrichtigungen auf Ihrem Wearable bei einem Fehlschlagen der Hintergrundaufgabe bei der nächsten Ausführung der Hintergrundaufgabe weiterhin wiederhergestellt werden können.

SyncNotifications ist eine Methode, die Sie implementieren; Im nächsten Abschnitt wird gezeigt, wie das geht.

Bestimmen, welche Benachrichtigungen hinzugefügt und entfernt wurden

SyncNotifications Um zu bestimmen, welche Benachrichtigungen hinzugefügt oder entfernt wurden (Synchronisierung von Benachrichtigungen mit Ihrem Wearable), müssen Sie das Delta zwischen Ihrer aktuellen Benachrichtigungssammlung und den Benachrichtigungen in der Plattform berechnen.

// 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);
}

Vordergrundereignis für hinzugefügte/geschlossene Benachrichtigung

Wichtig

Bekanntes Problem: Bei Builds vor Build 17763 / Oktober 2018 Update / Version 1809 führt das Vordergrundereignis zu einer CPU-Schleife und/oder funktionierte nicht. Wenn Sie Unterstützung für diese früheren Builds benötigen, verwenden Sie stattdessen die Hintergrundaufgabe.

Sie können auch Benachrichtigungen von einem In-Memory-Ereignishandler abhören...

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

Beheben von Verzögerungen in der Hintergrundaufgabe

Beim Testen Ihrer App stellen Sie möglicherweise fest, dass die Hintergrundaufgabe manchmal verzögert wird und nicht für mehrere Minuten ausgelöst wird. Um die Verzögerung zu beheben, fordern Sie den Benutzer auf, zu den Systemeinstellungen zu wechseln – System –> Akku –>> Akkunutzung nach App, suchen Sie Ihre App in der Liste, wählen Sie sie aus, und legen Sie ihn auf "Immer im Hintergrund zulässig" fest. Danach sollte die Hintergrundaufgabe immer innerhalb einer Sekunde der empfangenen Benachrichtigung ausgelöst werden.