TL:DR
Protocol activation is a cool feature you can add to your Windows Store apps, and allows you to make your app more useful as well as more discoverable. For a video demonstration of how easy it is to add protocol activation to your app, skip to the end of the post. Otherwise, read on…
Helping Apps Collaborate
I’ve written in the past about a very useful feature of Windows called protocol activation (a feature that’s not new…in fact, it’s what allows an http:// link to open your default browser…but is particularly useful in the context of Windows Store apps), and how I’ve used this feature to add maps and directions to my Community Megaphone app (see below) without having to write any of the code for that functionality myself. Protocol activation allows both desktop and modern apps to register themselves as handlers for a given protocol or URL scheme. Some, like http: are well-known, and understood. Others may be custom schemes that are unique to the handling app.
In the case of the Maps app that comes with Windows 8, the custom schema for its bingmaps: protocol is well-documented, which is how I knew I could use it in the Community Megaphone app.
Discovering Available Protocols
But what other apps are out there waiting to be activated via protocol activation? Well, one way to discover this is via the Set Associations dialog in Control Panel (to get there, just open Control Panel and type “associate” in the search box in the upper right):
You may already be familiar with this dialog, if you’ve ever needed to fix some file associations after some program you installed “helpfully” re-set them for you. What you might not be aware of is that this dialog also allows you to view and edit the programs that are used to handle various protocols registered for activating apps.
For example, if I scroll down in this dialog to the Protocols section, I can see that on my system, the http protocol is mapped to Internet Explorer:
Note, above, that Internet Explorer is also mapped to the https and ftp protocols. If I had installed another FTP program, it might have taken over the mapping for that protocol.
Of greater interest for app developers is the fact that all of the desktop apps and modern Windows Store apps that offer protocol activation are listed here as well. So any app you develop can leverage these protocols by constructing a matching URL and invoking it in your app. Of course, the Maps app is one example, but here’s another from my system:
Code Writer is a third-party app created by ActiPro software, and it’s a very robust code editor, implemented as a modern app, with support for a vast array of file types, syntax coloring, theme support, and a lot more:
Why Implement Protocol Activation in My App?
Before getting into the nitty gritty of what Code Writer offers, I want to touch on motivation. The reasons for implementing protocol activation in an app are varied, but one major reason is to increase the utilization and discoverability of your app.
When your app offers its functionality via protocol activation (and you make that fact clear in your documentation), other app developers may gladly leverage the functionality in your app, rather than write it themselves. Which means more use of your app.
In terms of discoverability, Windows 8 has made huge strides in making it possible for developers to leverage your app, even if it isn’t currently installed on the user’s system. On Windows 7 and earlier, if you ran into a file extension or protocol that wasn’t registered, you’d get a dialog something like this:
I don’t know about the rest of you, but I can’t remember ever successfully finding and discovering a piece of software to handle an unknown extension from the above dialog.
By contrast, Windows 8 (and Windows RT) leverages the Windows Store to find apps that support the desired file type or protocol. Because protocol activation information is part of an app’s metadata, the store can easily surface appropriate apps for the end-user, even if they’re not already installed. So for example, if a user of my Community Megaphone app had uninstalled the Maps app, and tried to navigate to the Get Directions link for an event, here’s what they’d see:
The dialog is cleaner, and the call to action clearer. If the user clicks the button to look for an app, the Windows Store would open and display the Maps app (as well as any other apps that handle the same protocol):
Another point on motivation…in the case of an app like Code Writer, it’s clear that the reason for building their app is to help highlight their expertise in building robust code editors and components, as that’s their business. The more you can use and experience the app, presumably, the better your opinion of them. Adding protocol activation is just one more way for them to add value to the app for their customers, namely developers.
Similarly Telerik has a showcase page where they show off the many apps, including their own Tasks by Telerik app, that are built using their controls.
Whether your motive is to sell your app directly, get more attention for your controls or services, or simply to provide additional value for your app, adding protocol activation can be a good strategy, and is easy to do.
Protocol Activation Options
The most common way of providing additional functionality beyond just launching an app via protocol activation is for the registered app to accept querystring parameters that support specific options. For example, the options for the Bing Maps app protocol are documented on MSDN, and include the ‘where’ option, which is what I use to pass an address to the app on which to center the map. Other options include the ability to query for businesses, show traffic information, and even provide a pre-calculated route.
The CodeWriter app likewise provides good documentation of the options available for their app, which includes a path option to open a specific document upon launching the app.
Unfortunately, these two apps are the exception rather than the rule when it comes to documenting the available options with protocol activation. So if you do plan to provide this feature in your app, be sure to document it, so folks know it’s there, and how to use it! Below is an example from CodeWriter’s Help page (accessed from the Settings charm) of how to do it right:
Adding Protocol Activation
To illustrate how simple it can be to offer functionality via protocol activation, I’ll walk through a fairly simple scenario, in which I create an app that will display posts from my blog based on the devhammer: protocol, optionally displaying posts based on a query string argument passed with the Uri for the request. For a simpler example of file and protocol activation, check out the Association Launcher sample (this sample is for Windows 8.1, but should illustrate the concepts for either Windows 8 or 8.1). There’s also specific documentation on adding protocol activation for both JavaScript and HTML apps, as well as XAML and C#/VB/C++ apps.
One thing that’s nice about protocol activation is that you don’t necessarily need to build a client app to test it. You can simply enter the desired Uri in the Internet Explorer or File Explorer address bar (it also works with Firefox, but I wasn’t able to get it to work with Chrome in my testing)…for added security if you’re using a browser, you’ll be prompted whether you want to allow the target app to be opened:
If I use the File Explorer address bar instead, no prompt is needed, and the app opens immediately.
Since I don’t have a lot of opportunities to play with XAML code of late, I figured I’d build my example app using XAML and C#, based on part 5 of the “Create Your First App” tutorial on the Windows Developer Center. I’m not going to walk through the entire codebase, but I’ll show the highlights here, and make my app’s source code available for download.
To add support for the “devhammer:” protocol I’m going to use, I need to open up the Package.appxmanifest file at the root of my project (I just started out with a Blank App (XAML) C# project), and on the Declarations tab, use the drop-down on the left to add the Protocol declaration, and configure it to use “devhammer” as the protocol name, as shown below:
When the app is packaged and installed, this declaration will automatically add map the “devhammer” protocol to my app, and the entry will show up in the Set Associations dialog, as shown below (note that I’m using the default icon…not very snazzy):
In the code, we need to handle the situation where our app is activated by a protocol. To do this, we just handle the OnActivated event in App.xaml.cs, and check the Kind property of the args passed in, like so:
protected override void OnActivated(IActivatedEventArgs args) { if (args.Kind == ActivationKind.Protocol) { ProtocolActivatedEventArgs protocolArgs = args as ProtocolActivatedEventArgs; var rootFrame = new Frame(); rootFrame.Navigate(typeof(BlogItems), args); Window.Current.Content = rootFrame; } Window.Current.Activate(); }
The BlogItems class in the Navigate call is referring to the Items page I added to the project, and which I’m using to display the blog items in a GridView control. The second argument to the Navigate method is an object parameter, to which I’m passing the protocol activation event args, which contains the protocol activation Uri, among other important information. Note that we don’t care at this point about the name of the protocol, as the OS has already handled all that based on the declaration in the app manifest.
When the app navigates to the BlogItems page, the LoadState method in BlogItems.xaml.cs is called, and receives the parameter passed to the Navigate method above. It also receives any preserved state from earlier sessions, but this is not applicable in our case. In LoadState, I’m grabbing a reference to the FeedDataSource (implemented in FeedData.cs, which is a modified version of the code from the Blog Reader tutorial, you can check out the code in the download link at the end of the post), which is responsible for loading the posts from my blog, based on the tag name provided by the protocol activation query string argument (I’m keeping the parsing VERY simple by just grabbing whatever comes after the “=” sign…not very robust, but easy to do. If you want to handle multiple parameters, you’ll need some additional parsing code to grab them from the query string), or the default (which I’ve defined in App.xaml as a string resource, and defaults to “Windows 8”):
protected async override void LoadState(Object navigationParameter, Dictionary<String, Object> pageState) { FeedDataSource feedDataSource = (FeedDataSource)App.Current.Resources["feedDataSource"]; var connectionProfile = Windows.Networking.Connectivity.NetworkInformation.GetInternetConnectionProfile(); if (connectionProfile != null) { if (feedDataSource != null) { if (feedDataSource.Feeds.Count == 0 || navigationParameter != "") { string tagName = (string)App.Current.Resources["tagName"]; if (navigationParameter != "") { ProtocolActivatedEventArgs pa = navigationParameter as ProtocolActivatedEventArgs; string qS = pa.Uri.Query; int i = qS.IndexOf("=") + 1; tagName = qS.Substring(i, qS.Length - i); } else { //Windows.UI.Popups.MessageDialog myMessage = new Windows.UI.Popups.MessageDialog("No Protocol event args passed!"); //await myMessage.ShowAsync(); } this.pageTitle.Text = this.Resources["AppName"] + " " + tagName; await feedDataSource.GetFeedsAsync(tagName); } } } else { var messageDialog = new Windows.UI.Popups.MessageDialog("An internet connection is needed to download feeds. Please check your connection and restart the app."); var result = messageDialog.ShowAsync(); } if (feedDataSource != null) { this.DefaultViewModel["Items"] = feedDataSource.Feeds[0].Items; } }
Note that I’m testing to see whether the FeedDataSource instance has any feeds, and if not, I ask it to go get some feeds. I also check whether we’ve gotten a navigationParameter passed in. If not, the app was launched without protocol activation, so we’ll get the default tag, and things will still work fine.
Here’s what the app looks like if I launch it from the app tile (or from Visual Studio), which will default to retrieving posts tagged with “Windows 8”:
And here’s the result if I type “devhammer:?tag=canvas” in the address bar of File Explorer:
This is admittedly a very simple example, but you can imagine the flexible and powerful workflows you can enable via protocol activation. You could create modularized apps, each of which focus on a particular set of features, but which can rely on one another to provide optional functionality. Users who don’t need those features can simply download the app(s) they care about, while those who want the additional features can use the Windows Store integration to easily locate and download the related apps.
For those who appreciate a more visual approach to learning, here’s a screencast demo of the app and protocol activation in action: