C# アプリからローカル トースト通知を送信する

トースト通知とは、ユーザーが現在アプリ内にいないときに、アプリで作成してユーザーに配信できるメッセージです。

トースト通知のスクリーンショット

このクイックスタートでは、リッチ コンテンツと対話型アクションを使用して、Windows 10またはWindows 11トースト通知を作成、配信、表示する手順について説明します。 このクイックスタートでは、実装する最もシンプルな通知であるローカル通知を使用します。 すべての種類のアプリ (WPF、UWP、WinForms、コンソール) で通知を送信できます。

重要

C++ アプリを作成している場合は、C++ UWP または C++ WRL のドキュメントを参照してください。

手順 1: NuGet パッケージのインストール

Visual Studio ソリューション内で、プロジェクトを右クリックし、[NuGet パッケージの管理] をクリックします。Microsoft.Toolkit.Uwp.NotificationsNuGet パッケージ バージョン 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 と管理 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.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 は、ユーザーがトーストをクリックしても呼び出されません。アプリが閉じられてから初めて起動している場合も同様です。 通常は、OnLaunchedOnActivated を組み合わせて独自の OnLaunchedOrActivated メソッドにまとめることをお勧めします。これは、両方で同じ初期化を実行する必要があるためです。

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

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

イメージの追加

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

注意

画像は、アプリのパッケージ、アプリのローカル ストレージ、または 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 日間に設定されています。

注意

ローカル トースト通知の既定の最長有効期限は 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 を組み合わせると、復号主キーとして機能します。 Group はより汎用的な ID で、"wallPosts"、"messages"、"friendRequests" などのグループを割り当てることができます。Tag はグループ内から通知自体を一意に識別する必要があります。 汎用グループを使うことで、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();

リソース