Windows Phone Mango–What’s New? (“Push Notifications & Tiles” – Part 8 of 8)

May 24, 2011

Mango introduces some changes in Push Notifications mechanism which enables the developers to create more attractive scenarios.


First feature I’ll show in this post is a secondary tiles for application. Before Mango, every application could have only one pinned tile on the main screen which could be updated using Push Notification mechanism (I blogged about it quite some time ago here and here).


Mango release enables to have additional tiles which can be pinned and removed from application code! How about having something like this:


imageimage


All the tiles (beside IE9) on main screen are related to sample I’m going to show here… And they are flipping randomly! Clicking on the tile will take us directly to the person’s mood page:


image


The UI of the app will be very simple – only a bunch of checkboxes to create/remove secondary tiles:


image


Checking the checkbox will add corresponding secondary tile to the main screen; unchecking the checkbox will remove it.


Let’s see how to achieve it. First, my application uses PushNotification channel created (or found) when application loaded:

//Check push channel status and subscribe to the events
pushChannel = HttpNotificationChannel.Find(“MoodPushChannel”);
if (null == pushChannel)
{
pushChannel = new HttpNotificationChannel(“MoodPushChannel”);

SubscribeToChannelEvents();

pushChannel.Open();

pushChannel.BindToShellTile();
}
else
{
SubscribeToChannelEvents();

uri = pushChannel.ChannelUri;

if (!pushChannel.IsShellToastBound)
pushChannel.BindToShellToast();

// Uri for diagnostic — to use from server side
if (null != uri)
Debug.WriteLine(uri.ToString());
else
Debug.WriteLine(“PushChannel.ChannelUri is null”);
}


In my sample I’ll use the debug output to pickup the channel URI and use it for sending notifications from cloud-based website:


image


In case of this simple application I don’t really need RAW Notifications and TOAST notifications, so I’ll subscribing only for ChannelUriUpdates and ErrorOccured events:

private void SubscribeToChannelEvents()
{
pushChannel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(PushChannel_ChannelUriUpdated);
pushChannel.ErrorOccurred += new EventHandler<NotificationChannelErrorEventArgs>(PushChannel_ErrorOccurred);
}

void PushChannel_ChannelUriUpdated(object sender, NotificationChannelUriEventArgs e)
{
uri = e.ChannelUri;

if (!pushChannel.IsShellToastBound)
pushChannel.BindToShellToast();

Dispatcher.BeginInvoke(() =>
{
Debug.WriteLine(uri.ToString());
});
}

void PushChannel_ErrorOccurred(object sender, NotificationChannelErrorEventArgs e)
{
Dispatcher.BeginInvoke(() =>
MessageBox.Show(String.Format(“A push notification {0} error occurred. {1} ({2}) {3}”,
e.ErrorType, e.Message, e.ErrorCode, e.ErrorAdditionalData)));
}


Now let’s see how to create a secondary tile (one of checkbox’s event handlers function):

private void chkAlex_CheckedUnchecked(object sender, RoutedEventArgs e)
{
if (!StillInitializing)
{
if (chkAlex.IsChecked.Value)
{
StandardTileData initialData = CreateTile(“Alex”);
ShellTile.Create(new Uri(“/MoodInfo.xaml?Name=Alex”, UriKind.Relative), initialData);

}
else
{
//TODO…
}
}
}


And helper method:

private static StandardTileData CreateTile(string Name)
{
StandardTileData initialData = new StandardTileData
{
BackgroundImage = new Uri(“images/DEFAULT.png”, UriKind.Relative),
Title = Name,
BackContent = “No updates yet”,
BackTitle = “Mood”,
};
return initialData;
}

Let’s see what’s new in those methods. First – StandardTileData. It is a new class which defines the behavior of the secondary tile. It enables to define titles, contents and images for both sides of the tile. It also enables setting the count property to front face of the tile.


Note: If back property was not set, the tile will not flip.


Next – creating the tile itself: ShellTile.Create accepts the URI parameter which will serve two purposes: the ID of the tile and the URI within the application to navigate if the tile clicked.


Those parameters also affect the tile notification format sent to the application through Push Notification Server:

Content-Type: text/xml
X-WindowsPhone-Target: token

<?xmlversion=”1.0″encoding=”utf-8″?>
<
wp:Notification xmlns:wp=WPNotification>
<
wp:Tile Id=THE URL>
<
wp:BackgroundImage><background image=“” path=“”></wp:BackgroundImage>
<
wp:Count><count></wp:Count>
<
wp:Title><title></wp:Title>
<
wp:BackTitle><back side=“” title=“”></wp:BackTitle>
<
wp:BackContent><back side=“” content=“”></wp:BackContent
>
<
wp:BackBackgroundImage><back side=“” background=“” image=“” path=“”></wp:BackBackgroundImage
>
</
wp:Tile>
</
wp:Notification>


Bold parts are new for Mango.


When the tile arrives to the phone it will be identified by ID (which also serves as relative URI in the app) and will use provided images from application’s content.


Note: if secondary tile already removed (not found) nothing happens, no error thrown.


Note #2: the application doesn’t need to have primary tile on the main screen in order to make secondary tile to work.


Since it is not possible to create two tiles with the same ID, we need to manage the tiles from the application. For this matters ShellTile class provides the collection of ActiveTiles which represent all pinned tiles of the application (including the main tile if pinned by user).


The sample checks the pinned stated for secondary tiles and sets the corresponding checkbox state:

//Check for pinned secondary tiles and update UI
ShellTile toFind = ShellTile.ActiveTiles.FirstOrDefault(x => x.NavigationUri.ToString().Contains(“Alex”));
if (null != toFind)
chkAlex.IsChecked = true;

Same done when the tile need to be removed when unchecking the ckeckbox (after the “//TODO…” in “chkAlex_CheckedUnchecked” function):

ShellTile toFind = ShellTile.ActiveTiles.FirstOrDefault(x => x.NavigationUri.ToString().Contains(“Alex”));
toFind.Delete();

This way tiles added and removed from the main screen. See the video of working application below:






Working application

Last feature I want to talk about is known as “deep toast”. It enables to send relative URI to the application and navigate to specific page when TOAST notification clicked by user. In addition I’ll show how to send a local push notification message.


First – the change you have to make for your server side logic to sent deep toast message via push notification server:

Content-Type: text/xml
X-WindowsPhone-Target: toast

<?xmlversion=”1.0″encoding=”utf-8″?>
<
wp:Notification xmlns:wp=WPNotification>
<
wp:Toast>
<
wp:Text1><string></wp:Text1>
<
wp:Text2><string></wp:Text2>
<
wp:Param><THE URL=“”></wp:Param>
</
wp:Toast>
</
wp:Notification>


Bold line is new for Mango.


In order to create local deep toast I’ll use Background Agent (see part 5 in case you missed it) which will notify the user about mood change.


In the agent class I’ve created string arrays with mood/names:

string[] Names = { “Alex”, “Nicole”, “Medeya”, “Bru” };
string[] Moods = { “anger”, “burn”, “confused”, “cool”, “cry”, “fire”, “grimace”, “love”,
“miao”, “prettiness”, “question”, “shout”, “slobber”, “smile”, “spook”,
“startle”, “surprise”, “sweat”, “thirst”, “vomit”};
Random rnd = new Random();

When agent awakes I’m creating new ShellToast instance:

protected override void OnInvoke(ScheduledTask task)
{
if (!isChanceled)
{
int nameNum = rnd.Next(Names.Length);
int moodNum = rnd.Next(Moods.Length);

ShellToast toast = new ShellToast();
toast.Title = “Mood Change!”;
toast.Content = Names[nameNum] + ” changed mood”;
toast.NavigationUri = new Uri(“/MoodInfo.xaml?Name=” + Names[nameNum] + “&Mood=” + Moods[moodNum], UriKind.Relative);
toast.Show();
}
NotifyComplete();
}


The  NavigationUri points to the existing page in my application. Clicking on it takes user into specific page in the app.


image


Note: Due to bug in beta the deep toast feature is not working and will navigate always to the MainPage.xaml regardless to the URI provided. This feature should be fixed after beta.


The sample used in this post hosted here.


This is it… Will be happy to answer more questions.


Stay tuned for more Mango posts to come Smile


Alex

Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>