Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Neste início rápido, você criará um aplicativo da área de trabalho do Windows que envia e recebe notificações de aplicativos locais, também conhecidas como notificações do sistema, usando o SDK de Aplicativo Windows.
Importante
Atualmente, não há suporte para notificações para um aplicativo elevado (admin).
Pré-requisitos
- Introdução ao WinUI
- Criar um novo projeto que usa o SDK do Aplicativo Windows OU Usar o SDK do Aplicativo Windows em um projeto existente
Aplicativo de exemplo
Este guia de início rápido abrange o código dos aplicativos de exemplo de notificações encontrados no GitHub.
Referência da API
Para obter a documentação de referência da API para notificações de aplicativos, consulte de namespace Microsoft.Windows.AppNotifications .
Etapa 1: Adicionar declarações de namespace
Adicione o namespace para notificações de apps do SDK do Windows Microsoft.Windows.AppNotifications
.
using Microsoft.Windows.AppNotifications;
Etapa 2: atualizar o manifesto do aplicativo
Se o seu aplicativo estiver desempacotado (ou seja, ele não tiver identidade de pacote no tempo de execução), pule para Etapa 3: Registrar-se para lidar com uma notificação de aplicativo.
Se o seu aplicativo estiver empacotado (inclusive empacotado com local externo):
- 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>
parawindows.toastNotificationActivation
declarar seu ativador COM CLSID. Você pode obter um CLSID navegando até Criar GUID em Ferramentas no Visual Studio. - Adicione
<com:Extension>
para o ativador COM usando o mesmo CLSID.- Especifique seu arquivo .exe no atributo
Executable
. O ficheiro .exe deve ser o mesmo do processo que chamaRegister()
ao registar a sua aplicação para notificações, o que é descrito mais detalhadamente em Etapa 3. No exemplo abaixo, usamosExecutable="SampleApp\SampleApp.exe"
. - Especifique
Arguments="----AppNotificationActivated:"
para garantir que o Windows App SDK possa processar a carga útil da sua notificação como um tipo AppNotification. - Especifique um
DisplayName
.
- Especifique seu arquivo .exe no atributo
Importante
Aviso: Se você definir um tipo de extensibilidade de aplicativo Windows.Protocol em seu manifesto appx com <uap:Protocol>
, clicar em notificações iniciará novos processos do mesmo aplicativo, mesmo que 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: Registre-se para lidar com uma notificação de aplicativo
Registe a sua aplicação para lidar com notificações e, em seguida, cancele o registo quando a aplicação for encerrada.
Em seu arquivo App.xaml
, registre AppNotificationManager::Default().NotificationInvokede, em seguida, chame AppNotificationManager::Default().Registe. A ordem destas convocatórias é importante.
Importante
Você deve chamar AppNotificationManager::Default(). Registar antes de chamar AppInstance.GetCurrent.GetActivatedEventArgs.
Quando o seu aplicativo estiver a terminar, chame AppNotificationManager::Default().Unregister() para libertar o servidor COM e permitir futuras invocações para lançar um novo processo.
- C#
- C++
// 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 de aplicativo
Você DEVE concluir Etapa 3: Registre-se para lidar com uma de notificação de aplicativo antes de prosseguir.
Agora você exibirá uma notificação de aplicativo simples com uma imagem appLogoOverride
e um botão.
Construa sua notificação de aplicativo usando a classe AppNotificationBuilder e chame Show
. Para obter mais informações sobre como construir a sua notificação de aplicativo usando XML, consulte os exemplos em conteúdo de Toast e o esquema XML de Notificações .
Observação
Se a sua aplicação estiver empacotada (inclusive empacotada com localização externa), o ícone da aplicação no canto superior esquerdo da notificação é obtido a partir de package.manifest
. Se o seu aplicativo estiver desempacotado, o ícone será originado primeiro olhando para o atalho e, em seguida, olhando para 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 suportados são .jpg
, .png
, .bmp
e .ico
.
- C#
- C++
// 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 sua notificação. Seu aplicativo precisa processar a invocação em resposta a um usuário interagindo com sua notificação.
Existem 2 maneiras comuns de processar isso:
- Você opta por fazer com que seu aplicativo seja iniciado em um contexto específico da interface do usuário OU
- Você opta por fazer com que seu aplicativo avalie um comportamento específico da ação (como pressionar um botão no corpo da notificação) sem renderizar nenhuma interface do usuário. Também conhecida como ação em segundo plano.
O exemplo de código abaixo, que não é do aplicativo de exemplo, ilustra ambas as maneiras de processar uma ação gerada pelo usuário. Adicione um valor launch
(corresponde ao usuário clicando 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 clicando no botão) à carga XML da sua notificação. Na sua ProcessLaunchActivationArgs
, trate cada argumento.
Importante
A configuração activationType="background"
na carga XML de notificação é ignorada para aplicações 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 orientações abaixo:
- Se uma notificação for selecionada pelo usuário e 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 seu aplicativo for minimizado, espera-se que seu aplicativo seja trazido para o 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 a caixa de texto de notificação e pressionando responder), seu aplicativo processa a carga sem renderizar uma janela de primeiro plano.
Consulte o código de aplicativo de exemplo encontrado em do GitHub para obter 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 bate-papo em grupo em seu aplicativo, portanto, você limpa todas as notificações do bate-papo em grupo. Em seguida, o usuário silencia um amigo, para que você limpe todas as notificações do amigo. Primeiro, você adicionou as propriedades Group e Tag à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);
}
Características adicionais
Enviar uma notificação de aplicativo originado na nuvem
Para enviar uma notificação de aplicativo a partir da nuvem, siga Enviar uma notificação de aplicativo originada na nuvem em Quickstart: notificações por push noWindows App SDK.
Definir um tempo de expiração
Defina um tempo de expiração na notificação do seu aplicativo usando a propriedade Expiration
se a mensagem na sua notificação for relevante apenas por um determinado período de tempo. Por exemplo, se você enviar um lembrete de evento do calendário, defina o tempo de expiração para o final do evento do calendário.
Observação
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)
}
}
Garantir que as notificações expirem na reinicialização
Defina a propriedade ExpiresOnReboot
como True se quiser que as notificações sejam excluídas na reinicialização.
- C#
- C++
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:
Use a construção 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.
}
}
Recursos
- de detalhes da API Microsoft.Windows.AppNotifications
- Exemplo de código de notificações no GitHub
- Especificações de notificações de aplicativos no GitHub
- Conteúdo da notificação
- Esquema XML de Notificações
Windows developer