Dela via


Meddelandelyssnare: Få åtkomst till alla meddelanden

Meddelandelyssnaren ger åtkomst till en användares meddelanden. Smartwatches och andra bärbara kan använda meddelandelyssnaren för att skicka telefonens meddelanden till den bärbara enheten. Appar för hemautomatisering kan använda meddelandelyssnare för att utföra specifika åtgärder när meddelanden tas emot, till exempel att få lamporna att blinka när du får ett samtal.

Important

Kräver Anniversary Update: Du måste sikta på SDK 14393 och köra version 14393 eller senare för att använda meddelandelyssnaren.

Viktiga API:er: klassen UserNotificationListener, UserNotificationChangedTrigger

Aktivera lyssnaren genom att lägga till funktionen Användarmeddelande

Om du vill använda meddelandelyssnaren måste du lägga till funktionen Lyssnare för användarmeddelanden i appmanifestet.

  1. I Visual Studio i Solution Explorer dubbelklickar du på din Package.appxmanifest-fil för att öppna manifestdesignern.
  2. Öppna fliken Funktioner.
  3. Kontrollera kapaciteten för User Notification Listener.

Kontrollera om lyssnaren stöds

Om din app stöder äldre versioner av Windows 10 måste du använda klassen ApiInformation för att kontrollera om lyssnaren stöds. Om lyssnaren inte stöds kan du undvika att köra några anrop till lyssnar-API:erna.

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

Begära åtkomst till lyssnaren

Eftersom lyssnaren tillåter åtkomst till användarens meddelanden måste användarna ge appen behörighet att komma åt sina meddelanden. Under appens första körning bör du begära åtkomst för att använda meddelandelyssnaren. Om du vill kan du visa ett preliminärt användargränssnitt som förklarar varför din app behöver åtkomst till användarens meddelanden innan du anropar RequestAccessAsync, så att användaren förstår varför de ska tillåta åtkomst.

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

Användaren kan när som helst återkalla åtkomst via Windows-inställningar. Därför bör appen alltid kontrollera åtkomststatusen via metoden GetAccessStatus innan du kör kod som använder meddelandelyssnaren. Om användaren återkallar åtkomst misslyckas API:erna tyst i stället för att utlösa ett undantag (till exempel returnerar API:et för att hämta alla meddelanden helt enkelt en tom lista).

Få åtkomst till användarens meddelanden

Med meddelandelyssnaren kan du få en lista över användarens aktuella meddelanden. Anropa bara metoden GetNotificationsAsync och ange vilken typ av aviseringar du vill få (just nu är den enda typen av aviseringar som stöds toast-aviseringar).

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

Visa meddelandena

Varje meddelande representeras som en UserNotification, som innehåller information om appen som meddelandet kommer från, när meddelandet skapades, meddelandets ID och själva meddelandet.

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

Egenskapen AppInfo innehåller den information du behöver för att visa meddelandet.

Note

Vi rekommenderar att du omger all din kod för att bearbeta en enskild avisering i en try/catch, ifall ett oväntat undantag inträffar när du bearbetar en enskild avisering. Du bör inte helt misslyckas med att visa andra meddelanden bara på grund av ett problem med ett specifikt meddelande.

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

Innehållet i själva meddelandet, till exempel meddelandetexten, finns i egenskapen Notification. Den här egenskapen innehåller den visuella delen av meddelandet. (Om du är bekant med att skicka meddelanden i Windows ser du att objektet Visual och Visual.Bindings i objektet Notification motsvarar vad utvecklare skickar när de skickar ett meddelande.)

Vi vill söka efter toastmeddelande-bindningen (för felfri kod bör du kontrollera att bindningen inte är null). Från bindningen kan du hämta textelementen. Du kan välja att visa så många textelement som du vill. (Helst bör du visa alla.) Du kan välja att behandla textelementen på olika sätt. Du kan till exempel behandla den första som rubriktext och efterföljande element som brödtext.

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

Ta bort ett specifikt meddelande

Om din bärbara eller tjänst tillåter att användaren stänger av meddelanden kan du ta bort det faktiska meddelandet så att användaren inte ser det senare på sin telefon eller dator. Ange bara meddelande-ID :t (hämtat från UserNotification-objektet) för meddelandet som du vill ta bort:

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

Rensa alla meddelanden

Metoden UserNotificationListener.ClearNotifications rensar alla användarens meddelanden. Använd den här metoden med försiktighet. Du bör bara rensa alla meddelanden om din bärbara eller tjänst visar ALLA meddelanden. Om din bärbara eller tjänst bara visar vissa meddelanden, när användaren klickar på knappen Rensa meddelanden, förväntar sig användaren bara att de specifika meddelandena tas bort. Att anropa metoden ClearNotifications skulle dock faktiskt leda till att alla meddelanden, inklusive de som din bärbara eller tjänst inte visade, tas bort.

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

Bakgrundsaktivitet för notis tillagd/avfärdad

Ett vanligt sätt att göra det möjligt för en app att lyssna på meddelanden är att konfigurera en bakgrundsaktivitet, så att du kan veta när ett meddelande har lagts till eller avvisats oavsett om din app körs för närvarande.

Tack vare den enkla processmodellen , som lades till i Anniversary Update, är det ganska enkelt att lägga till bakgrundsuppgifter. I huvudappens kod, när du har fått användarens åtkomst till meddelandelyssnaren och åtkomst till att köra bakgrundsuppgifter genom att anropa UserNotificationListener.Current.RequestAccessAsync och BackgroundExecutionManager.RequestAccessAsync, registrerar du enkelt en ny bakgrundsuppgift och ställer in UserNotificationChangedTrigger med typen toast-avisering.

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

I din App.xaml.cs åsidosätter du sedan metoden OnBackgroundActivated om du inte har gjort det ännu och använder en switch-instruktion för aktivitetsnamnet för att avgöra vilken av dina många bakgrundsaktivitetsutlösare som anropades.

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

Bakgrundsaktiviteten är bara en "axeltryckning": den ger ingen information om vilken specifik avisering som har lagts till eller tagits bort. När bakgrundsaktiviteten utlöses bör du synkronisera meddelandena på den bärbara datorn så att de återspeglar aviseringarna på plattformen. Detta säkerställer att om din bakgrundsaktivitet misslyckas kan meddelanden på din bärbara enhet fortfarande återställas nästa gång din bakgrundsaktivitet körs.

SyncNotifications är en metod som du implementerar. nästa avsnitt visar hur.

Avgöra vilka meddelanden som har lagts till och tagits bort

För att avgöra vilka meddelanden som har lagts till eller tagits bort (synkronisera meddelanden med din bärbara) i din SyncNotifications metod måste du beräkna deltat mellan din aktuella meddelandesamling och meddelandena på plattformen.

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

Förgrundshändelse för meddelande tillagd/avvisad

Important

Känt problem: I versioner före Build 17763, oktober 2018-uppdateringen eller version 1809 orsakade förgrundshändelsen en CPU-loop och/eller fungerade inte. Om du behöver stöd för dessa tidigare versioner använder du bakgrundsaktiviteten i stället.

Du kan också lyssna på meddelanden från en minnesintern händelsehanterare...

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

Så här åtgärdar du fördröjningar i bakgrundsaktiviteten

När du testar din app kanske du märker att bakgrundsaktiviteten ibland fördröjs och inte utlöses på flera minuter. Om du vill åtgärda fördröjningen uppmanar du användaren att gå till systeminställningarna –> System –> Batteri –> Batterianvändning per app, hitta din app i listan, välja den och ange att den alltid ska vara tillåten i bakgrunden. Efter detta bör bakgrundsaktiviteten alltid utlösas inom ungefär en sekund från meddelandet som tas emot.