Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Neste Guia de início rápido, você criará um aplicativo de desktop do Windows que envia e recebe notificações locais do aplicativo, também conhecidas como notificações do tipo toast, usando o Windows App SDK .
Important
No momento, não há suporte para notificações para um aplicativo com privilégios elevados (administrador).
Prerequisites
- Introdução ao WinUI
- Criar um novo projeto que usa o SDK de Aplicativos do Windows OU Usar o SDK do Aplicativo do Windows em um projeto existente
Sample app
Este início rápido aborda o código dos aplicativos de exemplo de notificações encontrados no GitHub.
API reference
Para obter a documentação de referência da API para notificações de aplicativo, confira o Namespace Microsoft.Windows.AppNotifications.
Etapa 1: Adicionar declarações de namespace
Adicione o namespace para notificações de aplicativo do Windows App SDK Microsoft.Windows.AppNotifications.
using Microsoft.Windows.AppNotifications;
Etapa 2: atualizar o manifesto do aplicativo
Se o aplicativo estiver desempacotado (ou seja, ele não tem identidade de pacote em tempo de execução), pule para Etapa 3: Registrar-se para lidar com uma notificação de aplicativo.
Se seu aplicativo estiver empacotado (incluindo empacotado com localização externa):
- Abra o Package.appxmanifest .
- Adicionar namespaces
xmlns:com="http://schemas.microsoft.com/appx/manifest/com/windows10"exmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10"a<Package> - Adicione
<desktop:Extension>aowindows.toastNotificationActivationpara declarar o CLSID do seu ativador COM . Você pode obter um CLSID navegando até Criar GUID em Tools no Visual Studio. - Adicione
<com:Extension>para o ativador COM usando o mesmo CLSID.- Especifique o arquivo .exe no atributo
Executable. O arquivo .exe deve ser o mesmo processo que chamaRegister()ao registrar seu aplicativo para receber notificações, conforme descrito em Etapa 3. No exemplo abaixo, usamosExecutable="SampleApp\SampleApp.exe". - Especifique
Arguments="----AppNotificationActivated:"para garantir que o SDK do Aplicativo windows possa processar o conteúdo da notificação como um tipo AppNotification. - Especifique um
DisplayName.
- Especifique o arquivo .exe no atributo
Important
Aviso: se você definir um tipo de extensibilidade de aplicativo Windows.Protocol no manifesto appx com <uap:Protocol>, clicar em notificações iniciará novos processos do mesmo aplicativo, mesmo que o seu aplicativo já esteja em execução.
<!--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>
Etapa 3: registro para lidar com uma notificação do aplicativo
Registre seu aplicativo para lidar com notificações e cancele o registro quando seu aplicativo for encerrado.
No arquivo App.xaml, registre-se em AppNotificationManager::Default().NotificationInvoked e, em seguida, chame AppNotificationManager::Default().Register. A ordem dessas chamadas importa.
Important
Você deve chamar AppNotificationManager::D efault(). Registre antes de chamar AppInstance.GetCurrent.GetActivatedEventArgs.
Quando o aplicativo estiver sendo encerrado, chame AppNotificationManager::Default().Cancelar o cadastro() para liberar o servidor COM e permitir que as invocações subsequentes iniciem um novo 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
}
}
}
Etapa 4: exibir uma notificação do aplicativo
Você DEVE concluir Etapa 3: Registre-se para lidar com uma notificação do aplicativo antes de continuar.
Agora você exibirá uma notificação simples do aplicativo com uma imagem appLogoOverride e um botão.
Construa a notificação do aplicativo usando a classe AppNotificationBuilder e, em seguida, chame Show. Para obter mais informações sobre como construir a notificação do aplicativo usando XML, confira os exemplos de Conteúdo de notificação do sistema e o Esquema XML de notificações.
Note
Se o seu aplicativo estiver empacotado (incluindo empacotado com localização externa), então o ícone do aplicativo no canto superior esquerdo da notificação será proveniente do package.manifest. Se o aplicativo estiver desempacotado, o ícone é obtido primeiro ao verificar o atalho e, em seguida, consultando o arquivo de recurso no processo do aplicativo. Se todas as tentativas falharem, o ícone do aplicativo padrão do Windows será usado. Os tipos de arquivo de ícone com suporte são .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.
Etapa 5: processar um usuário selecionando uma notificação
Os usuários podem selecionar o corpo ou o botão da notificação. Seu aplicativo precisa processar a invocação em resposta a um usuário interagir com sua notificação.
Há duas maneiras comuns de processar isso:
- Você opta por iniciar seu aplicativo em um contexto específico da interface do usuário OU
- Você escolhe fazer com que seu aplicativo avalie um comportamento específico de ação (como o pressionamento de um botão no corpo da notificação) sem renderizar nenhuma UI. Também conhecida como uma ação em segundo plano.
O exemplo de código abaixo, que não é do aplicativo de exemplo, ilustra as duas maneiras de processar uma ação gerada pelo usuário. Adicione um valor launch (corresponde ao usuário clicar no corpo da notificação), um elemento input (caixa de texto de resposta rápida) e um botão com um valor arguments (corresponde ao usuário clicar no botão) ao conteúdo XML da notificação. No seu ProcessLaunchActivationArgs, lide com cada argumento separadamente.
Important
A configuração activationType="background" na carga XML de notificação é ignorada para aplicativos da área de trabalho. Em vez disso, você deve processar os argumentos de ativação e decidir se deseja exibir uma janela ou não, conforme indicado nesta etapa.
// 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);
}
}
Siga as diretrizes abaixo:
- Se uma notificação for selecionada pelo usuário e o seu aplicativo não estiver em execução, espera-se que seu aplicativo seja iniciado e o usuário possa ver a janela de primeiro plano no contexto da notificação.
- Se uma notificação for selecionada pelo usuário e o seu aplicativo for minimizado, espera-se que seu aplicativo seja colocado em primeiro plano e uma nova janela seja renderizada no contexto da notificação.
- Se uma ação em segundo plano de notificação for invocada pelo usuário (por exemplo, o usuário responde a uma notificação digitando na caixa de texto de notificação e pressionando Responder), seu aplicativo processará o conteúdo sem renderizar uma janela de primeiro plano.
Confira o código de aplicativo de exemplo encontrado no GitHub para ver um exemplo mais detalhado.
Etapa 6: remover notificações
Remova as notificações quando elas não forem mais relevantes para o usuário.
Neste exemplo, o usuário viu todas as mensagens de um chat em grupo em seu aplicativo, então você limpa todas as notificações do chat em grupo. Em seguida, o usuário silencia um amigo, então você limpa todas as notificações desse amigo. Primeiro, você adicionou as propriedades Grupo e Marca às notificações antes de exibi-las para identificá-las agora.
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);
}
Additional features
Enviar uma notificação de aplicativo de origem na nuvem
Para enviar uma notificação de aplicativo da nuvem, siga Enviar uma notificação de aplicativo de origem na nuvem em Início rápido: notificações por push no SDK do Aplicativo Windows.
Definir um tempo de expiração
Defina um tempo de expiração na notificação do aplicativo usando a propriedade Expiration se a mensagem na notificação for relevante apenas por um determinado período de tempo. Por exemplo, se você enviar um lembrete de evento de calendário, defina o tempo de expiração para o final do evento de calendário.
Note
O tempo de expiração padrão e máximo é de 3 dias.
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)
}
}
Garanta que as notificações expirem na reinicialização
Defina a propriedade ExpiresOnReboot para True para que as notificações sejam excluídas na reinicialização.
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)
}
}
Enviar e atualizar uma notificação da barra de progresso
Você pode exibir atualizações relacionadas à barra de progresso em uma notificação:
Notificação 
Use o constructo AppNotificationProgressData para atualizar a notificação da barra de progresso.
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.
}
}
Resources
Windows developer