Archived: Quickstart: Sending a local toast notification and handling activations from it (Windows 10) (10586)

A toast notification is a message that an app can construct and deliver to the user while he/she is not currently inside your app. This Quickstart walks you through the steps to create, deliver, and display a Windows 10 toast notification with the new adaptive templates and interactive actions. These actions are demonstrated through a local notification, which is the simplest notification to implement. We will go through the following things:

Sending a toast

Specifying the new flexible template for your notification;

Constructing the visual part (text and image) of the notification;

Adding actions to the notification to make it interactive, and providing activation type, and contextual information used when your app is activated by these actions;

Setting an expiration time on the toast so it no longer shows up in user’s action center once gone stale;

Providing identity to your toast so it can be replaced/removed at a later time;

Sending your toast as a local notification.

Handling activation from a toast

Handling activation when the body of the toast is tapped;

Handling foreground activation for interactive toast notification;

Handling background activation for interactive toast notification;

Keep toast and tile/badge in sync, and more

Getting notified when your app's toast notifications are removed by user, expired by system, or added from your app server;

Using the History property to get the list of toast notifications from your app that is currently displayed in action center;

Note: Different from Windows 8/8.1, you no longer need to declare in your app's manifest that your app is capable of showing toast notifications. All apps are capable of sending and displaying toast notifications.

Note: The example below will be using C# as the programming language.

Sending a toast

1. Install NuGet packages

We recommend installing the two following NuGet packages to your project. Our code sample will use these packages. We'll also provide the "Vanilla" code snippets that don't use any NuGet packages.

2. Add namespace declarations

using Windows.UI.Notifications;
using NotificationsExtensions.Toasts; // NotificationsExtensions.Win10
using Microsoft.QueryStringDotNET; // QueryString.NET

using Windows.UI.Notifications;
using Windows.Data.Xml.Dom;

3. Construct the notification payload

In Windows 8/8.1, you used to be required to choose a template from the system-provided template catalog that fits the needs of your content – one of the templates in ToastTemplateType enumeration. In Windows 10, that’s not the case anymore. The number of text lines, optional profile picture that replaces the logo, and optional inline picture, can all be managed by using the new flexible and adaptive toast templates – ToastGeneric. See the adaptive and interactive toast documentation for more information.

Constructing the visual part of the payload

Let’s start by constructing the visual part of the payload, which includes the text and image content you want the user to see.

Thanks to NotificationsExtensions, generating the XML payload is much easier. If you don't install NotificationsExtensions.Win10 from NuGet, you have to construct the XML manually, which leaves room for errors.

Note: Images can be used from the app's package, the app's local storage, or from the web. Images must be less than 200 KB in size and smaller than 1024 x 1024 pixels.

Constructing actions part of the payload

Now let’s add interactions to the payload.

In the below example, we included an input element that allows the user to input text, which can then be retrieved by the app using its id, once it is activated in the foreground or background – depending on how the interactions are defined for each of the actions.

We then created 2 action elements, each specifying its own activation type, content, and arguments.

Content attribute is used to specify the text on the button, when they are rendered to represent the actions;

activationType is used to specify how the app wants to be activated when this action is performed by the user, you can choose to launch your app in the foreground, launch a background task, or protocol launch another app. Whether your app chooses the activation type to be foreground or background, there is always a way for you to retrieve the user input, as well as the args you pre-defined in the arguments attribute, so you have the full context of what the user did to the notification.

Combining the above to construct the full payload

The construction of the XML payload is now complete, and we can use it to instantiate your ToastNotification object.

Note: you can also provide an activation type inside the root element, to specify what type of activation needs to happen when the user taps on the body of the toast notification. Normally, tapping the body of the toast should launch your app in the foreground to create a consistent user experience, but you can use other activation types to fit your specific scenario where it makes most sense to the user.

Just like before, you can and should always add a launch parameter to the root element, so when user taps the body of the toast, your app can still be launched with a view that relates to the content of the notification.

4. Providing expiration time to toast notification

In Windows 10, all toast notifications go in action center (which was previously only available on phone, but now available on all Windows devices) after they are dismissed or ignored by the user when it pops up on the screen for the first time, so the users no longer misses notifications from your app.

However, if the message in your notification is only available, or relevant for a period of time, you should set an expiration time on the toast notification so the users do not see stale information from your app. In the code below I set the expiration time to be 2 days.

toast.ExpirationTime = DateTime.Now.AddDays(2);

5. Providing identity and group id to toast notification

Just like in Windows Phone 8.1, you can provide identity to a toast notification, in order to target it at a later time, for the purposes of replacing or removing it, as shown below.

Handling activation from a toast notification

Since Windows 8/8.1, applications has always been expected to handle activations in response to a user clicking on a toast notification from this app – the app should respond by performing navigation and displaying UI specific to the toast. This is accomplished through an activation string that you include in the toast payload, which is then passed to your app as an argument in the activation event.

In Windows 10, the data flow is very similar, but with the addition of adaptive templates and custom actions, there are 3 different kind of activations that the app might be expected to handle.

Legacy: Foreground activation from a toast notification using legacy template.

Note: If you are developing a new Windows 10 universal app, I highly recommend using the new adaptive template. All legacy toast templates can be easily achieved by using the new adaptive template. By using the new adaptive template, you can have a consistent way and place to handle toast activation, which I will explain in details below.

In Windows 10, we updated the toast activation behavior so that when a toast (or an action inside toast) triggers a foreground activation, OnActivated is invoked instead of OnLaunched, with a new activation kind – ToastNotification. Thus, the developer is able to easily distinguish a toast activation and perform tasks accordingly.

In the example you see below, you can retrieve the developer pre-defined arguments and the user generated input from the activation event.

protected override void OnActivated(IActivatedEventArgs e)
{
// Get the root frame
Frame rootFrame = Window.Current.Content as Frame;
// TODO: Initialize root frame just like in OnLaunched
// Handle toast activation
if (e is ToastNotificationActivatedEventArgs)
{
var toastActivationArgs = e as ToastNotificationActivatedEventArgs;
// Parse the query string
QueryString args = QueryString.Parse(toastActivationArgs.Argument);
// See what action is being requested
switch (args["action"])
{
// Open the image
case "viewImage":
// The URL retrieved from the toast args
string imageUrl = args["imageUrl"];
// If we're already viewing that image, do nothing
if (rootFrame.Content is ImagePage && (rootFrame.Content as ImagePage).ImageUrl.Equals(imageUrl))
break;
// Otherwise navigate to view it
rootFrame.Navigate(typeof(ImagePage), imageUrl);
break;
// Open the conversation
case "viewConversation":
// The conversation ID retrieved from the toast args
int conversationId = int.Parse(args["conversationId"]);
// If we're already viewing that conversation, do nothing
if (rootFrame.Content is ConversationPage && (rootFrame.Content as ConversationPage).ConversationId == conversationId)
break;
// Otherwise navigate to view it
rootFrame.Navigate(typeof(ConversationPage), conversationId);
break;
}
// If we're loading the app for the first time, place the main page on
// the back stack so that user can go back after they've been
// navigated to the specific page
if (rootFrame.BackStack.Count == 0)
rootFrame.BackStack.Add(new PageStackEntry(typeof(MainPage), null, null));
}
// TODO: Handle other types of activation
// Ensure the current window is active
Window.Current.Activate();
}

protected override void OnActivated(IActivatedEventArgs args)
{
// TODO: Initialize root frame just like in OnLaunched
// Handle toast activation
if (args.Kind == ActivationKind.ToastNotification)
{
var toastArgs = args as ToastNotificationActivatedEventArgs;
// Get arguments corresponding to this activation;
// When tapping the body of the toast caused this activation, the app receives the value of “launch” property of ;
// When the activation is caused by using tapping on an action inside the toast, the app receives the value of “arguments” property of ;
var arguments = toastArgs.Arguments;
// User input from <input> can be retrieved using the UserInput property. The UserInput is a ValueSet and the key is the pre-defined id attribute in the <input> element in the payload.
var input = toastArgs.UserInput["1"];
// Navigate accordingly
}
// TODO: Handle other types of activation
}

When you specify the activation type of the toast notification (or an action inside the toast) to be background, a trigger will be fired to invoke the execution of your background task instead of activating your foreground app.

When the task runs, your app is able to retrieve pre-defined arguments and user generated inputs from ToastNotificationActionTriggerDetail, very similar to how they are retrieved from the foreground activation EventArgs.

When the user taps on a toast constructed with one of the legacy templates, the associated app is launched or brought to the foreground, firing its OnLaunched method.

This example shows the syntax for the override of the OnLaunched event, in which you can retrieve and act on the Arguments provided by the LaunchActivatedEventArgs object (which comes from the toast's launch attribute).

Keep toast and tile/badge in sync using ToastNotificationHistoryChangedTrigger

For a lot of apps, especially social networking or messaging apps, the toast notification is often corresponding to the badge/tile content – when a new toast notification is available and delivered, the app in this case would update the badge, to show the number of unseen toast notifications. When a toast notification is removed by the user, or expired by the system, the app is also expected to update the badge/tile to show the total number of toast notification left. This can now be done through a new trigger we introduce in Windows 10 – ToastNotificationHistoryChangedTrigger. As hinted by the name, this trigger is fired whenever the collection of toast notification history from your app changes on the device. Subscribing this trigger, will allow your app to get notified when:

A toast notification is removed by the user from action center;

A toast notification is expired and removed by the system from action center;

A toast notification is delivered form your app, via push;

Note: the only thing your app wouldn’t be notified for, is a local toast being popped/added, since it is not necessary to notify your app client about something it just did.

Here is how to register the background task in manifest by inserting below code inside <Extensions> which is a child element of <Application>:

When the task runs, the app is able to retrieve information on whether toast was added or removed from the collection of existing toasts using TriggerDetails and do different things accordingly. In the sample below, you can see that we access ToastNotificationHistory to see how many toast notifications are there from my app in action center, then update the badge count with that number, when toast notifications are added or removed.