Using Sony SmartTags with a Nokia Lumia
Published: 1/29/2014 9:03:24 PM
I have had a Nokia Lumia 920 for more than a year now and I have never tried using NFC. Until now that is. I don't remember why but all of the sudden I got extremely interested in NFC, so I downloaded the Nokia NFC Writer app last week and quickly realised that I needed to buy NFC tags.
Being eager and unexperienced I unfortunately skipped the research part and bought some colorful Sony Xperia SmartTags, hoping that I could create some useful tags.
Big mistake. When I tried to tap a tag I got a message box telling me I needed to search for an app in the store, but no app could be found when I tried.
Hmm. I started Nokia NFC Writer and tried to write something to the tag, but it just silently refused. Hmmm, time to see what Google says (this is the research I should have done earlier..). Turns out that Xperia SmartTags are actually read-only tags that only contains an ID (a URI) used by Sony's Android app to identify them and link them to a series of actions on the phone. Bummer.
So what could I do with these tags? By looking at the URIs I noticed that they used a custom protocol named "semc://", so I started to wonder what would happen if I would create an app that registered that protocol. Could I make the phone start my app whenever I tapped a tag? Well, there is only one way to find out!
I created a new Windows Phone 8 project in Visual Studio 2013, and the first step was to register the protocol. This is done by editing the WMAppManifest.xml and adding an <Extensions> element:
<Extensions>
<Protocol Name="semc" NavUriFragment="encodedLaunchUri=%s" TaskID="_default" />
</Extensions>
Now, the next step was to add a custom URI mapper to be able to inspect the URI. This is done by creating a class that derives from the UriMapperBase class and override the MapUri method:
class CustomUriMapper : UriMapperBase
{
public override Uri MapUri(Uri uri)
{
string tempUri = System.Net.HttpUtility.UrlDecode(uri.ToString());
if(tempUri.StartsWith("/Protocol?encodedLaunchUri=semc"))
return new Uri("/MainPage.xaml?tagId=" +
tempUri.Substring("/Protocol?encodedLaunchUri=".Length), UriKind.Relative);
else
return new Uri("/OtherPage.xaml", UriKind.Relative);
}
}
It's important to note that the URI at this point will not be the one stored on the tag. The operating system will prepend the URI with "/Protocol?encodedLaunchUri=", so we need to take that into account when checking the URI. The if-case will check whether the protocol is "semc" or not, and redirect the user to the correct page depending on whether the app was started manually or by tapping a tag.
With the custom URI mapper in place we need to tell the app to use it. This is typically done in the InitializePhoneApplication method of the App class by adding this line:
RootFrame.UriMapper = new CustomUriMapper();
The MainPage.xaml page will be the landing page if a tag is tapped, so I need to add some code there. The URI mapper will pass the tag URI in a parameter named "tagId", and my sample code will simply change the background color to match the color of the tag tapped (tag URIs are mapped to colors through the "tags" dictionary).
Dictionary<string, Color> tags = new Dictionary<string, Color>();
protected override void OnNavigatedTo(NavigationEventArgs e)
{
string uri;
if(NavigationContext.QueryString.TryGetValue("tagId", out uri))
{
if(tags.ContainsKey(uri))
LayoutRoot.Background = new SolidColorBrush(tags[uri]);
else
MessageBox.Show(uri);
}
base.OnNavigatedTo(e);
}
Time to test the app. After deploying the app and tapping a tag, the following question popped up:
Looks promising. Accepting the action starts the app and changes the background to the color of the tag (and yes, I DID tap the orange tag):
So it actually worked! By registering the "semc" protocol it is possible to launch your own app and do pre-defined tasks when tapping a Sony Xperia SmartTag. Now, if only I could come up with some useful tasks...