Mulai cepat: Pemberitahuan aplikasi di SDK Aplikasi Windows

A screen capture showing an app notification above the task bar. The notification is a reminder for an event. The app name, event name, event time, and event location are shown. A selection input displays the currently selected value,

Dalam mulai cepat ini, Anda akan membuat aplikasi Windows desktop yang mengirim dan menerima pemberitahuan aplikasi lokal, juga dikenal sebagai pemberitahuan toast, menggunakan SDK Aplikasi Windows.

Penting

Pemberitahuan untuk aplikasi yang ditingkatkan (admin) saat ini tidak didukung.

Prasyarat

Aplikasi sampel

Mulai cepat ini mencakup kode dari aplikasi sampel pemberitahuan yang ditemukan di GitHub.

Referensi API

Untuk dokumentasi referensi API untuk pemberitahuan aplikasi, lihat Namespace Microsoft.Windows.AppNotifications.

Langkah 1: Menambahkan deklarasi namespace layanan

Tambahkan namespace layanan untuk pemberitahuan Microsoft.Windows.AppNotificationsaplikasi SDK Aplikasi Windows .

using Microsoft.Windows.AppNotifications;

Langkah 2: Memperbarui manifes aplikasi Anda

Jika aplikasi Anda tidak dikemas (artinya, aplikasi tidak memiliki identitas paket saat runtime), maka lewati ke Langkah 3: Daftar untuk menangani pemberitahuan aplikasi.

Jika aplikasi Anda dipaketkan (termasuk dipaketkan dengan lokasi eksternal):

  1. Buka Package.appxmanifest Anda.
  2. Tambahkan xmlns:com="http://schemas.microsoft.com/appx/manifest/com/windows10" dan xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10" namespace ke <Package>
  3. Tambahkan <desktop:Extension> untuk windows.toastNotificationActivation mendeklarasikan CLSID aktivator COM Anda. Anda dapat memperoleh CLSID dengan menavigasi ke Buat GUID di bawah Alat di Visual Studio.
  4. Tambahkan <com:Extension> untuk aktivator COM menggunakan CLSID yang sama.
    1. Tentukan file .exe Anda di Executable atribut . File .exe harus merupakan panggilan Register() proses yang sama saat mendaftarkan aplikasi Anda untuk pemberitahuan, yang dijelaskan lebih lanjut di Langkah 3. Dalam contoh di bawah ini, kami menggunakan Executable="SampleApp\SampleApp.exe".
    2. Tentukan Arguments="----AppNotificationActivated:" untuk memastikan bahwa SDK Aplikasi Windows dapat memproses payload pemberitahuan Anda sebagai jenis AppNotification.
    3. DisplayNameTentukan .

Penting

Peringatan: Jika Anda menentukan jenis ekstensibilitas aplikasi Windows.Protocol di manifes appx Anda dengan <uap:Protocol>, maka mengklik pemberitahuan akan meluncurkan proses baru dari aplikasi yang sama, bahkan jika aplikasi Anda sudah berjalan.

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

Langkah 3: Daftar untuk menangani pemberitahuan aplikasi

Daftarkan aplikasi Anda untuk menangani pemberitahuan, lalu batalkan pendaftaran saat aplikasi Anda berakhir.

Dalam file AndaApp.xaml, daftar untuk AppNotificationManager::D efault(). NotificationInvoked, lalu panggil AppNotificationManager::D efault(). Daftar. Urutan panggilan ini penting.

Penting

Anda harus memanggil AppNotificationManager::D efault(). Daftar sebelum memanggil AppInstance.GetCurrent.GetActivatedEventArgs.

Saat aplikasi Anda dihentikan, panggil AppNotificationManager::D efault(). Batalkan pendaftaran() untuk membebaskan server COM dan memungkinkan pemanggilan berikutnya untuk meluncurkan proses baru.

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

    }
}       

Langkah 4: Menampilkan pemberitahuan aplikasi

App notification with button

Anda HARUS menyelesaikan Langkah 3: Mendaftar untuk menangani pemberitahuan aplikasi sebelum melanjutkan.

Sekarang Anda akan menampilkan pemberitahuan aplikasi sederhana dengan appLogoOverride gambar dan tombol.

Buat pemberitahuan aplikasi Anda menggunakan kelas AppNotificationBuilder lalu panggil Show. Untuk informasi selengkapnya tentang cara membuat pemberitahuan aplikasi Anda menggunakan XML, lihat contoh di Konten toast dan skema XML Pemberitahuan.

Catatan

Jika aplikasi Anda dipaketkan (termasuk dipaketkan dengan lokasi eksternal), ikon aplikasi Anda di sudut kiri atas pemberitahuan bersumber dari package.manifest. Jika aplikasi Anda tidak dikemas, maka ikon bersumber dengan terlebih dahulu melihat pintasan, lalu melihat file sumber daya dalam proses aplikasi. Jika semua upaya gagal, ikon aplikasi default Windows akan digunakan. Jenis file ikon yang didukung adalah .jpg, , .bmp.png, dan .ico.

// 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. 

Langkah 5: Memproses pengguna yang memilih pemberitahuan

Pengguna dapat memilih isi atau tombol pemberitahuan Anda. Aplikasi Anda perlu memproses pemanggilan sebagai respons terhadap pengguna yang berinteraksi dengan pemberitahuan Anda.

Ada 2 cara umum untuk memproses ini:

  1. Anda memilih untuk meluncurkan aplikasi dalam konteks UI tertentu ATAU
  2. Anda memilih untuk membuat aplikasi Anda mengevaluasi perilaku khusus tindakan (seperti tombol tekan di isi pemberitahuan) tanpa merender UI apa pun. Juga dikenal sebagai tindakan latar belakang.

Contoh kode di bawah ini, yang bukan dari aplikasi sampel, menggambarkan kedua cara memproses tindakan yang dihasilkan pengguna. launch Tambahkan nilai (sesuai dengan pengguna yang mengklik isi pemberitahuan), input elemen (kotak teks balasan cepat), dan tombol dengan nilai (sesuai dengan arguments pengguna yang mengklik tombol) ke payload XML pemberitahuan Anda. Dalam , kasus Anda ProcessLaunchActivationArgspada setiap argumen.

Penting

Pengaturan activationType="background" dalam payload XML pemberitahuan diabaikan untuk aplikasi desktop. Anda harus memproses argumen aktivasi dan memutuskan apakah akan menampilkan jendela atau tidak, seperti yang dinyatakan dalam langkah ini.

App notification with reply

// 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&amp;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&amp;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);
    }
}

Ikuti panduan di bawah ini:

  1. Jika pemberitahuan dipilih oleh pengguna dan aplikasi Anda tidak berjalan, diharapkan aplikasi Anda diluncurkan dan pengguna dapat melihat jendela latar depan dalam konteks pemberitahuan.
  2. Jika pemberitahuan dipilih oleh pengguna dan aplikasi Anda diminimalkan, diharapkan aplikasi Anda dibawa ke latar depan dan jendela baru dirender dalam konteks pemberitahuan.
  3. Jika tindakan latar belakang pemberitahuan dipanggil oleh pengguna (misalnya, pengguna merespons pemberitahuan dengan mengetik di kotak teks pemberitahuan dan menekan balasan), aplikasi Anda memproses payload tanpa merender jendela latar depan.

Lihat contoh kode aplikasi yang ditemukan di GitHub untuk contoh yang lebih rinci.

Langkah 6: Menghapus pemberitahuan

Hapus pemberitahuan saat pemberitahuan tidak lagi relevan dengan pengguna.

Dalam contoh ini, pengguna telah melihat semua pesan dari obrolan grup di aplikasi Anda, sehingga Anda menghapus semua pemberitahuan dari obrolan grup. Kemudian, pengguna mematikan suara teman, sehingga Anda menghapus semua pemberitahuan dari teman. Anda terlebih dahulu menambahkan properti Grup dan Tag ke pemberitahuan sebelum ditampilkan untuk mengidentifikasinya sekarang.


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

Fitur tambahan

Mengirim pemberitahuan aplikasi bersumber cloud

Untuk mengirim pemberitahuan aplikasi dari cloud, ikuti Mengirim pemberitahuan aplikasi bersumber cloud di Mulai Cepat: Pemberitahuan push di SDK Aplikasi Windows.

Mengatur waktu kedaluwarsa

Atur waktu kedaluwarsa pada pemberitahuan aplikasi Anda menggunakan Expiration properti jika pesan di pemberitahuan Anda hanya relevan untuk jangka waktu tertentu. Misalnya, jika Anda mengirim pengingat acara kalender, atur waktu kedaluwarsa ke akhir acara kalender.

Catatan

Waktu kedaluwarsa default dan maksimum adalah 3 hari.

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

Pastikan pemberitahuan kedaluwarsa saat boot ulang

Atur ExpiresOnReboot properti ke True jika Anda ingin pemberitahuan dihapus saat boot ulang.

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

Mengirim dan memperbarui pemberitahuan bilah kemajuan

Anda dapat menampilkan pembaruan terkait bilah kemajuan dalam pemberitahuan:

Notification with progress bar

AppNotificationProgressData Gunakan konstruksi untuk memperbarui pemberitahuan bilah kemajuan.

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

Sumber