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 以降を検索してインストールします。

重要

packages.config を引き続き使用する .NET Framework デスクトップ アプリは PackageReference に移行する必要があります。そうしないと、Windows SDK は正しく参照されません。 プロジェクトで [参照] を右クリックし、[packages.config を PackageReference に移行する] をクリックします。

.NET Core 3.0 WPF アプリは、.NET Core 3.1 に更新する必要があります。そうしないと、API は存在しません。

.NET アプリ Windows TFM のいずれかを使用する必要があります、それ以外の場合は、 Show() などのトースト送信および管理 API が見つかりません。 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.cs OnActivated が呼び出され、追加した引数が返されます。

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 は呼び出されません。 多くの場合、 OnLaunchedOnActivated を独自の OnLaunchedOrActivated メソッドに組み合わせることをお勧めします。これは、両方で同じ初期化を行う必要があるためです。

手順 4: アンインストールの処理

何も行う必要はありません。 UWP アプリがアンインストールされると、すべての通知とその他の関連リソースが自動的にクリーンアップされます。

画像の追加

通知には、リッチ コンテンツを追加できます。 ここでは、インライン イメージとプロファイル (アプリ ロゴのオーバーライド) 画像を追加します。

Note

イメージは、アプリのパッケージ、アプリのローカル ストレージ、または Web から使用できます。 Fall Creators Update の時点で、Web 画像の上限は通常の接続で 3 MB、従量制課金接続で 1 MB です。 まだ Fall Creators Update を実行していないデバイスでは、Web イメージは 200 KB を上限とします。

重要

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

フォアグラウンド ボタンのアクティブ化は、トーストの本体と同じ方法で処理されます (App.xaml.cs OnActivated が呼び出されます)。

上記のように、ボタンで AddArgument API を使用していれば、最上位のトーストに追加された引数 (会話 ID など) も返されます (ボタンで引数をカスタム割り当てした場合、最上位の引数は含まれません)。

バックグラウンド アクティブ化の処理

トースト (またはトースト内のボタン) でバックグラウンドアクティブ化を指定すると、フォアグラウンド アプリをアクティブ化するのではなく、バックグラウンド タスクが実行されます。

バックグラウンド タスクの詳細については、「 バックグラウンド タスクを使用してアプリをサポートする」を参照してください

ビルド 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 日に設定しています。

Note

ローカル トースト通知の既定の有効期限と最大有効期限は 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 プロパティ) を使用して、通知の主キーを指定する必要があります。 その後、この主キーを今後使用して、通知を削除または置き換えることができます。

既に配信されているトースト通知の置換または削除の詳細については、「 Quickstart: アクション センター (XAML) でのトースト通知の管理」を参照してください。

タグとグループの組み合わせは、複合主キーとして機能します。 Group はより汎用的な識別子であり、"wallPosts"、"messages"、"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. ユーザーのアクション センターで通知の状態が正しく反映されるようになりました。アクション センターには、その会話の古い通知が残っていないためです。

すべての通知のクリアまたは特定の通知の削除については、「 Quickstart: アクション センター (XAML) でのトースト通知の管理」を参照してください。

ToastNotificationManagerCompat.History.Clear();

リソース