Поделиться через


Отправка локального всплывающего уведомления из приложений UWP на C++

Всплывающее уведомление — это сообщение о том, что ваше приложение может создавать и доставлять пользователю, пока они не находятся в вашем приложении.

Снимок экрана: всплывающее уведомление

В этом кратком руководстве описаны действия по созданию, доставке и отображению всплывающего уведомления Windows 10 или Windows 11 с использованием полнофункционированного содержимого и интерактивных действий. В этом кратком руководстве используются локальные уведомления, которые являются самым простым уведомлением для реализации. Все типы приложений (WPF, UWP, WinForms, консоль) могут отправлять уведомления!

Внимание

Если вы пишете приложение C++, отличное от UWP, ознакомьтесь с документацией по WRL C++. Если вы пишете приложение C#, ознакомьтесь с документацией по C#.

Шаг 1. Установка пакета NuGet

Вы можете создавать всплывающие уведомления с помощью синтаксиса конструктора Windows Community Toolkit (WCT) или XML. Если вы предпочитаете последний, перейдите к шагу 2 и ознакомьтесь с примерами синтаксиса без построителя.

В решении Visual Studio щелкните проект правой кнопкой мыши, щелкните "Управление пакетами NuGet..." и найдите и установите Microsoft.Toolkit.Uwp.Notifications пакет NuGet версии 7.0 или выше.

Примеры кода синтаксиса построителя будут использовать этот пакет. Этот пакет позволяет создавать всплывающие уведомления без использования XML.

Шаг 2. Добавление объявлений пространства имен

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

Шаг 3. Отправка всплывающего уведомления

В Windows 10 и Windows 11 содержимое всплывающего уведомления описывается с помощью адаптивного языка, который обеспечивает большую гибкость в том, как выглядит уведомление. Дополнительные сведения см. в документации по всплывающему содержимому.

Начнем с простого текстового уведомления. Создайте содержимое уведомления (с помощью библиотеки уведомлений) и покажите уведомление! Обратите внимание, что пространство имен имеет значение Microsoft.Toolkit.Uwp.Notifications.

Простое текстовое уведомление

Если вы не используете синтаксис построителя библиотеки уведомлений WCT, вместо этого создайте шаблон xml-всплывающего уведомления, заполните его текстом и значениями, создайте уведомление и отобразите его.

// 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.xaml.cpp onActivated вашего приложения.

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

Внимание

Необходимо инициализировать кадр и активировать окно так же, как код OnLaunched . OnLaunched не вызывается, если пользователь щелкает всплывающее уведомление, даже если приложение было закрыто и запускается в первый раз. Мы часто рекомендуем объединить OnLaunched и OnActivated в собственный OnLaunchedOrActivated метод, так как в обоих ситуациях необходимо выполнить одну и ту же инициализацию.

Подробные сведения о активации

Первым шагом в принятии уведомлений является добавление некоторых активов запуска в уведомление, чтобы ваше приложение знали, что нужно запустить, когда пользователь щелкает уведомление (в этом случае мы включаем некоторые сведения, которые позже сообщают нам, что мы должны открыть беседу, и мы знаем, какой конкретный разговор нужно открыть).

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

Добавление изображений

Вы можете добавить в уведомления форматированный контент. Мы добавим встроенный образ и профиль (переопределение логотипа приложения).

Примечание.

Изображения можно использовать из пакета приложения, локального хранилища приложения или из Интернета. По состоянию на Fall Creators Update веб-образы могут составлять до 3 МБ в обычных подключениях и 1 МБ на лимитных подключениях. На устройствах, не работающих в Fall Creators Update, веб-образы не должны превышать 200 КБ.

Всплывающее уведомление с изображениями
// 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();

Добавление кнопок и входных данных

Вы можете добавить кнопки и входные данные, чтобы сделать уведомления интерактивными. Кнопки могут запускать приложение переднего плана, протокол или фоновую задачу. Мы добавим текстовое поле ответа, кнопку "Нравится" и кнопку "Вид", которая открывает изображение.

Снимок экрана: всплывающее уведомление с входными и кнопками
// 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.xaml.cpp OnActivated).

Обработка фоновой активации

При указании фоновой активации на всплывающем (или на кнопке внутри всплывающего уведомления) фоновая задача будет выполнена вместо активации приложения переднего плана.

Дополнительные сведения о фоновых задачах см. в статье "Поддержка приложения с фоновыми задачами".

Если вы используете сборку 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 все всплывающие уведомления отправляются в Центре уведомлений после того, как они уволены или игнорируются пользователем, чтобы пользователи могли просматривать уведомления после удаления всплывающего окна.

Однако если сообщение в уведомлении относится только в течение определенного периода времени, необходимо задать срок действия всплывающего уведомления, чтобы пользователи не видели устаревшие сведения из приложения. Например, если акция действительна только в течение 12 часов, задайте время окончания срока действия 12 часов. В приведенном ниже коде мы задали срок действия 2 дня.

Примечание.

По умолчанию и максимальное время окончания срока действия для локальных всплывающих уведомлений составляет 3 дня.

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

Предоставление первичного ключа для всплывающего уведомления

Если вы хотите программно удалить или заменить отправленное уведомление, необходимо использовать свойство Tag (и необязательно свойство Group), чтобы предоставить первичный ключ для уведомления. Затем вы можете использовать этот первичный ключ в будущем для удаления или замены уведомления.

Дополнительные сведения о замене и удалении уже доставленных уведомлений см. в кратком руководстве по управлению всплывающими уведомлениями в центре уведомлений (XAML).

Тег и группа объединяются в качестве составного первичного ключа. Группа — это более универсальный идентификатор, где можно назначать такие группы, как wallPosts, "messages", "friendRequests" и т. д. А затем тег должен однозначно идентифицировать уведомление из группы. С помощью универсальной группы можно удалить все уведомления из этой группы с помощью 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";
    });

Очистка уведомлений

Приложения отвечают за удаление и очистку собственных уведомлений. При запуске приложения мы не очищаем уведомления автоматически.

Windows автоматически удаляет уведомление, если пользователь явно щелкает уведомление.

Ниже приведен пример того, что должно сделать приложение для обмена сообщениями...

  1. Пользователь получает несколько уведомлений о новых сообщениях в беседе
  2. Пользователь нажимает один из этих точек, чтобы открыть беседу
  3. Приложение открывает беседу, а затем очищает все всплывающее меню для этой беседы (с помощью RemoveGroup в группе, предоставленной приложением для этой беседы)
  4. Центр уведомлений пользователя теперь правильно отражает состояние уведомлений, так как в Центре уведомлений нет устаревших уведомлений.

Дополнительные сведения о очистке всех уведомлений или удалении определенных уведомлений см. в кратком руководстве по управлению всплывающими уведомлениями в центре уведомлений (XAML).

ToastNotificationManagerCompat::History->Clear();

Ресурсы