Enviar uma notificação do sistema local de aplicativos UWP C++

Uma notificação do sistema é uma mensagem que seu aplicativo pode construir e entregar ao usuário enquanto ele não está dentro do aplicativo.

Captura de tela de uma notificação do sistema

Este guia de início rápido orienta você pelas etapas para criar, entregar e exibir uma notificação do sistema do Windows 10 ou Windows 11 usando conteúdo avançado e ações interativas. Este guia de início rápido usa notificações locais, que são as notificações mais simples de implementar. Todos os tipos de aplicativos (WPF, UWP, WinForms, console) podem enviar notificações!

Importante

Se você estiver escrevendo um aplicativo C++ não UWP, consulte a documentação da WRL do C++. Se você estiver escrevendo um aplicativo C#, consulte a documentação do C#.

Etapa 1: Instalar o pacote NuGet

Você pode criar notificações do sistema com a sintaxe do construtor do Windows Community Toolkit (WCT) OU com XML. Se você preferir o último, pule para a Etapa 2 e consulte os exemplos de código de sintaxe Sem construtor.

Na solução do Visual Studio, clique com o botão direito do mouse no projeto, clique em "Gerenciar pacotes NuGet..." e pesquise e instale o Microsoft.Toolkit.Uwp.Notifications pacote NuGet versão 7.0 ou superior.

Nossos exemplos de código de sintaxe Builder usarão este pacote. Este pacote permite que você crie notificações do sistema sem usar XML.

Etapa 2: Adicionar declarações de namespace

using namespace Microsoft::Toolkit::Uwp::Notifications;

Etapa 3: Enviar uma notificação do sistema

No Windows 10 e no Windows 11, o conteúdo da notificação do sistema é descrito usando uma linguagem adaptável que permite grande flexibilidade com a aparência da notificação. Para obter mais informações, consulte a documentação do conteúdo da notificação do sistema.

Começaremos com uma notificação simples baseada em texto. Construa o conteúdo da notificação (usando a biblioteca de notificações) e mostre a notificação! Observe que o namespace é Microsoft.Toolkit.Uwp.Notifications.

Notificação de texto simples

Se você não estiver usando a sintaxe do construtor de biblioteca de Notificações do WCT, construirá o modelo de notificação do sistema XML, preencherá-lo com texto e valores, construir a notificação e mostrá-la.

// Construct the content and show the toast!
(ref new ToastContentBuilder())
    ->AddArgument("action", "viewConversation")
    ->AddArgument("conversationId", 9813)
    ->AddText("Andrew sent you a picture")
    ->AddText("Check this out, The Enchantments in Washington!")
    ->Show();

Etapa 4: Manipulando a ativação

Quando o usuário clicar na notificação (ou em um botão na notificação com ativação em primeiro plano), o App.xaml.cpp OnActivated do aplicativo será invocado.

App.xaml.cpp

void App::OnActivated(IActivatedEventArgs^ e)
{
    // Handle notification activation
    if (e->Kind == ActivationKind::ToastNotification)
    {
        ToastNotificationActivatedEventArgs^ toastActivationArgs = (ToastNotificationActivatedEventArgs^)e;

        // Obtain the arguments from the notification
        ToastArguments^ args = ToastArguments::Parse(toastActivationArgs->Argument);

        // Obtain any user input (text boxes, menu selections) from the notification
        auto userInput = toastActivationArgs->UserInput;
 
        // TODO: Show the corresponding content
    }
}

Importante

Você deve inicializar seu quadro e ativar sua janela assim como seu código OnLaunched . OnLaunched NÃO será chamado se o usuário clicar na notificação do sistema, mesmo que seu aplicativo tenha sido fechado e esteja sendo iniciado pela primeira vez. Geralmente, recomendamos combinar OnLaunched e OnActivated em seu próprio OnLaunchedOrActivated método, pois a mesma inicialização precisa ocorrer em ambos.

Ativação em profundidade

A primeira etapa para tornar suas notificações acionáveis é adicionar alguns argumentos de inicialização à sua notificação, para que seu aplicativo possa saber o que iniciar quando o usuário clicar na notificação (nesse caso, estamos incluindo algumas informações que posteriormente nos dizem que devemos abrir uma conversa e sabemos qual conversa específica abrir).

// Construct the content and show the toast!
(ref new ToastContentBuilder())

    // Arguments returned when user taps body of notification
    ->AddArgument("action", "viewConversation")
    ->AddArgument("conversationId", 9813)

    ->AddText("Andrew sent you a picture")
    ->Show();

Adição de imagens

Você pode adicionar conteúdo avançado às notificações. Adicionaremos uma imagem embutida e uma imagem de perfil (substituição do logotipo do aplicativo).

Observação

As imagens podem ser usadas no pacote do aplicativo, no armazenamento local do aplicativo ou na Web. A partir do Fall Creators Update, as imagens da Web podem ter até 3 MB em conexões normais e 1 MB em conexões limitadas. Em dispositivos que ainda não executam o Fall Creators Update, as imagens da Web devem ter no máximo 200 KB.

Brinde com imagens
// Construct the content and show the toast!
(ref new ToastContentBuilder())
    ...

    // Inline image
    ->AddInlineImage(ref new Uri("https://picsum.photos/360/202?image=883"))

    // Profile (app logo override) image
    ->AddAppLogoOverride(ref new Uri("ms-appdata:///local/Andrew.jpg"), ToastGenericAppLogoCrop::Circle)
    
    ->Show();

Adicionando botões e entradas

Você pode adicionar botões e entradas para tornar suas notificações interativas. Os botões podem iniciar seu aplicativo em primeiro plano, um protocolo ou sua tarefa em segundo plano. Adicionaremos uma caixa de texto de resposta, um botão "Curtir" e um botão "Visualizar" que abre a imagem.

Captura de tela de uma notificação do sistema com entradas e botões
// Construct the content
(ref new ToastContentBuilder())
    ->AddArgument("conversationId", 9813)
    ...

    // Text box for replying
    ->AddInputTextBox("tbReply", "Type a response")

    // Buttons
    ->AddButton((ref new ToastButton())
        ->SetContent("Reply")
        ->AddArgument("action", "reply")
        ->SetBackgroundActivation())

    ->AddButton((ref new ToastButton())
        ->SetContent("Like")
        ->AddArgument("action", "like")
        ->SetBackgroundActivation())

    ->AddButton((ref new ToastButton())
        ->SetContent("View")
        ->AddArgument("action", "view"))
    
    ->Show();

A ativação dos botões em primeiro plano é tratada da mesma forma que o corpo da notificação do sistema principal (seu App.xaml.cpp OnActivated será chamado).

Manipulando a ativação em segundo plano

Quando você especifica a ativação em segundo plano na notificação do sistema (ou em um botão dentro da notificação do sistema), sua tarefa em segundo plano será executada em vez de ativar o aplicativo em primeiro plano.

Para obter mais informações sobre tarefas em segundo plano, consulte Dar suporte ao seu aplicativo com tarefas em segundo plano.

Se você estiver direcionando o build 14393 ou posterior, poderá usar tarefas em segundo plano no processo, o que simplifica muito as coisas. Observe que as tarefas em segundo plano em processo não serão executadas em versões mais antigas do Windows. Usaremos uma tarefa em segundo plano em processo neste exemplo de código.

const string taskName = "ToastBackgroundTask";

// If background task is already registered, do nothing
if (BackgroundTaskRegistration.AllTasks.Any(i => i.Value.Name.Equals(taskName)))
    return;

// Otherwise request access
BackgroundAccessStatus status = await BackgroundExecutionManager.RequestAccessAsync();

// Create the background task
BackgroundTaskBuilder builder = new BackgroundTaskBuilder()
{
    Name = taskName
};

// Assign the toast action trigger
builder.SetTrigger(new ToastNotificationActionTrigger());

// And register the task
BackgroundTaskRegistration registration = builder.Register();

Em seguida, no App.xaml.cs, substitua o método OnBackgroundActivated. Em seguida, você pode recuperar os argumentos predefinidos e a entrada do usuário, semelhante à ativação em primeiro plano.

App.xaml.cs

protected override async void OnBackgroundActivated(BackgroundActivatedEventArgs args)
{
    var deferral = args.TaskInstance.GetDeferral();
 
    switch (args.TaskInstance.Task.Name)
    {
        case "ToastBackgroundTask":
            var details = args.TaskInstance.TriggerDetails as ToastNotificationActionTriggerDetail;
            if (details != null)
            {
                string arguments = details.Argument;
                var userInput = details.UserInput;

                // Perform tasks
            }
            break;
    }
 
    deferral.Complete();
}

Definir um tempo de expiração

No Windows 10 e 11, todas as notificações do sistema vão para a Central de Ações depois de serem descartadas ou ignoradas pelo usuário, para que os usuários possam examinar sua notificação depois que o pop-up desaparecer.

No entanto, se a mensagem em sua notificação for relevante apenas por um período de tempo, você deverá definir um tempo de expiração na notificação do sistema para que os usuários não vejam informações obsoletas do seu aplicativo. Por exemplo, se uma promoção for válida apenas por 12 horas, defina o tempo de expiração como 12 horas. No código abaixo, definimos o tempo de expiração em 2 dias.

Observação

O tempo de expiração padrão e máximo para notificações do sistema locais é de 3 dias.

// Create toast content and show the toast!
(ref new ToastContentBuilder())
    ->AddText("Expires in 2 days...")
    ->Show(toast =>
    {
        toast->ExpirationTime = DateTime::Now->AddDays(2);
    });

Fornecer uma chave primária para sua notificação do sistema

Se você quiser remover ou substituir programaticamente a notificação enviada, precisará usar a propriedade Tag (e, opcionalmente, a propriedade Group) para fornecer uma chave primária para sua notificação. Em seguida, você pode usar essa chave primária no futuro para remover ou substituir a notificação.

Para ver mais detalhes sobre como substituir/remover notificações do sistema já entregues, consulte Guia de início rápido: gerenciando notificações do sistema na central de ações (XAML).

Tag e Group combinados atuam como uma chave primária composta. Grupo é o identificador mais genérico, onde você pode atribuir grupos como "wallPosts", "mensagens", "friendRequests", etc. E então Tag deve identificar exclusivamente a notificação em si de dentro do grupo. Usando um grupo genérico, você pode remover todas as notificações desse grupo usando a API RemoveGroup.

// Create toast content and show the toast!
(ref new ToastContentBuilder())
    ->AddText("New post on your wall!")
    ->Show(toast =>
    {
        toast.Tag = "18365";
        toast.Group = "wallPosts";
    });

Limpe suas notificações

Os aplicativos são responsáveis por remover e limpar suas próprias notificações. Quando seu aplicativo é iniciado, NÃO limpamos automaticamente suas notificações.

O Windows só removerá automaticamente uma notificação se o usuário clicar explicitamente na notificação.

Aqui está um exemplo do que um aplicativo de mensagens deve fazer...

  1. O usuário recebe várias notificações do sistema sobre novas mensagens em uma conversa
  2. O usuário toca em uma dessas notificações do sistema para abrir a conversa
  3. O aplicativo abre a conversa e, em seguida, limpa todas as notificações do sistema dessa conversa (usando RemoveGroup no grupo fornecido pelo aplicativo para essa conversa)
  4. A Central de Ações do Usuário agora reflete corretamente o estado da notificação, já que não há notificações obsoletas para essa conversa deixadas na Central de Ações.

Para saber mais sobre como limpar todas as notificações ou remover notificações específicas, consulte Guia de início rápido: gerenciando notificações do sistema na central de ações (XAML).

ToastNotificationManagerCompat::History->Clear();

Recursos