Eventi
19 nov, 23 - 21 nov, 23
Ottenere il vantaggio competitivo necessario con potenti soluzioni di intelligenza artificiale e cloud partecipando a Microsoft Ignite online.
Iscriviti subitoQuesto browser non è più supportato.
Esegui l'aggiornamento a Microsoft Edge per sfruttare i vantaggi di funzionalità più recenti, aggiornamenti della sicurezza e supporto tecnico.
In questo argomento di avvio rapido si creerà un'applicazione Windows desktop che invia e riceve notifiche di app locali, note anche come notifiche di tipo avviso popup, usando Windows App SDK.
Importante
Le notifiche per un'app con privilegi elevati (amministratore) non sono attualmente supportate.
Questa guida introduttiva illustra il codice delle app di esempio di notifiche disponibili in GitHub.
Per la documentazione di riferimento sulle API per le notifiche push, vedere Spazio dei nomi Microsoft.Windows.AppNotifications.
Aggiungere lo spazio dei nomi per notifiche app Windows App SDK Microsoft.Windows.AppNotifications
.
using Microsoft.Windows.AppNotifications;
Se l'app non è in pacchetto ( ovvero manca l'identità del pacchetto in fase di esecuzione), passare al passaggio 3: Registrarsi per gestire una notifica dell'app.
Se l'app viene inserita in un pacchetto (incluso il pacchetto con la posizione esterna):
xmlns:com="http://schemas.microsoft.com/appx/manifest/com/windows10"
and xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10"
a <Package>
<desktop:Extension>
per windows.toastNotificationActivation
in modo da dichiarare il CLSID dell'attivatore COM. È possibile ottenere un CLSID passando a Crea GUID in Strumenti in Visual Studio.<com:Extension>
per l'attivatore COM usando lo stesso CLSID.
Executable
. Il file .exe deve essere lo stesso processo che chiama Register()
durante la registrazione dell'app per le notifiche, come descritto più dettagliatamente nel Passaggio 3. Nell'esempio seguente, usiamo Executable="SampleApp\SampleApp.exe"
.Arguments="----AppNotificationActivated:"
per assicurarsi che Windows App SDK possa elaborare il payload della notifica come tipo AppNotification.DisplayName
.Importante
Avviso: se si definisce un tipo di estendibilità dell'app Windows.Protocol nel manifesto appx con <uap:Protocol>
, facendo clic sulle notifiche verranno eseguiti nuovi processi della stessa app, anche se l'app è già in esecuzione.
<!--Packaged apps only-->
<!--package.appxmanifest-->
<Package
xmlns:com="http://schemas.microsoft.com/appx/manifest/com/windows10"
xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10"
...
<Applications>
<Application>
...
<Extensions>
<!--Specify which CLSID to activate when notification is clicked-->
<desktop:Extension Category="windows.toastNotificationActivation">
<desktop:ToastNotificationActivation ToastActivatorCLSID="replaced-with-your-guid-C173E6ADF0C3" />
</desktop:Extension>
<!--Register COM CLSID-->
<com:Extension Category="windows.comServer">
<com:ComServer>
<com:ExeServer Executable="SampleApp\SampleApp.exe" DisplayName="SampleApp" Arguments="----AppNotificationActivated:">
<com:Class Id="replaced-with-your-guid-C173E6ADF0C3" />
</com:ExeServer>
</com:ComServer>
</com:Extension>
</Extensions>
</Application>
</Applications>
</Package>
Registrare l'app per gestire le notifiche, quindi annullare la registrazione al termine dell'app.
Nel file App.xaml
, registrare per AppNotificationManager::Default().NotificationInvoked, poi richiamare AppNotificationManager::Default().Register. L'ordine di queste chiamate è importante.
Importante
È necessario richiedere PushNotificationManager::Default().Register prima di richiedere AppInstance.GetCurrent.GetActivatedEventArgs.
Quando l'app termina, richiedere AppNotificationManager::Default(). Annullare la registrazione() per liberare il server COM e consentire ai richiami successivi di avviare un nuovo processo.
// App.xaml.cs
namespace CsUnpackagedAppNotifications
{
public partial class App : Application
{
private Window mainWindow;
private NotificationManager notificationManager;
public App()
{
this.InitializeComponent();
notificationManager = new NotificationManager();
AppDomain.CurrentDomain.ProcessExit += new EventHandler(OnProcessExit);
}
protected override void OnLaunched(LaunchActivatedEventArgs args)
{
mainWindow = new MainWindow();
notificationManager.Init();
// Complete in Step 5
mainWindow.Activate();
}
void OnProcessExit(object sender, EventArgs e)
{
notificationManager.Unregister();
}
}
}
// NotificationManager.cs
namespace CsUnpackagedAppNotifications
{
internal class NotificationManager
{
private bool m_isRegistered;
private Dictionary<int, Action<AppNotificationActivatedEventArgs>> c_map;
public NotificationManager()
{
m_isRegistered = false;
// When adding new a scenario, be sure to add its notification handler here.
c_map = new Dictionary<int, Action<AppNotificationActivatedEventArgs>>();
c_map.Add(ToastWithAvatar.ScenarioId, ToastWithAvatar.NotificationReceived);
c_map.Add(ToastWithTextBox.ScenarioId, ToastWithTextBox.NotificationReceived);
}
~NotificationManager()
{
Unregister();
}
public void Init()
{
// To ensure all Notification handling happens in this process instance, register for
// NotificationInvoked before calling Register(). Without this a new process will
// be launched to handle the notification.
AppNotificationManager notificationManager = AppNotificationManager.Default;
notificationManager.NotificationInvoked += OnNotificationInvoked;
notificationManager.Register();
m_isRegistered = true;
}
public void Unregister()
{
if (m_isRegistered)
{
AppNotificationManager.Default.Unregister();
m_isRegistered = false;
}
}
public void ProcessLaunchActivationArgs(AppNotificationActivatedEventArgs notificationActivatedEventArgs)
{
// Complete in Step 5
}
}
}
È NECESSARIO completare il passaggio 3: Eseguire la registrazione per gestire una notifica dell'app prima di procedere.
A questo punto si visualizzerà una semplice notifica dell'app con una appLogoOverride
immagine e un pulsante.
Creare la notifica dell'app usando la classe AppNotificationBuilder e quindi chiamare Show
. Per altre informazioni su come costruire la notifica dell'app tramite XML, vedere gli esempi in Contenuto dell'avviso popup e lo schema XML delle notifiche.
Nota
Se l'app è inclusa in un pacchetto con posizione esterna, l'icona dell'app nell'angolo superiore sinistro della notifica viene originata da package.manifest
. Se l'app non è inclusa nel pacchetto, l'icona viene originata esaminando prima il collegamento, quindi esaminando il file di risorse nel processo dell'app. Se tutti i tentativi hanno esito negativo, viene usata l'icona dell'app predefinita di Windows. Sono supportati i tipi di file .jpg
, .png
, .bmp
, e .ico
.
// ToastWithAvatar.cs
class ToastWithAvatar
{
public const int ScenarioId = 1;
public const string ScenarioName = "Local Toast with Avatar Image";
public static bool SendToast()
{
var appNotification = new AppNotificationBuilder()
.AddArgument("action", "ToastClick")
.AddArgument(Common.scenarioTag, ScenarioId.ToString())
.SetAppLogoOverride(new System.Uri("file://" + App.GetFullPathToAsset("Square150x150Logo.png")), AppNotificationImageCrop.Circle)
.AddText(ScenarioName)
.AddText("This is an example message using XML")
.AddButton(new AppNotificationButton("Open App")
.AddArgument("action", "OpenApp")
.AddArgument(Common.scenarioTag, ScenarioId.ToString()))
.BuildNotification();
AppNotificationManager.Default.Show(appNotification);
return appNotification.Id != 0; // return true (indicating success) if the toast was sent (if it has an Id)
}
public static void NotificationReceived(AppNotificationActivatedEventArgs notificationActivatedEventArgs)
{
// Complete in Step 5
}
}
// Call SendToast() to send a notification.
Gli utenti possono selezionare il corpo o il pulsante della notifica. L'app deve elaborare la chiamata in risposta a un utente che interagisce con la notifica.
Esistono due modi comuni per elaborare questa procedura:
L'esempio di codice seguente, che non proviene dall'app di esempio, illustra entrambi i modi di elaborazione di un'azione generata dall'utente. Aggiungere un launch
valore (corrisponde all'utente facendo clic sul corpo della notifica), un input
elemento (casella di testo risposta rapida) e un pulsante con un arguments
valore (corrisponde all'utente che fa clic sul pulsante) al payload XML della notifica. In questo ProcessLaunchActivationArgs
caso per ciascun argomento.
Importante
L'impostazione activationType="background"
nel payload XML di notifica viene ignorata per le app desktop. È invece necessario elaborare gli argomenti di attivazione e decidere se visualizzare una finestra o meno, come indicato in questo passaggio.
// Example of how to process a user either selecting the notification body or inputting a quick reply in the text box.
// Notification XML payload
//<toast launch="action=openThread&threadId=92187">
// <visual>
// <binding template="ToastGeneric">
// <image placement="appLogoOverride" hint-crop="circle" src="C:\<fullpath>\Logo.png"/>
// <text>Local Toast with Avatar and Text box</text>
// <text>This is an example message using</text>
// </binding>
// </visual>
// <actions>
// <input id="replyBox" type="text" placeHolderContent="Reply" />
// <action
// content="Send"
// hint-inputId="replyBox"
// arguments="action=reply&threadId=92187" />
// </actions>
//</toast>
void ProcessLaunchActivationArgs(const winrt::AppNotificationActivatedEventArgs& notificationActivatedEventArgs)
{
// If the user clicks on the notification body, your app needs to launch the chat thread window
if (std::wstring(notificationActivatedEventArgs.Argument().c_str()).find(L"openThread") != std::wstring::npos)
{
GenerateChatThreadWindow();
}
else // If the user responds to a message by clicking a button in the notification, your app needs to reply back to the other user with no window launched
if (std::wstring(notificationActivatedEventArgs.Argument().c_str()).find(L"reply") != std::wstring::npos)
{
auto input = notificationActivatedEventArgs.UserInput();
auto replyBoxText = input.Lookup(L"replyBox");
// Process the reply text
SendReplyToUser(replyBoxText);
}
}
Attenersi alle linee guida seguenti:
Per un esempio più dettagliato, vedere il codice dell'app di esempio disponibile in GitHub .
Rimuovere le notifiche quando non sono più rilevanti per l'utente.
In questo esempio, l'utente ha visto tutti i messaggi di una chat di gruppo nell'app, in modo da cancellare tutte le notifiche dalla chat di gruppo. Quindi, l'utente disattiva un amico, in modo da cancellare tutte le notifiche dall'amico. In primo luogo, le proprietà Gruppo e Tag sono state aggiunte alle notifiche prima di visualizzarle per identificarle ora.
void SendNotification(winrt::hstring const& payload, winrt::hstring const& friendId, winrt::hstring const& groupChatId)
{
winrt::AppNotification notification(payload);
// Setting Group Id here allows clearing notifications from a specific chat group later
notification.Group(groupChatId);
// Setting Tag Id here allows clearing notifications from a specific friend later
notification.Tag(friendId);
winrt::AppNotificationManager::Default().Show(notification);
}
winrt::Windows::Foundation::IAsyncAction RemoveAllNotificationsFromGroupChat(const std::wstring groupChatId)
{
winrt::AppNotificationManager manager = winrt::AppNotificationManager::Default();
co_await manager.RemoveByGroupAsync(groupChatId);
}
winrt::Windows::Foundation::IAsyncAction RemoveAllNotificationsFromFriend(const std::wstring friendId)
{
winrt::AppNotificationManager manager = winrt::AppNotificationManager::Default();
co_await manager.RemoveByTagAsync(friendId);
}
Per inviare una notifica dell'app dal cloud, seguire Inviare una notifica dell'app di origine cloud all'indirizzo Avvio rapido: Notifiche push Windows App SDK.
Impostare un'ora di scadenza per la notifica dell'app usando la Expiration
proprietà se il messaggio nella notifica è rilevante solo per un determinato periodo di tempo. Ad esempio, se si invia un promemoria dell'evento del calendario, impostare l'ora di scadenza sulla fine dell'evento del calendario.
Nota
Il tempo di scadenza predefinito e massimo è di 3 giorni.
class ToastWithAvatar
{
public static bool SendToast()
{
var appNotification = new AppNotificationBuilder()
.SetAppLogoOverride(new System.Uri("ms-appx:///images/logo.png"), AppNotificationImageCrop.Circle)
.AddText("Example expiring notification")
.AddText("This is an example message")
.BuildNotification();
appNotification.Expiration = DateTime.Now.AddDays(1);
AppNotificationManager.Default.Show(appNotification);
return appNotification.Id != 0; // return true (indicating success) if the toast was sent (if it has an Id)
}
}
Impostare la ExpiresOnReboot
proprietà su Vero se si desidera che le notifiche vengano eliminate al riavvio.
class ToastWithAvatar
{
public static bool SendToast()
{
var appNotification = new AppNotificationBuilder()
.SetAppLogoOverride(new System.Uri("ms-appx:///images/logo.png"), AppNotificationImageCrop.Circle)
.AddText("Example ExpiresOnReboot notification")
.AddText("This is an example message")
.BuildNotification();
appNotification.ExpiresOnReboot = true;
AppNotificationManager.Default.Show(appNotification);
return appNotification.Id != 0; // return true (indicating success) if the toast was sent (if it has an Id)
}
}
È possibile visualizzare gli aggiornamenti correlati alla barra di stato in una notifica:
Usare il AppNotificationProgressData
costrutto per aggiornare la notifica dell'indicatore di stato.
const winrt::hstring c_tag = L"weekly-playlist";
const winrt::hstring c_group = L"downloads";
// Send first Notification Progress Update
void SendUpdatableNotificationWithProgress()
{
auto notification{ winrt::AppNotificationBuilder()
.AddText(L"Downloading this week's new music...")
.AddProgressBar(winrt::AppNotificationProgressBar()
.BindTitle()
.BindValue()
.BindValueStringOverride()
.BindStatus())
.BuildNotification() }
notification.Tag(c_tag);
notification.Group(c_group);
// Assign initial values for first notification progress UI
winrt::AppNotificationProgressData data(1); // Sequence number
data.Title(L"Weekly playlist"); // Binds to {progressTitle} in xml payload
data.Value(0.6); // Binds to {progressValue} in xml payload
data.ValueStringOverride(L"15/26 songs"); // Binds to {progressValueString} in xml payload
data.Status(L"Downloading..."); // Binds to {progressStatus} in xml payload
notification.Progress(data);
winrt::AppNotificationManager::Default().Show(notification);
}
// Send subsequent progress updates
winrt::Windows::Foundation::IAsyncAction UpdateProgressAsync()
{
// Assign new values
winrt::AppNotificationProgressData data(2 /* Sequence number */ );
data.Title(L"Weekly playlist"); // Binds to {progressTitle} in xml payload
data.Value(0.7); // Binds to {progressValue} in xml payload
data.ValueStringOverride(L"18/26 songs"); // Binds to {progressValueString} in xml payload
data.Status(L"Downloading..."); // Binds to {progressStatus} in xml payload
auto result = co_await winrt::AppNotificationManager::Default().UpdateAsync(data, c_tag, c_group);
if (result == winrt::AppNotificationProgressResult::AppNotificationNotFound)
{
// Progress Update failed since the previous notification update was dismissed by the user! So account for this in your logic by stopping updates or starting a new Progress Update flow.
}
}
Feedback su Windows developer
Windows developer è un progetto di open source. Selezionare un collegamento per fornire feedback:
Eventi
19 nov, 23 - 21 nov, 23
Ottenere il vantaggio competitivo necessario con potenti soluzioni di intelligenza artificiale e cloud partecipando a Microsoft Ignite online.
Iscriviti subito