Nico's digital footprint

I grew up in the nineties, that makes me awesome by default

Getting home with Windows Phone 8 and NFC

by Nico

Imagine this, you’re somewhere you’ve never been before and you need your phone to navigate you home but you need a quick getaway and don’t have time to enter the address manually. Or you’re taking the boy/girl of your dreams home after a great date and want to impress them with some technological stuff (because geeks are the new sexy). In both scenarios NFC can come to the rescue. In this article I’m going to explain how you can program an NFC tag to launch your navigation app and navigate you home. (NOTE: this has been tested on a Nokia Lumia 920 with Nokia Drive).

First, the prerequisites. We need an NFC capable Windows Phone 8 device with navigation software. We also need a blank, NDEF formatted, writable NFC tag (I got mine from RapidNFC). We’ll also need a dataconnection to fetch our coordinates (only for writing the NFC tag).

Next, the pieces of the puzzle. In this case there are three things that need to be taken care of. First we need to be able to enter an address in an app and get the longitude/latitude coordinates for that address. Second, we need to write the instruction for launching the navigations app and navigating to those coordinates to an NFC tag and third we need our phone to actually launch the app and navigate to the received coordinates. Now to make that last part work we only need to make sure we have an NFC capable phone, have NFC enabled in Settings and that we have navigational software installed.

Enough planning, let’s get to work. First the UI, I‘m going with two TextBlocks, one to enter the address and one that will show the coordinates just to see if that worked. I also need two buttons, one for fetching the coordinates and one for writing the NFC tag. Here’s the XAML

Code Snippet
  1. <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
  2.     <StackPanel>
  3.         <TextBlock Text="Address" />
  4.         <TextBox x:Name="TextBoxAddress" />
  5.                         <TextBlock Text="Coordinates" />
  6.            <TextBox x:Name="TextBoxCoordinates" />
  7.         
  8.         <StackPanel Orientation="Horizontal">
  9.             <Button Content="Get Coordinates" Click="GetCoordinatesButtonClick" />
  10.             <Button Content="Write NFC tag" Click="WriteTagButtonClick" />
  11.         </StackPanel>
  12.     </StackPanel>
  13. </Grid>

With this as the final result

How this works, we enter an address in the top TextBox and click the “Get Coordinates” button. This will use the Microsoft.Phone.Maps functionality to translate that address into coordinates, those coordinates will show up in the bottom TextBox. When we click the “Write NFC tag” button the app will wait for a writable NFC tag, once that’s detected the data will be written on it. All it takes then is a tap on the tag and the phone will take you home.

Before we dive into code we need to add some capabilities. Using the Maps namespace and using NFC requires two capabilities, double-click the WMAppManifest.xml file and select these capabilities.

This will keep us away from any UnauthorizedExceptions.

On to the code we go, we’ll start with declaring some private fields.

Code Snippet
  1. private GeoCoordinate _coordinate;
  2. private ProximityDevice _device;

After that, we go to the “Get Coordinates” button.

Code Snippet
  1. private void GetCoordinatesButtonClick(object sender, RoutedEventArgs e)
  2. {
  3.     string address = TextBoxAddress.Text.Trim();
  4.  
  5.     if (address == string.Empty)
  6.     {
  7.         MessageBox.Show("Address cannot be empty!");
  8.         return;
  9.     }
  10.  
  11.     GeocodeQuery query = new GeocodeQuery
  12.                              {
  13.                                  GeoCoordinate = new GeoCoordinate(0, 0),
  14.                                  SearchTerm = address
  15.                              };
  16.  
  17.     query.QueryCompleted += (o, args) =>
  18.                                 {
  19.                                     if (args.Result == null)
  20.                                     {
  21.                                         TextBoxCoordinates.Text = "No coordinates found";
  22.                                         return;
  23.                                     }
  24.                                     _coordinate = args.Result[0].GeoCoordinate;
  25.                                     TextBoxCoordinates.Text = string.Format("Lat: {0} / Lon: {1}",
  26.                                         args.Result[0].GeoCoordinate.Latitude.ToString(),
  27.                                         args.Result[0].GeoCoordinate.Longitude.ToString());
  28.                                 };
  29.     query.QueryAsync();
  30. }

First thing we need to do is verify if an address was actually entered in the TextBlock. When that’s verified we declare a GeocodeQuery and initialize it with a new GeoCoordinate and pass the address as a SearchTerm. When the query completes we check if there’s a result. The query should return a result of type IList<MapLocation> the first element in the list is the one we need, and from this first item we need the GeoCoordinate property, we’ll put that one in the _coordinate field. We call the QueryAsync() method on GeocodeQuery to get the result. For some reason QueryAsync returns void, meaning we can’t just await it. We need to do this the oldschool way and use the QueryCompleted event handler.

With that, the first part of our puzzle is solved. We can go from an address to a coordinate. Now we just need a way to get this coordinate and the navigation app launch instruction onto an NFC tag. Let’s have a look at what happens when the “Write NFC tag” button is clicked.

Code Snippet
  1. private void WriteTagButtonClick(object sender, RoutedEventArgs e)
  2. {
  3.     _device = ProximityDevice.GetDefault();
  4.  
  5.     if (_device == null)
  6.     {
  7.         MessageBox.Show("NFC not detected, is it disabled?");
  8.         return;
  9.     }
  10.  
  11.     TextBlockStatus.Text = "NFC detected, waiting for writable tag";
  12.  
  13.     _device.SubscribeForMessage("WriteableTag", (device, message) =>
  14.                     {
  15.                         Deployment.Current.Dispatcher.BeginInvoke(() =>
  16.                                         {
  17.                                             TextBlockStatus.Text = "writable tag detected";
  18.                                         });
  19.                         WriteTag();
  20.                     });
  21. }

There’s some NFC magic going on here. First we instantiate a ProximityDevice instance and activate the proximity provider. If, at that point, _device is null it means that the Windows Phone device either has no NFC capabilities or they are disabled in Settings > Tap & Send. If _device is not null we have successfully initialized NFC. Line 13 is a bit special. We call the SubscribeForMessage() method on the ProximityDevice. What happens is, when the NFC provider reads a tag it sends a message, we subscribe to the “WritableTag” message because it’s the only thing we can use in this case. If you want a complete list of all supported message types, have a look at MSDN.Since the subscription doesn’t live on the UI thread we need to use the Dispatcher in order to update the TextBlock that hold the status. The WriteTag() method gets called when a writable NFC tag is detected.

Code Snippet
  1. private void WriteTag()
  2. {
  3.     string uri = string.Format(@"ms-drive-to:?destination.latitude={0}&destination.longitude={1}",
  4.         _coordinate.Latitude.ToString(CultureInfo.InvariantCulture),
  5.         _coordinate.Longitude.ToString(CultureInfo.InvariantCulture));
  6.  
  7.     var writer = new DataWriter
  8.                          {
  9.                              UnicodeEncoding = UnicodeEncoding.Utf16LE
  10.                          };
  11.  
  12.     writer.WriteString(uri);
  13.  
  14.     _device.PublishBinaryMessage("WindowsUri:WriteTag", writer.DetachBuffer(), (sender, id) =>
  15.         Dispatcher.BeginInvoke(() => TextBlockStatus.Text = "Tag written"));
  16. }

This method is the piece of magic that glues all pieces together. We start by setting the Uri that will launch when the tag is tapped. “ms-drive-to” means we need whatever app is registered to the drive-to command (you can also get walking directions by using “ms-walk-to”) the rest of the string are parameters we’re passing into that app. We are passing the coordinates into the app, passing those in means that the app knows we want to navigate and where we want to go. We also need a DataWriter with Utf16LE encoding (this is the encoding needed for writing uri messages to NFC tags). We fill the buffer of the DataWriter with the uri string we’ve constructed a second ago and we publish it through the ProximityDevice as a binary message. The PublishBinaryMessage() method takes in a messagetype and an implementation of IBuffer, provided by the DataWriter in this case. In an overload the method also takes a method that fires when the publish is completed, we use this event handler to update our UI.

That’s all folks, with a bit of tinkering we’ve combined two possibilities of the Windows Phone 8 platform in a very cool, almost “magical” trick. I've got my NFC sticker in my car, impressing people wherever I go and now you can all be as cool as I am Smile you’re welcome.

To finish of, some action shots of the app.


Coordinates detected


Tapped a programmed tag


Navigation started


Tags:

NFC | .Net | Devices | WP8 | XAML

blog comments powered by Disqus
  Log in

About the author

Hi,

My name is Nico, I’m an MVP Windows Platform Development living in Belgium.
I’m currently employed as a .NET consultant at RealDolmen, one of Belgium’s leading IT single source providers.

I'm also founding member and board member of the Belgian Metro App Developer Network, a user group focussed on Windows 8 and Windows Phone development. If you're in Belgium feel free to drop by if we're doing an event. http://www.madn.be

Since June 2012 I'm a proud member of Microsoft's Extended Experts Team Belgium. And in February 2013 I became a member of DZone's Most Valuable Bloggers family.

In 2013 I became a book author and wrote "Windows 8 app projects, XAML & C# edition".

In 2014 I received the MVP award for the very first time.

I hope to get feedback from my readers either through comments, mail (nico_vermeir@hotmail.com), twitter, facebook, …

 

mvp

 

mvp

 

 

MeetLogo

 

MVBLogo

mybook

 

Month List