Andrej Tozon's blog

In the Attic

NAVIGATION - SEARCH

Windows 8 Metro declarations: Protocol

I touched on the Metro-style application declarations in my previous blog entry where I wrote about application manifest. I’m continuing the series with exploring the currently available declarations, starting with Protocol. I’ll be using C# Windows Metro style application samples throughout the whole series.

I imagined an application that would respond to the specific URL requests. Let’s say that invoking a URL like “locx://aerial/47.639747~-122.129731” should show me an aerial map, centered to a geographical point of (47.639747, -122.129731).

Displaying a Map

Let’s first figure out how to display the map. There isn’t any native WinRT maps component yet, so the simplest way to display a map is using Bing maps in a WebView Xaml control. WebView is a control that can display HTML, either passed in by string or by navigating to actual web site. Think of it as a very lightweight WebBrowser control, without all the chrome and other clutter.

So I put a WebView control on the MainPage, made sure it fills the whole page and altered its default constructor a bit:

public MainPage()
{
    InitializeComponent();
    WebView.Navigate(new Uri("http://www.bing.com/maps"));
}

Run the application – it should display a nice map of the world. If you have a touch screen, try manipulating the map with your fingers – it' feels nice Winking smile

Metro-style application can be configured to handle any URL protocol

Back to the subject. Open the application manifest configuration screen and navigate to the Declarations tab. Open the Available Declarations dropdown and select Protocol. The protocol will be added to Supported Declarations list box when you click the Add button.

image

Handling declaration properties for Protocol is pretty simple. You’re only required to name the protocol you want your application to handle. For this example, I’m using “locx”.

An optional custom graphics can be used as an application icon whenever the protocol declaration association needs to be displayed to the user (e.g. Control Panel). If not set, application’s Logo image will be used.

Once configured, open App.xaml.cs and override the OnActivated method. This method will get called whenever application is activated. Because an application can be activated for the various reasons, you have to check against the passed arguments for the specific activation kind.

protected override void OnActivated(IActivatedEventArgs args)
{
    if (args.Kind == ActivationKind.Protocol)
    {
        OnProtocolActivated((ProtocolActivatedEventArgs)args);
    }
}

When application is Protocol-activated, the activation arguments should be of the ProtocolActivatedEventArgs type and it should be safe to cast to that. I’ve created the OnProtocolActivated method to handle those cases separately. Note that some other activation scenarios have their equivalent activation methods already built in.

In the OnProtocolActivated method, you’ll have to resolve the Uri that was used for activation. I declared the following Uri format: locx://[view]/[latitude]~[longitude], where view is either roads or aerial. Here’s the method that parses the Uri and calls a specific constructor of the MainPage. That latitude and longitude should be provided using the currently set culture format (commas vs. dots) so they could be parsed into doubles.

private void OnProtocolActivated(ProtocolActivatedEventArgs args)
{
    string type = args.Uri.Host;
    double lat;
    double lng;

    string[] latlng = args.Uri.LocalPath.Substring(1).Split(new[] { "~" }, StringSplitOptions.RemoveEmptyEntries);

    if (latlng.Length != 2 || !double.TryParse(latlng[0], out lat) || !double.TryParse(latlng[1], out lng))
    {
        Exit();
        return;
    }

    Window.Current.Content = new MainPage(type, lat, lng);
    Window.Current.Activate();
}

In overridden MainPage constructor, a Bing maps query is composed and navigated to. Invariant culture is used to convert latitude and longitude to the proper format.

public MainPage(string type, double lat, double lng)
{
    InitializeComponent();
    string uri = string.Format("http://www.bing.com/maps/default.aspx?cp={0}~{1}&lvl=10&style={2}", lat.ToString(CultureInfo.InvariantCulture), lng.ToString(CultureInfo.InvariantCulture), type.ToLower()[0]);
    WebView.Navigate(new Uri(uri));
}

Activation Registration

A very positive thing about activating declarations is that protocol registration will be done when you deploy the application to your computer. That means you don’t need to run the application (as in – the first time) to register the protocol. You can even choose that your application will only support activation and do nothing when launched the ordinary way.

After deploying, you can test your application by invoking the following link from the command line (or Run prompt):

image

image

Of course application will handle any subsequent protocol requests while it’s already running too.

Metro-style application declarations promise a simple integration with the OS through predefined contracts, Protocol is just one of those extensibility points. I’ll look into others in my next posts.