As I mentioned in one of my last posts I have ordered some NFC tags to try out the new abilities of Near Field Communication (NFC) for Windows Phone 8 using the Proximity API.
The user story – Check-in by NFC tag
For my timesheet management application I decided that I want to use NFC technology to register new timesheet entries (check-ins) in a quick and short way. Therefore my application should have a new menu item at the timesheet entry detail page which creates a NDEF auto-launch message at a NFC tag with the current timesheet entry data. So you could have a particular NFC tag for each customer and project. If the user now tapping one of these NFC tags the WorkTime app should be started and a new entry as a clone of the data at the NFC tag should be created.
First step – save data to the NFC tag
The following code snippet I use to store the serialized current timesheet entry at the NFC tag:
I am using the NDEF library which helps me easily parse and create NDEF records with the Windows Proximity APIs (NFC). You can install the NDEF library via Nuget with Install-Package NdefLibrary. The NDEF library supports several record types such as WpSettings (for launching Windows Phone 8 settings pages), Mailto (records for sending email messages), DriveTo and WalkTo (URI schemes for starting navigation on WP8), Nokia Accessories (record to easily launch apps on Nokia Lumia WP8 phones) and the Launch App Record for auto-launching a Windows Phone 8 app.
But what to do at your app to support auto-launching?
Add Auto-Launching ability
To auto-launch a Windows Phone 8 app we have to add a URI association (a very nice new feature of Windows Phone 8) for the WorkTime app. What makes that URI special is that it begins with a URI scheme name that your app has registered for. After you do this registration, your app will be automatically started by the Windows Phone operating system, if anyone calls a URI with this scheme or the NFC tag contains a URI with the registered scheme.
In this sample worktime is the registered app scheme and all after the colon could be interpreted by your app in a UriMapper class (see later).
To register for a URI association, you must edit the WMAppManifest.xml file of your project using the XML (Text) Editor. In the Extensions element of the app manifest file, a URI association is specified with a Protocol element. Note that the Extensions element must immediately follow the Tokens element. You can register a maximum of 10 URI associations in each app.
Some schemes are reserved and will be ignored. For more information, see Reserved file and URI associations for Windows Phone 8.
The URI of our NFC tag looks like:
Protocol?encodedLaunchUri=worktime:<xml string of our TimesheetEntry object>
Map the URI and add MainPage arguments
To resolve the incoming URI we have to implement a UriMapper class which is derived from UriMapperBase and use this as new UriMapper in our application. The arguments from the LaunchApp tag are encoded into the query string. The pre-defined key name for the launch arguments which will be used also by the operating system is ms_nfp_launchargs
(nobody knows if ms_nfc_launchargs is correct or ms_nfp_launchargs because in the MSDN documentation they have mentioned both :-( - but all samples working with ms_nfp_launchargs)
My UriMapper class decodes the Uri and uses a regular expression to parses the payload of my NDEF message:
To add this class as URIMapper we have to add a new statement in the InitializePhoneApplication method of the App.xaml.cs code file.
Now the UriMapper will match the incoming Uri from the NFC tag to a relative Uri the MainPage.xaml with the NFC tag arguments as query parameter ms_nfp_launchargs.
Parse arguments and add TimesheetEntry
At my MainPage.xaml I have now to check the arguments (I use also Voice commands, therefore to check this too) and invoke the correct function of my MainViewModel. To use MVVM I have added a new message of the type NavigationMessage and send this in the NavigateTo event of my MainPage to the Messenger component of MVVMLight.
The message implementation:
To have a boolean property IsStartedByNfcRequest I added a extensions method for NavigationEventArgs:
In my MainViewModel I registered this new message and implemented a method that handles all my the app startup navigation features.
The ProcessNavigationMessage method handles all my navigation startup requests to my app (how to implement voice commands you get read here):
Supported NFC tags at Windows Phone 8
My Lumia 920 – but according the documentation also the rest of Windows 8 Phone - supports the following tag types:
- Type 1: Topaz family
- Type 2: Mifare Ultralight family, my-d-move, NTag
- Type 3: Felica family
- Type 4: Desfire family
- Non standardized: Mifare Standard
Regarding NFC tags NDEF formatting:
- Windows Phone 8 supports only NDEF level access to these tags, that means that the tag needs to be NDEF formatted or have an existing NDEF message on it (empty or not). If you try to use the APIs on a non-formatted NFC tags they won’t work (as Windows Phone 8 has no support for low level Tag Type specific commands/access)
- Tip: If you want to NDEF format your tags you can ordering tags which are already NDEF formatted. Alternatively you can use an NFC USB Reader/Writer for PC or use an Android NFC device with an NFC writing app
The result - How it’s look like
In my timesheet detail page I have now a menu entry for a NFC Tag page (create NFC Tag- sorry for the German screenshot)
The NFC status page which writes the data to the NFC tag, if this is tapped. I used the DeviceArrived and DeviceDeparted events of the API (see code above) to inform the user if the tag is in writable near.
Result: I can use now these colorful NFC tags to auto-checkin for different projects: