{"id":1707,"date":"2014-09-15T17:54:08","date_gmt":"2014-09-15T16:54:08","guid":{"rendered":"http:\/\/meier-online.com\/?p=1707"},"modified":"2014-09-19T14:04:08","modified_gmt":"2014-09-19T13:04:08","slug":"nfc-hunt-analysed","status":"publish","type":"post","link":"https:\/\/meier-online.com\/en\/2014\/09\/nfc-hunt-analysed\/","title":{"rendered":"How does the NFC-Hunt App from Google works?"},"content":{"rendered":"<p>Google organized a kind of scavenger hunt for the developers conference IO 2013 to demonstrate the practical use of NFC. Participants needed an NFC-enabled Android and then installed an app called <a href=\"https:\/\/nfchunt.appspot.com\" title=\"Description of the NFC-Hunt game from Google IO\" target=\"_blank\">&#8220;NFC Hunt&#8221;<\/a>. The app gives clues where to find specific NFC tags in the real world. The user has to find and scan these tags, and then the app give clues for the next station. <\/p>\n<p>Google has published the<a href=\"https:\/\/code.google.com\/p\/google-io-hunt\" title=\"to source code repository from google NFC Hunt\" target=\"_blank\"> source code of NFC Hunt app<\/a>. So we developers have a fine example of a complete NFC application. But when I tried to understand the source code I noticed gaps in the documentation. Just the interesting parts are not explicitly explained: how can I make my app listen to NFC tags and how do I respond to the detected tags. Here now is the result of my research: <\/p>\n<p><!--more--><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/meier-online.com\/blog\/uploads\/nfchunt-tagdetectionflow.png\" alt=\"Diagram with Manifest, Android-OS, NFC-Tag, NFCShimActivity and ClueActivity\" width=\"540\" height=\"500\" class=\"alignnone size-full wp-image-1717\" srcset=\"https:\/\/meier-online.com\/blog\/uploads\/nfchunt-tagdetectionflow.png 540w, https:\/\/meier-online.com\/blog\/uploads\/nfchunt-tagdetectionflow-300x277.png 300w\" sizes=\"(max-width: 540px) 100vw, 540px\" \/><\/p>\n<p>Step 0: The app uses the manifest to tell the system that it wants to handle NFC messages. This happens without the app running. The <a href=\"https:\/\/code.google.com\/p\/google-io-hunt\/source\/browse\/SimpleIOHunt\/AndroidManifest.xml\" title=\"Source code of nfc-hunt manifest.xml\" target=\"_blank\">manifest <\/a>defines which Activity gets the NFC data:<\/p>\n<pre lang=\"xml\" escaped=\"true\">  \r\n&lt;activity android:name=\".NFCShimActivity\"\r\n            android:theme=\"@android:style\/Theme.NoDisplay\">      \r\n&lt;intent-filter>\r\n  &lt;action android:name=\"android.nfc.action.NDEF_DISCOVERED\" \/>\r\n  &lt;category android:name=\"android.intent.category.DEFAULT\" \/>\r\n  &lt;data android:scheme=\"https\" android:host=\"nfchunt.appspot.com\"\r\n                    android:pathPrefix=\"\/f\" \/>\r\n&lt;\/intent-filter>\r\n\t...\r\n&lt;\/activity>\r\n<\/pre>\n<p>In addition, we need to request the permission to use NFC at all: <\/p>\n<pre lang=\"xml\" escaped=\"true\">\r\n&lt;uses-permission android:name=\"android.permission.NFC\" \/&gt;\r\n<\/pre>\n<p>For some Apps NFC is only an optional feature. But our app does not make sense without NFC-capable hardware, therefore there is the following entry: <\/p>\n<pre lang=\"xml\" escaped=\"true\">\r\n&lt;uses-feature android:name=\"android.hardware.nfc\" android:required=\"true\" \/&gt;\r\n <\/pre>\n<p>Step 1: The NFC tag contains data in the <acronym title=\"NFC Data Exchange Format\">NDEF<\/acronym> format. In our case, this is a &#8220;bookmark&#8221;, a URL. The URL has a pattern: the front part is always the same and the end defines different data, just like web developers use it for HTTP GET. <\/p>\n<pre>http:\/\/nfchunt.appspot.com\/f?c=CLUENAME<\/pre>\n<p>The system recognizes the NFC tag, analyses the type of message and determines which app is responsible. In case that our NFC-Hunt is not installed yet, the browser would start, then load the specified URL and display a page with the description of the game.<\/p>\n<p>The system recognizes the NFC tag, analyses the type of message and determines which app is responsible. In case that our NFC-Hunt is not installed yet, the browser would start, load the specified URL and displays a page with the description of the game.<\/p>\n<p>Step 2: The system calls our Activity as specified in the manifest. In our app a minimal activity without UI is defined: the <a href=\"https:\/\/code.google.com\/p\/google-io-hunt\/source\/browse\/SimpleIOHunt\/src\/com\/google\/wolff\/androidhunt\/NFCShimActivity.java\" title=\"Source code if NFCShimActivity\" target=\"_blank\">NFCShimActivity<\/a>. <\/p>\n<p>This Activity analyses the received data. It puts the data in an Intent. The Intent is now sent to the actual Activity with the UI. (Step 3) <\/p>\n<p>This intermediate step allows to decouple the external NFC data and formats from all what is happening in the rest of the app. We even have the option to send the Intent to an entirely different app to give this app new NFC capabilities. <\/p>\n<p>Step 4: The system displays the actual Activity, in our case the <a href=\"https:\/\/code.google.com\/p\/google-io-hunt\/source\/browse\/SimpleIOHunt\/src\/com\/google\/wolff\/androidhunt\/ClueActivity.java\" title=\"Source Code of ClueActivity\" target=\"_blank\">ClueActivity<\/a>. There is something we need to care of: If the Activity is already visible, then Android will start a second instance of Actvity and you see it pop up in a second window. <\/p>\n<p>In our case an already visible screen should remain visible, it should just be updated with the newly received data. Therefore, the Activity gets in the manifest attribute <\/p>\n<p><code> android:launchMode=\"singleTask\" <\/code><\/p>\n<p>Usually we get access to the data of an Intent in onCreate () &#8211; method, now onCreate () is not called a second time. We must therefore overriding the method onNewIntent (). We store the transferred data there. <\/p>\n<pre lang=\"java\">public void onNewIntent(Intent intent) {....}<\/pre>\n<p>In the following Android calls the onResume () method again. In the method we finally respond to the data, change the game status and show the found tags with updateTagDisplay(). (Step 6) <\/p>\n<h3>Conclusion<\/h3>\n<p>The approach demonstrated in NFC-Hunt is only one way in which you can interact with NFC tags. For many applications it provides a useful framework. <\/p>","protected":false},"excerpt":{"rendered":"<p>Google organized a kind of scavenger hunt for the developers conference IO 2013 to demonstrate the practical use of NFC. Participants needed an NFC-enabled Android and then installed an app called &#8220;NFC Hunt&#8221;. The app gives clues where to find specific NFC tags in the real world. The user has to find and scan these &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/meier-online.com\/en\/2014\/09\/nfc-hunt-analysed\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;How does the NFC-Hunt App from Google works?&#8221;<\/span><\/a><\/p>\n","protected":false},"author":4,"featured_media":1701,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[106,104],"tags":[18,186,225],"class_list":["post-1707","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-mobile","category-develop","tag-adventure","tag-android","tag-nfc","entry"],"_links":{"self":[{"href":"https:\/\/meier-online.com\/en\/wp-json\/wp\/v2\/posts\/1707"}],"collection":[{"href":"https:\/\/meier-online.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/meier-online.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/meier-online.com\/en\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/meier-online.com\/en\/wp-json\/wp\/v2\/comments?post=1707"}],"version-history":[{"count":13,"href":"https:\/\/meier-online.com\/en\/wp-json\/wp\/v2\/posts\/1707\/revisions"}],"predecessor-version":[{"id":1753,"href":"https:\/\/meier-online.com\/en\/wp-json\/wp\/v2\/posts\/1707\/revisions\/1753"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/meier-online.com\/en\/wp-json\/wp\/v2\/media\/1701"}],"wp:attachment":[{"href":"https:\/\/meier-online.com\/en\/wp-json\/wp\/v2\/media?parent=1707"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/meier-online.com\/en\/wp-json\/wp\/v2\/categories?post=1707"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/meier-online.com\/en\/wp-json\/wp\/v2\/tags?post=1707"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}