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

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

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

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

Важно!

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

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

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

Важно!

платформа .NET Framework классические приложения, которые по-прежнему используют packages.config, должны перейти на PackageReference, в противном случае на пакеты SDK для Windows не будут ссылаться правильно. В проекте щелкните правой кнопкой мыши элемент "Ссылки" и выберите пункт "Миграция packages.config в PackageReference".

Приложения WPF для .NET Core 3.0 должны быть обновлены до .NET Core 3.1, в противном случае API-интерфейсы будут отсутствовать.

Приложения .NET должны использовать один из TFM Windows, в противном случае не будут отсутствовать API Show() отправки всплывающих сообщений и управления. Задайте для TFM значение или более позднюю версию net6.0-windows10.0.17763.0 .

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

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

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

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

Простое текстовое уведомление
// Requires Microsoft.Toolkit.Uwp.Notifications NuGet package version 7.0 or greater
new ToastContentBuilder()
    .AddArgument("action", "viewConversation")
    .AddArgument("conversationId", 9813)
    .AddText("Andrew sent you a picture")
    .AddText("Check this out, The Enchantments in Washington!")
    .Show(); // Not seeing the Show() method? Make sure you have version 7.0, and if you're using .NET 6 (or later), then your TFM must be net6.0-windows10.0.17763.0 or greater

Попробуйте выполнить этот код, и вы увидите уведомление!

Шаг 3. Обработка активации

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

Действия по обработке активации различаются для UWP, а также для упакованных и неупакованных классических приложений.

Когда пользователь щелкнет уведомление (или кнопку на уведомлении с активацией переднего плана), будет вызван app.xaml.csOnActivated и будут возвращены добавленные аргументы.

App.xaml.cs

protected override void OnActivated(IActivatedEventArgs e)
{
    // Handle notification activation
    if (e is ToastNotificationActivatedEventArgs toastActivationArgs)
    {
        // Obtain the arguments from the notification
        ToastArguments args = ToastArguments.Parse(toastActivationArgs.Argument);

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

Важно!

Вам необходимо инициализировать кадр и активировать окно вашего так же, как ваш код OnLaunched. OnLaunched не вызывается, если пользователь нажимает на всплывающего уведомления, даже если ваше приложение было закрыто и запуск в первый раз. Часто рекомендуется комбинировать OnLaunched и OnActivated в методе OnLaunchedOrActivated, так как такая же инициализация должна произойти в обоих.

Шаг 4. Обработка удаления

Вам не нужно ничего делать! При удалении приложений UWP все уведомления и другие связанные ресурсы автоматически очищаются.

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

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

Примечание

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

Важно!

Http-образы поддерживаются только в упакованных приложениях, в манифесте которых есть возможность Интернета. Неупакованные приложения не поддерживают http-образы; Необходимо скачать образ в данные локального приложения и ссылаться на него локально.

Всплывающее уведомление с изображениями
// Construct the content and show the toast!
new ToastContentBuilder()
    ...

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

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

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

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

Снимок экрана: всплывающее уведомление с входными данными и кнопками
int conversationId = 384928;

// Construct the content
new ToastContentBuilder()
    .AddArgument("conversationId", conversationId)
    ...

    // Text box for replying
    .AddInputTextBox("tbReply", placeHolderContent: "Type a response")

    // Buttons
    .AddButton(new ToastButton()
        .SetContent("Reply")
        .AddArgument("action", "reply")
        .SetBackgroundActivation())

    .AddButton(new ToastButton()
        .SetContent("Like")
        .AddArgument("action", "like")
        .SetBackgroundActivation())

    .AddButton(new ToastButton()
        .SetContent("View")
        .AddArgument("action", "viewImage")
        .AddArgument("imageUrl", image.ToString()))
    
    .Show();

Активация кнопок переднего плана обрабатывается так же, как и main текст всплывающего уведомления (будет вызываться app.xaml.cs OnActivated).

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

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

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

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

Если вы используете сборку 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)
            {
                ToastArguments arguments = ToastArguments.Parse(details.Argument);
                var userInput = details.UserInput;

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

Задание времени окончания срока действия

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

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

Примечание

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

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

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

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

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

Tag и Group объединены в качестве составного первичного ключа. Группа — это более общий идентификатор, которой можно назначить группам, например "wallPosts", "сообщения", "friendRequests", и т. д. Выберите тег уникальной идентификации уведомления из группы. С помощью универсальной группы вы можете удалить все уведомления из группы с помощью RemoveGroup API .

// Create toast content and show the toast!
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();

Ресурсы