1 page.title=NFC Basics 2 @jd:body 3 4 5 <div id="qv-wrapper"> 6 <div id="qv"> 7 <h2>In this document</h2> 8 <ol> 9 <li><a href="#tag-dispatch">The Tag Dispatch System</a> 10 <ol> 11 <li><a href="#ndef">How NFC tags are mapped to MIME types and URIs</a></li> 12 <li><a href="#dispatching">How NFC Tags are Dispatched to Applications</a></li> 13 </ol> 14 </li> 15 <li><a href="#manifest">Requesting NFC Access in the Android Manifest</a></li> 16 <li><a href="#filtering-intents">Filtering for Intents</a> 17 <ol> 18 <li><a href="#ndef-disc">ACTION_NDEF_DISCOVERED</a></li> 19 <li><a href="#tech-disc">ACTION_TECH_DISCOVERED</a></li> 20 <li><a href="#tag-disc">ACTION_TAG_DISCOVERED</a></li> 21 <li><a href="#obtain-info">Obtaining information from intents</a></li> 22 </ol> 23 </li> 24 <li><a href="#creating-records">Creating Common Types of NDEF Records</a> 25 <ol> 26 <li><a href="#abs-uri">TNF_ABSOLUTE_URI</a></li> 27 <li><a href="#mime">TNF_MIME_MEDIA</a></li> 28 <li><a href="#well-known-text">TNF_WELL_KNOWN with RTD_TEXT</a></li> 29 <li><a href="#well-known-uri">TNF_WELL_KNOWN with RTD_URI</a></li> 30 <li><a href="#ext-type">TNF_EXTERNAL_TYPE</a></li> 31 <li><a href="#aar">Android Application Records</a></li> 32 </ol> 33 </li> 34 <li><a href="#p2p">Beaming NDEF Messages to Other Devices</a></li> 35 </ol> 36 </div> 37 </div> 38 39 <p>This document describes the basic NFC tasks you perform in Android. It explains how to send and 40 receive NFC data in the form of NDEF messages and describes the Android framework APIs that support 41 these features. For more advanced topics, including a discussion of working with non-NDEF data, 42 see <a href="{@docRoot}guide/topics/connectivity/nfc/advanced-nfc.html">Advanced NFC</a>.</p> 43 44 45 <p>There are two major uses cases when working with NDEF data and Android:</p> 46 47 <ul> 48 <li>Reading NDEF data from an NFC tag</li> 49 <li>Beaming NDEF messages from one device to another with <a href="#p2p">Android 50 Beam™</a></li> 51 </ul> 52 53 54 <p>Reading NDEF data from an NFC tag is handled with the <a href="#tag-dispatch">tag dispatch 55 system</a>, which analyzes discovered NFC tags, appropriately categorizes the data, and starts 56 an application that is interested in the categorized data. An application that wants to handle the 57 scanned NFC tag can <a href="#filtering-intents">declare an intent filter</a> and 58 request to handle the data.</p> 59 60 <p>The Android Beam™ feature allows a device to push an NDEF message onto 61 another device by physically tapping the devices together. This interaction provides an easier way 62 to send data than other wireless technologies like Bluetooth, because with NFC, no manual device 63 discovery or pairing is required. The connection is automatically started when two devices come 64 into range. Android Beam is available through a set of NFC APIs, so any application can transmit 65 information between devices. For example, the Contacts, Browser, and YouTube applications use 66 Android Beam to share contacts, web pages, and videos with other devices. 67 </p> 68 69 70 <h2 id="tag-dispatch">The Tag Dispatch System</h2> 71 72 <p>Android-powered devices are usually looking for NFC tags when the screen 73 is unlocked, unless NFC is disabled in the device's Settings menu. 74 When an Android-powered device discovers an NFC tag, the desired behavior 75 is to have the most appropriate activity handle the intent without asking the user what application 76 to use. Because devices scan NFC tags at a very short range, it is likely that making users manually 77 select an activity would force them to move the device away from the tag and break the connection. 78 You should develop your activity to only handle the NFC tags that your activity cares about to 79 prevent the Activity Chooser from appearing.</p> 80 81 <p>To help you with this goal, Android provides a special tag dispatch system that analyzes scanned 82 NFC tags, parses them, and tries to locate applications that are interested in the scanned data. It 83 does this by:</p> 84 85 <ol> 86 <li>Parsing the NFC tag and figuring out the MIME type or a URI that identifies the data payload 87 in the tag.</li> 88 <li>Encapsulating the MIME type or URI and the payload into an intent. These first two 89 steps are described in <a href="#ndef">How NFC tags are mapped to MIME types and URIs</a>.</li> 90 <li>Starts an activity based on the intent. This is described in 91 <a href="#dispatching">How NFC Tags are Dispatched to Applications</a>.</li> 92 </ol> 93 94 <h3 id="ndef">How NFC tags are mapped to MIME types and URIs</h3> 95 <p>Before you begin writing your NFC applications, it is important to understand the different 96 types of NFC tags, how the tag dispatch system parses NFC tags, and the special work that the tag 97 dispatch system does when it detects an NDEF message. NFC tags come in a 98 wide array of technologies and can also have data written to them in many different ways. 99 Android has the most support for the NDEF standard, which is defined by the <a 100 href="http://www.nfc-forum.org/home">NFC Forum</a>. 101 </p> 102 103 <p>NDEF data is encapsulated inside a message ({@link android.nfc.NdefMessage}) that contains one 104 or more records ({@link android.nfc.NdefRecord}). Each NDEF record must be well-formed according to 105 the specification of the type of record that you want to create. Android 106 also supports other types of tags that do not contain NDEF data, which you can work with by using 107 the classes in the {@link android.nfc.tech} package. To learn more 108 about these technologies, see the <a href="{@docRoot}guide/topics/connectivity/nfc/advanced-nfc.html 109 ">Advanced NFC</a> topic. Working with these other types of tags involves 110 writing your own protocol stack to communicate with the tags, so we recommend using NDEF when 111 possible for ease of development and maximum support for Android-powered devices. 112 </p> 113 114 <p class="note"><strong>Note:</strong> 115 To download complete NDEF specifications, go to the <a 116 href="http://www.nfc-forum.org/specs/spec_license">NFC Forum Specification Download</a> site and see 117 <a href="#creating-records">Creating common types of NDEF records</a> for examples of how to 118 construct NDEF records. </p> 119 120 <p>Now that you have some background in NFC tags, the following sections describe in more detail how 121 Android handles NDEF formatted tags. When an Android-powered device scans an NFC tag containing NDEF 122 formatted data, it parses the message and tries to figure out the data's MIME type or identifying 123 URI. To do this, the system reads the first {@link android.nfc.NdefRecord} inside the {@link 124 android.nfc.NdefMessage} to determine how to interpret the entire NDEF message (an NDEF message can 125 have multiple NDEF records). In a well-formed NDEF message, the first {@link android.nfc.NdefRecord} 126 contains the following fields: 127 <dl> 128 <dt><strong>3-bit TNF (Type Name Format)</strong></dt> 129 <dd>Indicates how to interpret the variable length type field. Valid values are described in 130 described in <a href="#table1">Table 1</a>.</dd> 131 132 <dt><strong>Variable length type</strong></dt> 133 <dd>Describes the type of the record. If using {@link android.nfc.NdefRecord#TNF_WELL_KNOWN}, use 134 this field to specify the Record Type Definition (RTD). Valid RTD values are described in <a 135 href="#table2">Table 2</a>.</dd> 136 137 <dt><strong>Variable length ID</strong></dt> 138 <dd>A unique identifier for the record. This field is not used often, but 139 if you need to uniquely identify a tag, you can create an ID for it.</dd> 140 141 <dt><strong>Variable length payload</strong></dt> 142 <dd>The actual data payload that you want to read or write. An NDEF 143 message can contain multiple NDEF records, so don't assume the full payload is in the first NDEF 144 record of the NDEF message.</dd> 145 146 </dl> 147 148 <p>The tag dispatch system uses the TNF and type fields to try to map a MIME type or URI to the 149 NDEF message. If successful, it encapsulates that information inside of a {@link 150 android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} intent along with the actual payload. However, there 151 are cases when the tag dispatch system cannot determine the type of data based on the first NDEF 152 record. This happens when the NDEF data cannot be mapped to a MIME type or URI, or when the 153 NFC tag does not contain NDEF data to begin with. In such cases, a {@link 154 android.nfc.Tag} object that has information about the tag's technologies and the payload are 155 encapsulated inside of a {@link android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED} intent instead.</p> 156 157 <p> 158 <a href="#table1">Table 1.</a> describes how the tag dispatch system maps TNF and type 159 fields to MIME types or URIs. It also describes which TNFs cannot be mapped to a MIME type or URI. 160 In these cases, the tag dispatch system falls back to 161 {@link android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED}. 162 163 <p>For example, if the tag dispatch system encounters a record of type {@link 164 android.nfc.NdefRecord#TNF_ABSOLUTE_URI}, it maps the variable length type field of that record 165 into a URI. The tag dispatch system encapsulates that URI in the data field of an {@link 166 android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} intent along with other information about the tag, 167 such as the payload. On the other hand, if it encounters a record of type {@link 168 android.nfc.NdefRecord#TNF_UNKNOWN}, it creates an intent that encapsulates the tag's technologies 169 instead.</p> 170 171 172 <p class="table-caption" id="table1"> 173 <strong>Table 1.</strong> Supported TNFs and their mappings</p> 174 <table id="mappings"> 175 <tr> 176 <th>Type Name Format (TNF)</th> 177 <th>Mapping</th> 178 </tr> 179 <tr> 180 <td>{@link android.nfc.NdefRecord#TNF_ABSOLUTE_URI}</td> 181 <td>URI based on the type field.</td> 182 </tr> 183 <td>{@link android.nfc.NdefRecord#TNF_EMPTY}</td> 184 <td>Falls back to {@link android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED}.</td> 185 </tr> 186 <td>{@link android.nfc.NdefRecord#TNF_EXTERNAL_TYPE}</td> 187 <td>URI based on the URN in the type field. The URN is encoded into the NDEF type field in 188 a shortened form: <code><em><domain_name>:<service_name></em></code>. 189 Android maps this to a URI in the form: 190 <code>vnd.android.nfc://ext/<em><domain_name>:<service_name></em></code>.</td> 191 </tr> 192 <td>{@link android.nfc.NdefRecord#TNF_MIME_MEDIA}</td> 193 <td>MIME type based on the type field.</td> 194 </tr> 195 <td>{@link android.nfc.NdefRecord#TNF_UNCHANGED}</td> 196 <td>Invalid in the first record, so falls back to 197 {@link android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED}.</td> 198 </tr> 199 <td>{@link android.nfc.NdefRecord#TNF_UNKNOWN}</td> 200 <td>Falls back to {@link android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED}.</td> 201 </tr> 202 <td>{@link android.nfc.NdefRecord#TNF_WELL_KNOWN}</td> 203 <td>MIME type or URI depending on the Record Type Definition (RTD), which you set in the 204 type field. See <a href="#well_known">Table 2.</a> for more information on 205 available RTDs and their mappings.</td> 206 </tr> 207 </table> 208 209 <p class="table-caption" id="table2"> 210 <strong>Table 2.</strong> Supported RTDs for TNF_WELL_KNOWN and their 211 mappings</p> 212 <table id="well-known"> 213 <tr> 214 <th>Record Type Definition (RTD)</th> 215 <th>Mapping</th> 216 </tr> 217 <tr> 218 <td>{@link android.nfc.NdefRecord#RTD_ALTERNATIVE_CARRIER}</td> 219 <td>Falls back to {@link android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED}.</td> 220 </tr> 221 <td>{@link android.nfc.NdefRecord#RTD_HANDOVER_CARRIER}</td> 222 <td>Falls back to {@link android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED}.</td> 223 </tr> 224 <td>{@link android.nfc.NdefRecord#RTD_HANDOVER_REQUEST}</td> 225 <td>Falls back to {@link android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED}.</td> 226 </tr> 227 <td>{@link android.nfc.NdefRecord#RTD_HANDOVER_SELECT}</td> 228 <td>Falls back to {@link android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED}.</td> 229 </tr> 230 <td>{@link android.nfc.NdefRecord#RTD_SMART_POSTER}</td> 231 <td>URI based on parsing the payload.</td> 232 </tr> 233 <td>{@link android.nfc.NdefRecord#RTD_TEXT}</td> 234 <td>MIME type of <code>text/plain</code>.</td> 235 </tr> 236 <td>{@link android.nfc.NdefRecord#RTD_URI}</td> 237 <td>URI based on payload.</td> 238 </tr> 239 </table> 240 241 <h3 id="dispatching">How NFC Tags are Dispatched to Applications</h3> 242 243 <p>When the tag dispatch system is done creating an intent that encapsulates the NFC tag and its 244 identifying information, it sends the intent to an interested application that 245 filters for the intent. If more than one application can handle the intent, the Activity Chooser 246 is presented so the user can select the Activity. The tag dispatch system defines three intents, 247 which are listed in order of highest to lowest priority:</p> 248 249 <ol> 250 <li> 251 {@link android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED}: This intent is used to start an 252 Activity when a tag that contains an NDEF payload is scanned and is of a recognized type. This is 253 the highest priority intent, and the tag dispatch system tries to start an Activity with this 254 intent before any other intent, whenever possible. 255 </li> 256 257 <li>{@link android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED}: If no activities register to 258 handle the {@link android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} 259 intent, the tag dispatch system tries to start an application with this intent. This 260 intent is also directly started (without starting {@link 261 android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} first) if the tag that is scanned 262 contains NDEF data that cannot be mapped to a MIME type or URI, or if the tag does not contain NDEF 263 data but is of a known tag technology. 264 </li> 265 266 <li>{@link android.nfc.NfcAdapter#ACTION_TAG_DISCOVERED}: This intent is started 267 if no activities handle the {@link 268 android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} or {@link 269 android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED} 270 intents.</li> 271 </ol> 272 273 <p>The basic way the tag dispatch system works is as follows:</p> 274 275 <ol> 276 <li>Try to start an Activity with the intent that was created by the tag dispatch system 277 when parsing the NFC tag (either 278 {@link android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} or {@link 279 android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED}).</li> 280 <li>If no activities filter for that intent, try to start an Activity with the next 281 lowest priority intent (either {@link android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED} or {@link 282 android.nfc.NfcAdapter#ACTION_TAG_DISCOVERED}) until an application filters for the 283 intent or until the tag dispatch system tries all possible intents.</li> 284 <li>If no applications filter for any of the intents, do nothing.</li> 285 </ol> 286 287 <img src="{@docRoot}images/nfc_tag_dispatch.png" /> 288 289 <p class="figure"><strong>Figure 1. </strong> Tag Dispatch System</p> 290 291 292 <p>Whenever possible, work with NDEF messages and the {@link 293 android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} intent, because it is the most specific out of 294 the three. This intent allows you to start your application at a more appropriate time than the 295 other two intents, giving the user a better experience.</p> 296 297 <h2 id="manifest">Requesting NFC Access in the Android Manifest</h2> 298 299 <p>Before you can access a device's NFC hardware and properly handle NFC intents, declare these 300 items in your <code>AndroidManifest.xml</code> file:</p> 301 302 <ul> 303 <li>The NFC <code><uses-permission></code> element to access the NFC hardware: 304 <pre> 305 <uses-permission android:name="android.permission.NFC" /> 306 </pre> 307 </li> 308 309 <li>The minimum SDK version that your application can support. API level 9 only supports 310 limited tag dispatch via {@link android.nfc.NfcAdapter#ACTION_TAG_DISCOVERED}, and only gives 311 access to NDEF messages via the {@link android.nfc.NfcAdapter#EXTRA_NDEF_MESSAGES} extra. No 312 other tag properties or I/O operations are accessible. API level 10 313 includes comprehensive reader/writer support as well as foreground NDEF pushing, and API level 314 14 provides an easier way to push NDEF messages to other devices with Android Beam and extra 315 convenience methods to create NDEF records. 316 <pre class="pretty-print"> 317 <uses-sdk android:minSdkVersion="10"/> 318 </pre> 319 </li> 320 321 <li>The <code>uses-feature</code> element so that your application shows up in Google Play 322 only for devices that have NFC hardware: 323 <pre> 324 <uses-feature android:name="android.hardware.nfc" android:required="true" /> 325 </pre> 326 <p>If your application uses NFC functionality, but that functionality is not crucial to your 327 application, you can omit the <code>uses-feature</code> element and check for NFC avalailbility at 328 runtime by checking to see if {@link android.nfc.NfcAdapter#getDefaultAdapter getDefaultAdapter()} 329 is <code>null</code>.</p> 330 </li> 331 </ul> 332 333 <h2 id="filtering-intents">Filtering for NFC Intents</h2> 334 335 <p>To start your application when an NFC tag that you want to handle is scanned, your application 336 can filter for one, two, or all three of the NFC intents in the Android manifest. However, you 337 usually want to filter for the {@link android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} intent for the 338 most control of when your application starts. The {@link 339 android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED} intent is a fallback for {@link 340 android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} when no applications filter for 341 {@link android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} or for when the payload is not 342 NDEF. Filtering for {@link android.nfc.NfcAdapter#ACTION_TAG_DISCOVERED} is usually too general of a 343 category to filter on. Many applications will filter for {@link 344 android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} or {@link 345 android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED} before {@link 346 android.nfc.NfcAdapter#ACTION_TAG_DISCOVERED}, so your application has a low probability of 347 starting. {@link android.nfc.NfcAdapter#ACTION_TAG_DISCOVERED} is only available as a last resort 348 for applications to filter for in the cases where no other applications are installed to handle the 349 {@link android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} or {@link 350 android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED}intent.</p> 351 352 <p>Because NFC tag deployments vary and are many times not under your control, this is not always 353 possible, which is why you can fallback to the other two intents when necessary. When you have 354 control over the types of tags and data written, it is recommended that you use NDEF to format your 355 tags. The following sections describe how to filter for each type of intent.</p> 356 357 358 <h3 id="ndef-disc">ACTION_NDEF_DISCOVERED</h3> 359 <p> 360 To filter for {@link android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} intents, declare the 361 intent filter along with the type of data that you want to filter for. The 362 following example filters for {@link android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} 363 intents with a MIME type of <code>text/plain</code>: 364 </p> 365 <pre> 366 <intent-filter> 367 <action android:name="android.nfc.action.NDEF_DISCOVERED"/> 368 <category android:name="android.intent.category.DEFAULT"/> 369 <data android:mimeType="text/plain" /> 370 </intent-filter> 371 </pre> 372 <p>The following example filters for a URI in the form of 373 <code>http://developer.android.com/index.html</code>. 374 <pre> 375 <intent-filter> 376 <action android:name="android.nfc.action.NDEF_DISCOVERED"/> 377 <category android:name="android.intent.category.DEFAULT"/> 378 <data android:scheme="http" 379 android:host="developer.android.com" 380 android:pathPrefix="/index.html" /> 381 </intent-filter> 382 </pre> 383 384 385 <h3 id="tech-disc">ACTION_TECH_DISCOVERED</h3> 386 387 <p>If your activity filters for the {@link android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED} intent, 388 you must create an XML resource file that specifies the technologies that your activity supports 389 within a <code>tech-list</code> set. Your activity is 390 considered a match if a <code>tech-list</code> set is a subset of the technologies that are 391 supported by the tag, which you can obtain by calling {@link android.nfc.Tag#getTechList 392 getTechList()}.</p> 393 394 <p>For example, if the tag that is scanned supports MifareClassic, NdefFormatable, and NfcA, your 395 <code>tech-list</code> set must specify all three, two, or one of the technologies (and nothing 396 else) in order for your activity to be matched.</p> 397 398 <p>The following sample defines all of the technologies. You can remove the ones that you do not 399 need. Save this file (you can name it anything you wish) in the 400 <code><project-root>/res/xml</code> folder.</p> 401 <pre> 402 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> 403 <tech-list> 404 <tech>android.nfc.tech.IsoDep</tech> 405 <tech>android.nfc.tech.NfcA</tech> 406 <tech>android.nfc.tech.NfcB</tech> 407 <tech>android.nfc.tech.NfcF</tech> 408 <tech>android.nfc.tech.NfcV</tech> 409 <tech>android.nfc.tech.Ndef</tech> 410 <tech>android.nfc.tech.NdefFormatable</tech> 411 <tech>android.nfc.tech.MifareClassic</tech> 412 <tech>android.nfc.tech.MifareUltralight</tech> 413 </tech-list> 414 </resources> 415 </pre> 416 417 <p>You can also specify multiple <code>tech-list</code> sets. Each of the <code>tech-list</code> 418 sets is considered independently, and your activity is considered a match if any single 419 <code>tech-list</code> set is a subset of the technologies that are returned by {@link 420 android.nfc.Tag#getTechList getTechList()}. This provides <code>AND</code> and <code>OR</code> 421 semantics for matching technologies. The following example matches tags that can support the 422 NfcA and Ndef technologies or can support the NfcB and Ndef technologies:</p> 423 <pre> 424 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> 425 <tech-list> 426 <tech>android.nfc.tech.NfcA</tech> 427 <tech>android.nfc.tech.Ndef</tech> 428 </tech-list> 429 </resources> 430 431 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> 432 <tech-list> 433 <tech>android.nfc.tech.NfcB</tech> 434 <tech>android.nfc.tech.Ndef</tech> 435 </tech-list> 436 </resources> 437 </pre> 438 439 <p>In your <code>AndroidManifest.xml</code> file, specify the resource file that you just created 440 in the <code><meta-data></code> element inside the <code><activity></code> 441 element like in the following example:</p> 442 <pre> 443 <activity> 444 ... 445 <intent-filter> 446 <action android:name="android.nfc.action.TECH_DISCOVERED"/> 447 </intent-filter> 448 449 <meta-data android:name="android.nfc.action.TECH_DISCOVERED" 450 android:resource="@xml/nfc_tech_filter" /> 451 ... 452 </activity> 453 </pre> 454 455 <p>For more information about working with tag technologies and the {@link 456 android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED} intent, see <a 457 href="{@docRoot}guide/topics/connectivity/nfc/advanced-nfc.html#tag-tech">Working with Supported Tag 458 Technologies</a> in the Advanced NFC document.</p> 459 <h3 id="tag-disc">ACTION_TAG_DISCOVERED</h3> 460 <p>To filter for {@link android.nfc.NfcAdapter#ACTION_TAG_DISCOVERED} use the following intent 461 filter:</p> 462 463 464 <pre><intent-filter> 465 <action android:name="android.nfc.action.TAG_DISCOVERED"/> 466 </intent-filter> 467 </pre> 468 469 470 471 <h3 id="obtain-info">Obtaining information from intents</h3> 472 473 <p>If an activity starts because of an NFC intent, you can obtain information about the scanned NFC 474 tag from the intent. Intents can contain the following extras depending on the tag that was scanned: 475 476 <ul> 477 <li>{@link android.nfc.NfcAdapter#EXTRA_TAG} (required): A {@link android.nfc.Tag} object 478 representing the scanned tag.</li> 479 <li>{@link android.nfc.NfcAdapter#EXTRA_NDEF_MESSAGES} (optional): An array of NDEF messages 480 parsed from the tag. This extra is mandatory on 481 {@link android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} intents.</li> 482 <li>{@link android.nfc.NfcAdapter#EXTRA_ID} (optional): The low-level ID of the tag.</li></ul> 483 484 <p>To obtain these extras, check to see if your activity was launched with one of 485 the NFC intents to ensure that a tag was scanned, and then obtain the extras out of the 486 intent. The following example checks for the {@link android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} 487 intent and gets the NDEF messages from an intent extra.</p> 488 489 <pre> 490 public void onResume() { 491 super.onResume(); 492 ... 493 if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) { 494 Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES); 495 if (rawMsgs != null) { 496 msgs = new NdefMessage[rawMsgs.length]; 497 for (int i = 0; i < rawMsgs.length; i++) { 498 msgs[i] = (NdefMessage) rawMsgs[i]; 499 } 500 } 501 } 502 //process the msgs array 503 } 504 </pre> 505 506 <p>Alternatively, you can obtain a {@link android.nfc.Tag} object from the intent, which will 507 contain the payload and allow you to enumerate the tag's technologies:</p> 508 509 <pre>Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);</pre> 510 511 512 <h2 id="creating-records">Creating Common Types of NDEF Records</h2> 513 <p>This section describes how to create common types of NDEF records to help you when writing to 514 NFC tags or sending data with Android Beam. Starting with Android 4.0 (API level 14), the 515 {@link android.nfc.NdefRecord#createUri createUri()} method is available to help you create 516 URI records automatically. Starting in Android 4.1 (API level 16), 517 {@link android.nfc.NdefRecord#createExternal createExternal()} 518 and {@link android.nfc.NdefRecord#createMime createMime()} are available to help you create 519 MIME and external type NDEF records. Use these helper methods whenever possible to avoid mistakes 520 when manually creating NDEF records.</p> 521 522 <p> 523 This section also describes how to create the corresponding 524 intent filter for the record. All of these NDEF record examples should be in the first NDEF 525 record of the NDEF message that you are writing to a tag or beaming.</p> 526 527 <h3 id="abs-uri">TNF_ABSOLUTE_URI</h3> 528 <p class="note"><strong>Note:</strong> We recommend that you use the 529 <a href="#well-known-uri"><code>RTD_URI</code></a> type instead 530 of {@link android.nfc.NdefRecord#TNF_ABSOLUTE_URI}, because it is more efficient.</p> 531 532 <p>You can create a {@link android.nfc.NdefRecord#TNF_ABSOLUTE_URI} NDEF record in the following way 533 :</p> 534 535 <pre> 536 NdefRecord uriRecord = new NdefRecord( 537 NdefRecord.TNF_ABSOLUTE_URI , 538 "http://developer.android.com/index.html".getBytes(Charset.forName("US-ASCII")), 539 new byte[0], new byte[0]); 540 </pre> 541 542 <p>The intent filter for the previous NDEF record would look like this:</p> 543 <pre> 544 <intent-filter> 545 <action android:name="android.nfc.action.NDEF_DISCOVERED" /> 546 <category android:name="android.intent.category.DEFAULT" /> 547 <data android:scheme="http" 548 android:host="developer.android.com" 549 android:pathPrefix="/index.html" /> 550 </intent-filter> 551 </pre> 552 553 <h3 id="mime">TNF_MIME_MEDIA</h3> 554 <p>You can create a {@link android.nfc.NdefRecord#TNF_MIME_MEDIA} NDEF record in the following ways: 555 </p> 556 557 <p>Using the {@link android.nfc.NdefRecord#createMime createMime()} method:</p> 558 <pre> 559 NdefRecord mimeRecord = NdefRecord.createMime("application/vnd.com.example.android.beam", 560 "Beam me up, Android".getBytes(Charset.forName("US-ASCII"))); 561 </pre> 562 563 <p>Creating the {@link android.nfc.NdefRecord} manually:</p> 564 <pre> 565 NdefRecord mimeRecord = new NdefRecord( 566 NdefRecord.TNF_MIME_MEDIA , 567 "application/vnd.com.example.android.beam".getBytes(Charset.forName("US-ASCII")), 568 new byte[0], "Beam me up, Android!".getBytes(Charset.forName("US-ASCII"))); 569 </pre> 570 571 <p>The intent filter for the previous NDEF records would look like this:</p> 572 <pre> 573 <intent-filter> 574 <action android:name="android.nfc.action.NDEF_DISCOVERED" /> 575 <category android:name="android.intent.category.DEFAULT" /> 576 <data android:mimeType="application/vnd.com.example.android.beam" /> 577 </intent-filter> 578 </pre> 579 580 <h3 id="well-known-text">TNF_WELL_KNOWN with RTD_TEXT</h3> 581 582 <p>You can create a {@link android.nfc.NdefRecord#TNF_WELL_KNOWN} NDEF record in the following way: 583 </p> 584 <pre> 585 public NdefRecord createTextRecord(String payload, Locale locale, boolean encodeInUtf8) { 586 byte[] langBytes = locale.getLanguage().getBytes(Charset.forName("US-ASCII")); 587 Charset utfEncoding = encodeInUtf8 ? Charset.forName("UTF-8") : Charset.forName("UTF-16"); 588 byte[] textBytes = payload.getBytes(utfEncoding); 589 int utfBit = encodeInUtf8 ? 0 : (1 << 7); 590 char status = (char) (utfBit + langBytes.length); 591 byte[] data = new byte[1 + langBytes.length + textBytes.length]; 592 data[0] = (byte) status; 593 System.arraycopy(langBytes, 0, data, 1, langBytes.length); 594 System.arraycopy(textBytes, 0, data, 1 + langBytes.length, textBytes.length); 595 NdefRecord record = new NdefRecord(NdefRecord.TNF_WELL_KNOWN, 596 NdefRecord.RTD_TEXT, new byte[0], data); 597 return record; 598 } 599 </pre> 600 601 <p>the intent filter would look like this:</p> 602 <pre> 603 <intent-filter> 604 <action android:name="android.nfc.action.NDEF_DISCOVERED" /> 605 <category android:name="android.intent.category.DEFAULT" /> 606 <data android:mimeType="text/plain" /> 607 </intent-filter> 608 </pre> 609 610 611 <h3 id="well-known-uri">TNF_WELL_KNOWN with RTD_URI</h3> 612 613 <p>You can create a {@link android.nfc.NdefRecord#TNF_WELL_KNOWN} NDEF record in the following ways: 614 </p> 615 616 <p>Using the {@link android.nfc.NdefRecord#createUri(String)} method:</p> 617 <pre> 618 NdefRecord rtdUriRecord1 = NdefRecord.createUri("http://example.com"); 619 </pre> 620 621 <p>Using the {@link android.nfc.NdefRecord#createUri(Uri)} method:</p> 622 <pre> 623 Uri uri = new Uri("http://example.com"); 624 NdefRecord rtdUriRecord2 = NdefRecord.createUri(uri); 625 </pre> 626 627 <p>Creating the {@link android.nfc.NdefRecord} manually:</p> 628 <pre> 629 byte[] uriField = "example.com".getBytes(Charset.forName("US-ASCII")); 630 byte[] payload = new byte[uriField.length + 1]; //add 1 for the URI Prefix 631 byte payload[0] = 0x01; //prefixes http://www. to the URI 632 System.arraycopy(uriField, 0, payload, 1, uriField.length); //appends URI to payload 633 NdefRecord rtdUriRecord = new NdefRecord( 634 NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_URI, new byte[0], payload); 635 </pre> 636 637 <p>The intent filter for the previous NDEF records would look like this:</p> 638 639 <pre> 640 <intent-filter> 641 <action android:name="android.nfc.action.NDEF_DISCOVERED" /> 642 <category android:name="android.intent.category.DEFAULT" /> 643 <data android:scheme="http" 644 android:host="example.com" 645 android:pathPrefix="" /> 646 </intent-filter> 647 </pre> 648 649 <h3 id="ext-type">TNF_EXTERNAL_TYPE</h3> 650 <p>You can create a {@link android.nfc.NdefRecord#TNF_EXTERNAL_TYPE} NDEF record in the following 651 ways:</p> 652 653 <p>Using the {@link android.nfc.NdefRecord#createExternal createExternal()} method: 654 <pre> 655 byte[] payload; //assign to your data 656 String domain = "com.example"; //usually your app's package name 657 String type = "externalType"; 658 NdefRecord extRecord = NdefRecord.createExternal(domain, type, payload); 659 </pre> 660 661 <p>Creating the {@link android.nfc.NdefRecord} manually:</p> 662 <pre> 663 byte[] payload; 664 ... 665 NdefRecord extRecord = new NdefRecord( 666 NdefRecord.TNF_EXTERNAL_TYPE, "com.example:externalType", new byte[0], payload); 667 </pre> 668 669 <p>The intent filter for the previous NDEF records would look like this:</p> 670 <pre> 671 <intent-filter> 672 <action android:name="android.nfc.action.NDEF_DISCOVERED" /> 673 <category android:name="android.intent.category.DEFAULT" /> 674 <data android:scheme="vnd.android.nfc" 675 android:host="ext" 676 android:pathPrefix="/com.example:externalType"/> 677 </intent-filter> 678 </pre> 679 680 681 <p>Use TNF_EXTERNAL_TYPE for more generic NFC tag deployments to better support both 682 Android-powered and non-Android-powered devices.</p> 683 684 <p class="note"><strong>Note</strong>: URNs for {@link 685 android.nfc.NdefRecord#TNF_EXTERNAL_TYPE} have a canonical format of: 686 <code>urn:nfc:ext:example.com:externalType</code>, however the NFC Forum RTD specification 687 declares that the <code>urn:nfc:ext:</code> portion of the URN must be ommitted from the 688 NDEF record. So all you need to provide is the domain (<code>example.com</code> in the example) 689 and type (<code>externalType</code> in the example) separated by a colon. 690 When dispatching TNF_EXTERNAL_TYPE, Android converts the <code>urn:nfc:ext:example.com:externalType 691 </code> URN to a <code>vnd.android.nfc://ext/example.com:externalType</code> URI, which is what the 692 intent filter in the example declares.</p> 693 694 <h3 id="aar">Android Application Records</h3> 695 696 <p> 697 Introduced in Android 4.0 (API level 14), an Android Application Record (AAR) provides a stronger 698 certainty that your application is started when an NFC tag is scanned. An AAR has the package name 699 of an application embedded inside an NDEF record. You can add an AAR to any NDEF record of your NDEF 700 message, because Android searches the entire NDEF message for AARs. If it finds an AAR, it starts 701 the application based on the package name inside the AAR. If the application is not present on the 702 device, Google Play is launched to download the application.</p> 703 704 <p>AARs are useful if you want to prevent other applications from filtering for the same intent and 705 potentially handling specific tags that you have deployed. AARs are only supported at the 706 application level, because of the package name constraint, and not at the Activity level as with 707 intent filtering. If you want to handle an intent at the Activity level, <a 708 href="#filtering-intents">use intent filters</a>. 709 </p> 710 711 712 713 <p>If a tag contains an AAR, the tag dispatch system dispatches in the following manner:</p> 714 <ol> 715 <li>Try to start an Activity using an intent filter as normal. If the Activity that matches 716 the intent also matches the AAR, start the Activity.</li> 717 <li>If the Activity that filters for the intent does not match the 718 AAR, if multiple Activities can handle the intent, or if no Activity handles the intent, start the 719 application specified by the AAR.</li> 720 <li>If no application can start with the AAR, go to Google Play to download the 721 application based on the AAR.</li> 722 </ol> 723 724 </p> 725 726 <p class="note"><strong>Note:</strong> You can override AARs and the intent dispatch system with the 727 <ahref="{@docRoot}guide/topics/connectivity/nfc/advanced-nfc.html#foreground-dispatch">foreground 728 dispatch system</a>, which allows a foreground activity to have priority when an NFC tag is 729 discovered. With this method, the activity must be in the foreground to override AARs and the 730 intent dispatch system.</p> 731 732 <p>If you still want to filter for scanned tags that do not contain an AAR, you can declare 733 intent filters as normal. This is useful if your application is interested in other tags 734 that do not contain an AAR. For example, maybe you want to guarantee that your application handles 735 proprietary tags that you deploy as well as general tags deployed by third parties. Keep in mind 736 that AARs are specific to Android 4.0 devices or later, so when deploying tags, you most likely want 737 to use a combination of AARs and MIME types/URIs to support the widest range of devices. In 738 addition, when you deploy NFC tags, think about how you want to write your NFC tags to enable 739 support for the most devices (Android-powered and other devices). You can do this by 740 defining a relatively unique MIME type or URI to make it easier for applications to distinguish. 741 </p> 742 743 <p>Android provides a simple API to create an AAR, 744 {@link android.nfc.NdefRecord#createApplicationRecord createApplicationRecord()}. All you need to 745 do is embed the AAR anywhere in your {@link android.nfc.NdefMessage}. You do not want 746 to use the first record of your {@link android.nfc.NdefMessage}, unless the AAR is the only 747 record in the {@link android.nfc.NdefMessage}. This is because the Android 748 system checks the first record of an {@link android.nfc.NdefMessage} to determine the MIME type or 749 URI of the tag, which is used to create an intent for applications to filter. The following code 750 shows you how to create an AAR:</p> 751 752 <pre> 753 NdefMessage msg = new NdefMessage( 754 new NdefRecord[] { 755 ..., 756 NdefRecord.createApplicationRecord("com.example.android.beam")} 757 </pre> 758 759 760 <h2 id="p2p">Beaming NDEF Messages to Other Devices</h2> 761 762 <p>Android Beam allows simple peer-to-peer data exchange between two Android-powered devices. The 763 application that wants to beam data to another device must be in the foreground and the device 764 receiving the data must not be locked. When the beaming device comes in close enough contact with a 765 receiving device, the beaming device displays the "Touch to Beam" UI. The user can then choose 766 whether or not to beam the message to the receiving device.</p> 767 768 <p class="note"><strong>Note:</strong> Foreground NDEF pushing was available at API level 10, 769 which provides similar functionality to Android Beam. These APIs have since been deprecated, but 770 are available to support older devices. See {@link android.nfc.NfcAdapter#enableForegroundNdefPush 771 enableForegroundNdefPush()} for more information.</p> 772 773 <p>You can enable Android Beam for your application by calling one of the two methods:</p> 774 <ul> 775 <li>{@link android.nfc.NfcAdapter#setNdefPushMessage setNdefPushMessage()}: Accepts an 776 {@link android.nfc.NdefMessage} to set as the message to beam. Automatically beams the message 777 when two devices are in close enough proximity.</li> 778 <li>{@link android.nfc.NfcAdapter#setNdefPushMessageCallback setNdefPushMessageCallback()}: 779 Accepts a callback that contains a 780 {@link android.nfc.NfcAdapter.CreateNdefMessageCallback#createNdefMessage createNdefMessage()} 781 which is called when a device is in range to beam data to. The callback lets you create 782 the NDEF message only when necessary.</li> 783 </ul> 784 785 <p>An activity can only push one NDEF message at a time, so {@link 786 android.nfc.NfcAdapter#setNdefPushMessageCallback setNdefPushMessageCallback()} takes precedence 787 over {@link android.nfc.NfcAdapter#setNdefPushMessage setNdefPushMessage()} if both are set. To use 788 Android Beam, the following general guidelines must be met: 789 </p> 790 791 <ul> 792 <li>The activity that is beaming the data must be in the foreground. Both devices must have 793 their screens unlocked.</li> 794 795 <li>You must encapsulate the data that you are beaming in an {@link android.nfc.NdefMessage} 796 object.</li> 797 798 <li>The NFC device that is receiving the beamed data must support the 799 <code>com.android.npp</code> NDEF push protocol or NFC Forum's SNEP (Simple NDEF Exchange 800 Protocol). The <code>com.android.npp</code> protocol is required for devices on API level 9 (Android 801 2.3) to API level 13 (Android 3.2). <code>com.android.npp</code> and SNEP are both required on 802 API level 14 (Android 4.0) and later.</li> 803 </li> 804 </ul> 805 806 <p class="note"><strong>Note:</strong> If your activity enables Android Beam and is 807 in the foreground, the standard intent dispatch system is disabled. However, if your activity also 808 enables <a href="{@docRoot}guide/topics/connectivity/nfc/advanced-nfc.html#foreground-dispatch"> 809 foreground dispatching</a>, then it can still scan tags that match the intent filters set in the 810 foreground dispatching.</p> 811 812 <p>To enable Android Beam:</p> 813 814 <ol> 815 <li>Create an {@link android.nfc.NdefMessage} that contains the {@link android.nfc.NdefRecord}s 816 that you want to push onto the other device.</li> 817 818 <li>Call {@link 819 android.nfc.NfcAdapter#setNdefPushMessage setNdefPushMessage()} with a {@link 820 android.nfc.NdefMessage} or call {@link 821 android.nfc.NfcAdapter#setNdefPushMessageCallback setNdefPushMessageCallback} passing in a {@link 822 android.nfc.NfcAdapter.CreateNdefMessageCallback} object in the <code>onCreate()</code> method of 823 your activity. These methods require at least one activity that you want to enable with Android 824 Beam, along with an optional list of other activities to activate. 825 826 <p>In general, you normally use {@link 827 android.nfc.NfcAdapter#setNdefPushMessage setNdefPushMessage()} if your Activity only needs to 828 push the same NDEF message at all times, when two devices are in range to communicate. You use 829 {@link android.nfc.NfcAdapter#setNdefPushMessageCallback setNdefPushMessageCallback} when your 830 application cares about the current context of the application and wants to push an NDEF message 831 depending on what the user is doing in your application.</p> 832 </li> 833 </ol> 834 835 <p>The following sample shows how a simple activity calls {@link 836 android.nfc.NfcAdapter.CreateNdefMessageCallback} in the <code>onCreate()</code> method of an 837 activity (see <a href="{@docRoot}resources/samples/AndroidBeamDemo/index.html">AndroidBeamDemo</a> 838 for the complete sample). This example also has methods to help you create a MIME record:</p> 839 840 <pre id="code-example"> 841 package com.example.android.beam; 842 843 import android.app.Activity; 844 import android.content.Intent; 845 import android.nfc.NdefMessage; 846 import android.nfc.NdefRecord; 847 import android.nfc.NfcAdapter; 848 import android.nfc.NfcAdapter.CreateNdefMessageCallback; 849 import android.nfc.NfcEvent; 850 import android.os.Bundle; 851 import android.os.Parcelable; 852 import android.widget.TextView; 853 import android.widget.Toast; 854 import java.nio.charset.Charset; 855 856 857 public class Beam extends Activity implements CreateNdefMessageCallback { 858 NfcAdapter mNfcAdapter; 859 TextView textView; 860 861 @Override 862 public void onCreate(Bundle savedInstanceState) { 863 super.onCreate(savedInstanceState); 864 setContentView(R.layout.main); 865 TextView textView = (TextView) findViewById(R.id.textView); 866 // Check for available NFC Adapter 867 mNfcAdapter = NfcAdapter.getDefaultAdapter(this); 868 if (mNfcAdapter == null) { 869 Toast.makeText(this, "NFC is not available", Toast.LENGTH_LONG).show(); 870 finish(); 871 return; 872 } 873 // Register callback 874 mNfcAdapter.setNdefPushMessageCallback(this, this); 875 } 876 877 @Override 878 public NdefMessage createNdefMessage(NfcEvent event) { 879 String text = ("Beam me up, Android!\n\n" + 880 "Beam Time: " + System.currentTimeMillis()); 881 NdefMessage msg = new NdefMessage( 882 new NdefRecord[] { createMime( 883 "application/vnd.com.example.android.beam", text.getBytes()) 884 /** 885 * The Android Application Record (AAR) is commented out. When a device 886 * receives a push with an AAR in it, the application specified in the AAR 887 * is guaranteed to run. The AAR overrides the tag dispatch system. 888 * You can add it back in to guarantee that this 889 * activity starts when receiving a beamed message. For now, this code 890 * uses the tag dispatch system. 891 */ 892 //,NdefRecord.createApplicationRecord("com.example.android.beam") 893 }); 894 return msg; 895 } 896 897 @Override 898 public void onResume() { 899 super.onResume(); 900 // Check to see that the Activity started due to an Android Beam 901 if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) { 902 processIntent(getIntent()); 903 } 904 } 905 906 @Override 907 public void onNewIntent(Intent intent) { 908 // onResume gets called after this to handle the intent 909 setIntent(intent); 910 } 911 912 /** 913 * Parses the NDEF Message from the intent and prints to the TextView 914 */ 915 void processIntent(Intent intent) { 916 textView = (TextView) findViewById(R.id.textView); 917 Parcelable[] rawMsgs = intent.getParcelableArrayExtra( 918 NfcAdapter.EXTRA_NDEF_MESSAGES); 919 // only one message sent during the beam 920 NdefMessage msg = (NdefMessage) rawMsgs[0]; 921 // record 0 contains the MIME type, record 1 is the AAR, if present 922 textView.setText(new String(msg.getRecords()[0].getPayload())); 923 } 924 } 925 </pre> 926 927 <p>Note that this code comments out an AAR, which you can remove. If you enable the AAR, the 928 application specified in the AAR always receives the Android Beam message. If the application is not 929 present, Google Play is started to download the application. Therefore, the following intent 930 filter is not technically necessary for Android 4.0 devices or later if the AAR is used: 931 </p> 932 933 <pre> 934 <intent-filter> 935 <action android:name="android.nfc.action.NDEF_DISCOVERED"/> 936 <category android:name="android.intent.category.DEFAULT"/> 937 <data android:mimeType="application/vnd.com.example.android.beam"/> 938 </intent-filter> 939 </pre> 940 <p>With this intent filter, the <code>com.example.android.beam</code> application now can be started 941 when it scans an NFC tag or receives an Android Beam with an AAR of 942 type <code>com.example.android.beam</code>, or when an NDEF formatted message contains a MIME record 943 of type <code>application/vnd.com.example.android.beam</code>.</p> 944 945 <p>Even though AARs guarantee an application is started or downloaded, intent filters are 946 recommended, because they let you start an Activity of your choice in your 947 application instead of always starting the main Activity within the package specified by an AAR. 948 AARs do not have Activity level granularity. Also, because some Android-powered devices do not 949 support AARs, you should also embed identifying information in the first NDEF record of your NDEF 950 messages and filter for that as well, just in case. See <a href="#creating-records">Creating Common 951 Types of NDEF records</a> for more information on how to create records. 952 </p> 953