Condividi tramite


Listener di notifica: accedere a tutte le notifiche

Il listener di notifica fornisce l'accesso alle notifiche di un utente. Gli smartphone e altri dispositivi indossabili possono usare il listener di notifica per inviare le notifiche del telefono al dispositivo indossabile. Le app di automazione home possono usare il listener di notifica per eseguire azioni specifiche quando vengono ricevute notifiche, ad esempio facendo lampeggiare le luci quando si riceve una chiamata.

Importante

Richiede l'aggiornamento dell'anniversario: è necessario avere come destinazione l'SDK 14393 ed eseguire la build 14393 o successiva per usare il listener di notifica.

API importanti: classe UserNotificationListener, classe UserNotificationChangedTrigger

Abilitazione del listener aggiungendo la funzionalità Notifica utente

Per usare il listener di notifica, devi aggiungere la funzionalità Listener di notifica utente al manifesto dell'app.

  1. In Visual Studio, nel Solution Explorer, fai doppio clic sul tuo file Package.appxmanifest per aprire la Progettazione manifesto.
  2. Apri la scheda Capacità.
  3. Controlla la funzionalità Listener di notifica utente.

Controlla se il listener è supportato

Se la tua app supporta versioni precedenti di Windows 10, devi usare la classe ApiInformation per verificare se il listener è supportato. Se il listener non è supportato, evita di eseguire chiamate alle API del listener.

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

Richiesta di accesso al listener

Poiché il listener consente l'accesso alle notifiche dell'utente, gli utenti devono concedere all'app l'autorizzazione per accedere alle notifiche. Durante la prima esecuzione dell'app, devi richiedere l'accesso per usare il listener di notifica. Se vuoi, puoi mostrare un'interfaccia utente preliminare che spiega perché l'app deve accedere alle notifiche dell'utente prima di chiamare RequestAccessAsync, in modo che l'utente comprenda il motivo per cui deve consentire l'accesso.

// 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'utente può revocare l'accesso in qualsiasi momento tramite Windows Impostazioni. Pertanto, l'app deve sempre controllare lo stato di accesso tramite il metodo GetAccessStatus prima di eseguire il codice che usa il listener di notifica. Se l'utente revoca l'accesso, le API avranno esito negativo in modo invisibile all'utente anziché generare un'eccezione( ad esempio, l'API per ottenere tutte le notifiche restituirà semplicemente un elenco vuoto).

Accesso alle notifiche dell'utente

Con il listener di notifica puoi ottenere un elenco delle notifiche correnti dell'utente. È sufficiente chiamare il metodo GetNotificationsAsync e specificare il tipo di notifiche che si desidera ottenere (attualmente l'unico tipo di notifiche supportate sono notifiche di tipo avviso popup).

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

Visualizzazione delle notifiche

Ogni notifica è rappresentata come UserNotification, che fornisce informazioni sull'app da cui proviene la notifica, l'ora di creazione della notifica, l'ID della notifica e la notifica stessa.

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

La proprietà AppInfo fornisce le informazioni necessarie per visualizzare la notifica.

Nota

Raccomandiamo di racchiudere tutto il codice per l'elaborazione di una singola notifica in un tentativo/catch, nel caso in cui si verifichi un'eccezione imprevista quando si acquisisce una singola notifica. Non è consigliabile visualizzare completamente altre notifiche solo a causa di un problema con una notifica specifica.

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

Il contenuto della notifica stessa, ad esempio il testo della notifica, è contenuto nella proprietà Notification . Questa proprietà contiene la parte visiva della notifica. (Se hai familiarità con l'invio di notifiche in Windows, si noterà che Le proprietà Visual e Visual.Bindings nell'oggetto Notification corrispondono a ciò che gli sviluppatori inviano quando estrae una notifica.)

Intendiamo cercare l'associazione di tipo avviso popup (per il codice di correzione degli errori, è necessario verificare che l'associazione non sia Null). Dall'associazione puoi ottenere gli elementi di testo. Puoi scegliere di visualizzare tutti gli elementi di testo desiderati. (Idealmente, dovresti visualizzarli tutti). È possibile scegliere di trattare gli elementi di testo in modo diverso; Ad esempio, considerare il primo come testo del titolo e gli elementi successivi come testo del corpo.

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

Rimuovere una notifica specifica

Se il dispositivo indossabile o il servizio consente all'utente di ignorare le notifiche, puoi rimuovere la notifica effettiva in modo che l'utente non lo visualizzi in un secondo momento sul telefono o sul PC. Specificare semplicemente l'ID notifica (ottenuto dall'oggetto UserNotification ) della notifica che vuoi rimuovere:

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

Cancellazione di tutte le notifiche

Il metodo UserNotificationListener.ClearNotifications cancella tutte le notifiche dell'utente. Usa questo metodo con cautela. È consigliabile cancellare tutte le notifiche solo se il dispositivo indossabile o il servizio visualizza tutte le notifiche. Se il dispositivo indossabile o il servizio visualizza solo determinate notifiche, quando l'utente fa clic sul pulsante "Cancella notifiche", l'utente si aspetta che vengano rimosse solo le notifiche specifiche; Tuttavia, la chiamata al metodo ClearNotifications provocherebbe effettivamente la rimozione di tutte le notifiche, incluse quelle che il dispositivo indossabile o il servizio non stava visualizzando.

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

Attività in background per la notifica aggiunta/chiusura

Un modo comune per consentire a un'app di ascoltare le notifiche consiste nel configurare un'attività in background, in modo da sapere quando è stata aggiunta o chiusa una notifica indipendentemente dal fatto che l'app sia attualmente in esecuzione.

Grazie al modello a processo singolo aggiunto nell'aggiornamento dell'anniversario, l'aggiunta di attività in background è piuttosto semplice. Nel codice dell'app principale, dopo aver ottenuto l'accesso dell'utente al listener di notifica e aver ottenuto l'accesso per eseguire le attività in background chiamando UserNotificationListener.Current.RequestAccessAsync e BackgroundExecutionManager.RequestAccessAsync , è sufficiente registrare una nuova attività in background e impostare UserNotificationChangedTrigger usando il tipo di notifica Avviso popup.

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

Quindi, nel App.xaml.cs eseguire l'override del metodo OnBackgroundActivated se non è ancora stato fatto e usare un'istruzione switch sul nome dell'attività per determinare quale dei numerosi trigger di attività in background è stato richiamato.

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

L'attività in background è semplicemente un "tocco a spalla": non fornisce informazioni su quale notifica specifica è stata aggiunta o rimossa. Quando viene attivata l'attività in background, devi sincronizzare le notifiche sul dispositivo indossabile in modo che riflettano le notifiche nella piattaforma. In questo modo, se l'attività in background ha esito negativo, le notifiche sul dispositivo indossabile possono comunque essere recuperate al successivo esecuzione dell'attività in background.

SyncNotifications è un metodo implementato; nella sezione successiva viene illustrato come.

Determinazione delle notifiche aggiunte e rimosse

Nel tuo SyncNotifications metodo, per determinare quali notifiche sono state aggiunte o rimosse (sincronizzazione delle notifiche con il dispositivo indossabile), è necessario calcolare il delta tra la raccolta di notifiche corrente e le notifiche nella piattaforma.

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

Evento in primo piano per la notifica aggiunta/chiusura

Importante

Problema noto: nelle build precedenti alla build 17763/ottobre 2018 Update / Versione 1809, l'evento in primo piano causerà un ciclo cpu e/o non funzionava. Se è necessario il supporto per queste build precedenti, usare invece l'attività in background.

È anche possibile ascoltare le notifiche da un gestore eventi in memoria...

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

Come correggere i ritardi nell'attività in background

Durante il test dell'app, potresti notare che l'attività in background a volte viene ritardata e non viene attivata per alcuni minuti. Per correggere il ritardo, chiedere all'utente di passare alle impostazioni di sistema -> Sistema - Batteria ->> Utilizzo batteria per app, trovare l'app nell'elenco, selezionarla e impostarla su "Sempre consentito in background". Successivamente, l'attività in background deve essere sempre attivata entro un secondo della notifica ricevuta.