从 C++ UWP 应用发送本地 app 通知

通知 app 是一条消息,你可以在 app 用户当前不在用户 app内部时构造和传送。

通知的 app 屏幕截图

本快速入门指导你完成使用丰富内容和交互式作创建、交付和显示 Windows 10 或 Windows 11 app 通知的步骤。 本快速入门指南使用本地通知,这是最简单实现的通知类型。 所有类型的应用(WPF、UWP、WinForms、控制台)都可以发送通知!

Note

术语“toast notification”正在替换为“app notification”。 这些术语都指的是 Windows 的相同功能,但随着时间的推移,我们将逐步取消使用文档中的“toast 通知”。

Important

如果要编写非 UWP appC++,请参阅 C++ WRL 文档。 如果要编写 C# app,请参阅 C# 文档

步骤 1:安装 NuGet 包

可以使用 Windows Community Toolkit(WCT)的生成器语法或 XML 创建 app 通知。 如果更喜欢后者,请跳到 步骤 2,并参考 无需生成器语法 代码示例。

在 Visual Studio 解决方案中,右键单击项目,单击“ 管理 NuGet 包...” ,然后搜索并安装 Microsoft.Toolkit.Uwp.NotificationsNuGet 包 版本 7.0 或更高版本。

生成器语法代码示例将使用此包。 此包允许在不使用 XML 的情况下创建 app 通知。

步骤 2:添加命名空间声明

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

步骤 3:发送 app 通知

在 Windows 10 和 Windows 11 中,通知 app 内容是使用自适应语言描述的,该语言允许你对通知的外观具有极大的灵活性。 有关详细信息,请参阅 App 通知内容 文档。

我们将从简单的基于文本的通知开始。 构造通知内容(使用通知库),并显示通知! 请注意,命名空间 Microsoft.Toolkit.Uwp.Notifications

简单文本通知

如果不使用 WCT 通知库生成器语法,则改为构造 XML app 通知模板,使用文本和值填充它,构造通知,并显示它。

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

步骤 4:处理激活

当用户单击通知(或具有前台激活的通知上的按钮)时, app将调用's App.xaml.cppOnActivated

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
    }
}

Important

您必须初始化您的框架,并像您的 OnLaunched 代码那样激活窗口。 如果用户单击通知,即使app已关闭且首次启动,也不会调用 OnLaunched。app 我们通常建议将 OnLaunchedOnActivated 合并到您自己的 OnLaunchedOrActivated 方法中,因为两者都需要进行相同的初始化。

深入激活

使通知可作的第一步是向通知添加一些启动参数,以便用户可以 app 知道在用户单击通知时要启动的内容(在本例中,我们包括一些稍后告知我们应该打开对话的信息,以及我们知道要打开的特定对话)。

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

Add images

你可以向通知添加丰富的内容。 我们将添加内联图像和配置文件(app 徽标替代)图像。

Note

可以从“包”、“app本地存储”或“Web”使用app映像。 从 Fall Creators Update 开始,普通连接上的 Web 图像最多可以为 3 MB,按流量计费的连接可以达到 1 MB。 在尚未运行 Fall Creators Update 的设备上,Web 图像必须不超过 200 KB。

Toast 包含图像
// 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();

添加按钮和输入

可以添加按钮和输入,使通知具有交互性。 按钮可以启动前台 app、协议或后台任务。 我们将添加回复文本框、“赞”按钮和打开图像的“视图”按钮。

包含输入和按钮的 toast 通知的屏幕截图
// 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();

前台按钮的激活处理方式与主通知正文相同( App将调用 onActivated .xaml.cpp)。

处理后台激活

在通知中 app 指定后台激活(或在通知内的按钮上)时,将执行后台任务,而不是激活前台 app。

有关后台任务的详细信息,请参阅 “支持后台 app 任务”。

如果您针对构建版本 14393 或更高版本,则可以使用在进程内运行的后台任务,从而大大简化操作。 请注意,进程内后台任务将无法在较旧版本的 Windows 上运行。 我们将在此代码示例中使用进程内后台任务。

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

App然后在.xaml.cs中重写 OnBackgroundActivated 方法。 然后,可以检索预定义的参数和用户输入,类似于前台激活。

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

设置过期时间

在 Windows 10 和 11 中,所有 app 通知在用户关闭或忽略后都会进入作中心,以便用户可以在弹出窗口消失后查看通知。

但是,如果通知中的消息仅在一段时间内相关,则应在 app 通知上设置过期时间,以便用户看不到来自你的 app过时信息。 例如,如果促销仅有效 12 小时,请将到期时间设置为 12 小时。 在下面的代码中,我们将过期时间设置为 2 天。

Note

本地 app 通知的默认和最长过期时间为 3 天。

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

为通知提供主密钥app

如果要以编程方式删除或替换你发送的通知,则需要使用 Tag 属性(以及可选的 Group 属性)为通知提供主键。 然后,可以在将来使用此主键删除或替换通知。

若要查看有关替换/删除已传递 app 通知的更多详细信息,请参阅 快速入门:在作中心(XAML)中管理 toast 通知

标签和组一起用作复合主键。 组是更通用的标识符,可在其中分配“wallPosts”、“messages”、“friendRequests”等组。然后,Tag 应从组中唯一标识通知本身。 然后,通过使用泛型组,可以使用 RemoveGroup API 从该组中删除所有通知。

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

清除通知

应用负责删除和清除其自己的通知。 启动后 app ,我们不会自动清除通知。

仅当用户显式单击通知时,Windows 才会自动删除通知。

下面是消息 app 传送应执行的作的示例...

  1. 用户收到有关对话中新消息的多个 app 通知
  2. 用户点击其中一条通知以打开对话
  3. 打开app对话,然后清除该对话的所有通知(通过使用该会话的 -提供的组上的 appRemoveGroup
  4. 用户的操作中心现在正确反映通知状态,因为操作中心中没有留下的该会话的过时通知。

若要了解如何清除所有通知或删除特定通知,请参阅 快速入门:在作中心(XAML)中管理 toast 通知

ToastNotificationManagerCompat::History->Clear();

Resources