nfc.jd revision 1f415fa2eaa3819e99021dd54ed62aabc6689ea0
1page.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
40receive NFC data in the form of NDEF messages and describes the Android framework APIs that support
41these features. For more advanced topics, including a discussion of working with non-NDEF data,
42see <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
50Beam&trade;</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
55system</a>, which analyzes discovered NFC tags, appropriately categorizes the data, and starts
56an application that is interested in the categorized data. An application that wants to handle the
57scanned NFC tag can <a href="#filtering-intents">declare an intent filter</a> and
58request to handle the data.</p>
59
60<p>The Android Beam&trade; feature allows a device to push an NDEF message onto
61another device by physically tapping the devices together. This interaction provides an easier way
62to send data than other wireless technologies like Bluetooth, because with NFC, no manual device
63discovery or pairing is required. The connection is automatically started when two devices come
64into range. Android Beam is available through a set of NFC APIs, so any application can transmit
65information between devices. For example, the Contacts, Browser, and YouTube applications use
66Android 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
73is unlocked, unless NFC is disabled in the device's Settings menu.
74When an Android-powered device discovers an NFC tag, the desired behavior
75is to have the most appropriate activity handle the intent without asking the user what application
76to use. Because devices scan NFC tags at a very short range, it is likely that making users manually
77select an activity would force them to move the device away from the tag and break the connection.
78You should develop your activity to only handle the NFC tags that your activity cares about to
79prevent 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
82NFC tags, parses them, and tries to locate applications that are interested in the scanned data. It
83does 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
96types of NFC tags, how the tag dispatch system parses NFC tags, and the special work that the tag
97dispatch system does when it detects an NDEF message. NFC tags come in a
98wide array of technologies and can also have data written to them in many different ways.
99Android has the most support for the NDEF standard, which is defined by the <a
100href="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
104or more records ({@link android.nfc.NdefRecord}). Each NDEF record must be well-formed according to
105the specification of the type of record that you want to create. Android
106also supports other types of tags that do not contain NDEF data, which you can work with by using
107the classes in the {@link android.nfc.tech} package. To learn more
108about these technologies, see the <a href="{@docRoot}guide/topics/connectivity/nfc/advanced-nfc.html">Advanced
109NFC</a> topic. Working with these other types of tags involves
110writing your own protocol stack to communicate with the tags, so we recommend using NDEF when
111possible for ease of development and maximum support for Android-powered devices.
112</p>
113
114<p class="note"><strong>Note:</strong>
115To download complete NDEF specifications, go to the <a
116href="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
118construct NDEF records. </p>
119
120<p>Now that you have some background in NFC tags, the following sections describe in more detail how
121Android handles NDEF formatted tags. When an Android-powered device scans an NFC tag containing NDEF
122formatted data, it parses the message and tries to figure out the data's MIME type or identifying
123URI. To do this, the system reads the first {@link android.nfc.NdefRecord} inside the {@link
124android.nfc.NdefMessage} to determine how to interpret the entire NDEF message (an NDEF message can
125have multiple NDEF records). In a well-formed NDEF message, the first {@link android.nfc.NdefRecord}
126contains 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
130described 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
134this field to specify the Record Type Definition (RTD). Valid RTD values are described in <a
135href="#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
139if 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
143message can contain multiple NDEF records, so don't assume the full payload is in the first NDEF
144record 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
149NDEF message. If successful, it encapsulates that information inside of a {@link
150android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} intent along with the actual payload. However, there
151are cases when the tag dispatch system cannot determine the type of data based on the first NDEF
152record. This happens when the NDEF data cannot be mapped to a MIME type or URI, or when the
153NFC tag does not contain NDEF data to begin with. In such cases, a {@link
154android.nfc.Tag} object that has information about the tag's technologies and the payload are
155encapsulated 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
159fields to MIME types or URIs. It also describes which TNFs cannot be mapped to a MIME type or URI.
160In 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
164android.nfc.NdefRecord#TNF_ABSOLUTE_URI}, it maps the variable length type field of that record
165into a URI. The tag dispatch system encapsulates that URI in the data field of an {@link
166android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} intent along with other information about the tag,
167such as the payload. On the other hand, if it encounters a record of type {@link
168android.nfc.NdefRecord#TNF_UNKNOWN}, it creates an intent that encapsulates the tag's technologies
169instead.</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>&lt;domain_name&gt;:&lt;service_name&gt;</em></code>.
189        Android maps this to a URI in the form:
190        <code>vnd.android.nfc://ext/<em>&lt;domain_name&gt;:&lt;service_name&gt;</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
204type field. See <a  href="#well_known">Table 2.</a> for more information on
205available 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
211mappings</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
244identifying information, it sends the intent to an interested application that
245filters for the intent. If more than one application can handle the intent, the Activity Chooser
246is presented so the user can select the Activity. The tag dispatch system defines three intents,
247which 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
252Activity when a tag that contains an NDEF payload is scanned and is of a recognized type. This is
253the highest priority intent, and the tag dispatch system tries to start an Activity with this
254intent before any other intent, whenever possible.
255  </li>
256
257    <li>{@link android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED}: If no activities register to
258handle the {@link android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED}
259intent, the tag dispatch system tries to start an application with this intent. This
260intent is also directly started (without starting {@link
261android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} first) if the tag that is scanned
262contains NDEF data that cannot be mapped to a MIME type or URI, or if the tag does not contain NDEF
263data 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
268android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} or {@link
269android.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
277when parsing the NFC tag (either
278{@link android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} or {@link
279android.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
282android.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
293android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} intent, because it is the most specific out of
294the three. This intent allows you to start your application at a more appropriate time than the
295other 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>&lt;uses-permission&gt;</code> element to access the NFC hardware:
304      <pre>
305&lt;uses-permission android:name="android.permission.NFC" /&gt;
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&lt;uses-sdk android:minSdkVersion="10"/&gt;
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&lt;uses-feature android:name="android.hardware.nfc" android:required="true" /&gt;
325</pre>
326<p>If your application uses NFC functionality, but that functionality is not crucial to your
327application, you can omit the <code>uses-feature</code> element and check for NFC avalailbility at
328runtime by checking to see if {@link android.nfc.NfcAdapter#getDefaultAdapter getDefaultAdapter()}
329is <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
336can filter for one, two, or all three of the NFC intents in the Android manifest. However, you
337usually want to filter for the {@link android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} intent for the
338most control of when your application starts. The {@link
339android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED} intent is a fallback for {@link
340android.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
342NDEF. Filtering for {@link android.nfc.NfcAdapter#ACTION_TAG_DISCOVERED} is usually too general of a
343category to filter on.  Many applications will filter for {@link
344android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} or {@link
345android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED} before {@link
346android.nfc.NfcAdapter#ACTION_TAG_DISCOVERED}, so your application has a low probability of
347starting. {@link android.nfc.NfcAdapter#ACTION_TAG_DISCOVERED} is only available as a last resort
348for 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
350android.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
353possible, which is why you can fallback to the other two intents when necessary. When you have
354control over the types of tags and data written, it is recommended that you use NDEF to format your
355tags. 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>
360To filter for {@link android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} intents, declare the
361intent filter along with the type of data that you want to filter for. The
362following example filters for {@link android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED}
363intents with a MIME type of <code>text/plain</code>:
364</p>
365<pre>
366&lt;intent-filter&gt;
367    &lt;action android:name="android.nfc.action.NDEF_DISCOVERED"/&gt;
368    &lt;category android:name="android.intent.category.DEFAULT"/&gt;
369    &lt;data android:mimeType="text/plain" /&gt;
370&lt;/intent-filter&gt;
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&lt;intent-filter&gt;
376    &lt;action android:name="android.nfc.action.NDEF_DISCOVERED"/&gt;
377    &lt;category android:name="android.intent.category.DEFAULT"/&gt;
378   &lt;data android:scheme="http"
379              android:host="developer.android.com"
380              android:pathPrefix="/index.html" />
381&lt;/intent-filter&gt;
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,
388you must create an XML resource file that specifies the technologies that your activity supports
389within 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>&lt;project-root&gt;/res/xml</code> folder.</p>
401  <pre>
402&lt;resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"&gt;
403    &lt;tech-list&gt;
404        &lt;tech&gt;android.nfc.tech.IsoDep&lt;/tech&gt;
405        &lt;tech&gt;android.nfc.tech.NfcA&lt;/tech&gt;
406        &lt;tech&gt;android.nfc.tech.NfcB&lt;/tech&gt;
407        &lt;tech&gt;android.nfc.tech.NfcF&lt;/tech&gt;
408        &lt;tech&gt;android.nfc.tech.NfcV&lt;/tech&gt;
409        &lt;tech&gt;android.nfc.tech.Ndef&lt;/tech&gt;
410        &lt;tech&gt;android.nfc.tech.NdefFormatable&lt;/tech&gt;
411        &lt;tech&gt;android.nfc.tech.MifareClassic&lt;/tech&gt;
412        &lt;tech&gt;android.nfc.tech.MifareUltralight&lt;/tech&gt;
413    &lt;/tech-list&gt;
414&lt;/resources&gt;
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&lt;resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"&gt;
425    &lt;tech-list&gt;
426        &lt;tech&gt;android.nfc.tech.NfcA&lt;/tech&gt;
427        &lt;tech&gt;android.nfc.tech.Ndef&lt;/tech&gt;
428    &lt;/tech-list&gt;
429&lt;/resources&gt;
430
431&lt;resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"&gt;
432    &lt;tech-list&gt;
433        &lt;tech&gt;android.nfc.tech.NfcB&lt;/tech&gt;
434        &lt;tech&gt;android.nfc.tech.Ndef&lt;/tech&gt;
435    &lt;/tech-list&gt;
436&lt;/resources&gt;
437</pre>
438
439  <p>In your <code>AndroidManifest.xml</code> file, specify the resource file that you just created
440  in the <code>&lt;meta-data&gt;</code> element inside the <code>&lt;activity&gt;</code>
441  element like in the following example:</p>
442  <pre>
443&lt;activity&gt;
444...
445&lt;intent-filter&gt;
446    &lt;action android:name="android.nfc.action.TECH_DISCOVERED"/&gt;
447&lt;/intent-filter&gt;
448
449&lt;meta-data android:name="android.nfc.action.TECH_DISCOVERED"
450    android:resource="@xml/nfc_tech_filter" /&gt;
451...
452&lt;/activity&gt;
453</pre>
454
455<p>For more information about working with tag technologies and the {@link
456android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED} intent, see <a
457href="{@docRoot}guide/topics/connectivity/nfc/advanced-nfc.html#tag-tech">Working with Supported Tag
458Technologies</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
461filter:</p>
462
463
464<pre>&lt;intent-filter&gt;
465    &lt;action android:name="android.nfc.action.TAG_DISCOVERED"/&gt;
466&lt;/intent-filter&gt;
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
474tag 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
478representing the scanned tag.</li>
479  <li>{@link android.nfc.NfcAdapter#EXTRA_NDEF_MESSAGES} (optional): An array of NDEF messages
480parsed from the tag. This extra is mandatory on {@link android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED
481intents.</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
485the NFC intents to ensure that a tag was scanned, and then obtain the extras out of the
486intent. The following example checks for the {@link android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED}
487intent and gets the NDEF messages from an intent extra.</p>
488
489<pre>
490public 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 &lt; 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
507contain 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
514NFC 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
516URI records automatically. Starting in Android 4.1 (API level 16), {@link android.nfc.NdefRecord#createExternal createExternal()}
517and {@link android.nfc.NdefRecord#createMime createMime()} are available to help you create
518MIME and external type NDEF records. Use these helper methods whenever possible to avoid mistakes
519when manually creating NDEF records.</p>
520
521<p>
522This section also describes how to create the corresponding
523intent filter for the record. All of these NDEF record examples should be in the first NDEF
524record of the NDEF message that you are writing to a tag or beaming.</p>
525
526<h3 id="abs-uri">TNF_ABSOLUTE_URI</h3>
527<p class="note"><strong>Note:</strong> We recommend that you use the
528  <a href="#well-known-uri"><code>RTD_URI</code></a> type instead
529  of {@link android.nfc.NdefRecord#TNF_ABSOLUTE_URI}, because it is more efficient.</p>
530
531<p>You can create a {@link android.nfc.NdefRecord#TNF_ABSOLUTE_URI} NDEF record in the following way:</p>
532
533<pre>
534NdefRecord uriRecord = new NdefRecord(
535    NdefRecord.TNF_ABSOLUTE_URI ,
536    "http://developer.android.com/index.html".getBytes(Charset.forName("US-ASCII")),
537    new byte[0], new byte[0]);
538</pre>
539
540<p>The intent filter for the previous NDEF record would look like this:</p>
541<pre>
542&lt;intent-filter&gt;
543    &lt;action android:name="android.nfc.action.NDEF_DISCOVERED" /&gt;
544    &lt;category android:name="android.intent.category.DEFAULT" /&gt;
545    &lt;data android:scheme="http"
546        android:host="developer.android.com"
547        android:pathPrefix="/index.html" /&gt;
548&lt;/intent-filter&gt;
549</pre>
550
551<h3 id="mime">TNF_MIME_MEDIA</h3>
552<p>You can create a {@link android.nfc.NdefRecord#TNF_MIME_MEDIA} NDEF record in the following ways.</p>
553
554<p>Using the {@link android.nfc.NdefRecord#createMime createMime()} method:</p>
555<pre>
556NdefRecord mimeRecord = NdefRecord.createMime("application/vnd.com.example.android.beam",
557    "Beam me up, Android".getBytes(Charset.forName("US-ASCII")));
558</pre>
559
560<p>Creating the {@link android.nfc.NdefRecord} manually:</p>
561<pre>
562NdefRecord mimeRecord = new NdefRecord(
563    NdefRecord.TNF_MIME_MEDIA ,
564    "application/vnd.com.example.android.beam".getBytes(Charset.forName("US-ASCII")),
565    new byte[0], "Beam me up, Android!".getBytes(Charset.forName("US-ASCII")));
566</pre>
567
568<p>The intent filter for the previous NDEF records would look like this:</p>
569<pre>
570&lt;intent-filter&gt;
571    &lt;action android:name="android.nfc.action.NDEF_DISCOVERED" /&gt;
572    &lt;category android:name="android.intent.category.DEFAULT" /&gt;
573    &lt;data android:mimeType="application/vnd.com.example.android.beam" /&gt;
574&lt;/intent-filter&gt;
575</pre>
576
577<h3 id="well-known-text">TNF_WELL_KNOWN with RTD_TEXT</h3>
578
579<p>You can create a {@link android.nfc.NdefRecord#TNF_WELL_KNOWN} NDEF record in the following way:</p>
580<pre>
581public NdefRecord createTextRecord(String payload, Locale locale, boolean encodeInUtf8) {
582    byte[] langBytes = locale.getLanguage().getBytes(Charset.forName("US-ASCII"));
583    Charset utfEncoding = encodeInUtf8 ? Charset.forName("UTF-8") : Charset.forName("UTF-16");
584    byte[] textBytes = payload.getBytes(utfEncoding);
585    int utfBit = encodeInUtf8 ? 0 : (1 &lt;&lt; 7);
586    char status = (char) (utfBit + langBytes.length);
587    byte[] data = new byte[1 + langBytes.length + textBytes.length];
588    data[0] = (byte) status;
589    System.arraycopy(langBytes, 0, data, 1, langBytes.length);
590    System.arraycopy(textBytes, 0, data, 1 + langBytes.length, textBytes.length);
591    NdefRecord record = new NdefRecord(NdefRecord.TNF_WELL_KNOWN,
592    NdefRecord.RTD_TEXT, new byte[0], data);
593    return record;
594}
595</pre>
596
597<p>the intent filter would look like this:</p>
598<pre>
599&lt;intent-filter&gt;
600    &lt;action android:name="android.nfc.action.NDEF_DISCOVERED" /&gt;
601    &lt;category android:name="android.intent.category.DEFAULT" /&gt;
602    &lt;data android:mimeType="text/plain" /&gt;
603&lt;/intent-filter&gt;
604</pre>
605
606
607<h3 id="well-known-uri">TNF_WELL_KNOWN with RTD_URI</h3>
608
609<p>You can create a {@link android.nfc.NdefRecord#TNF_WELL_KNOWN} NDEF record in the following ways.</p>
610
611<p>Using the {@link android.nfc.NdefRecord#createUri(String)} method:</p>
612<pre>
613NdefRecord rtdUriRecord1 = NdefRecord.createUri("http://example.com");
614</pre>
615
616<p>Using the {@link android.nfc.NdefRecord#createUri(Uri)} method:</p>
617<pre>
618Uri uri = new Uri("http://example.com");
619NdefRecord rtdUriRecord2 = NdefRecord.createUri(uri);
620</pre>
621
622<p>Creating the {@link android.nfc.NdefRecord} manually:</p>
623<pre>
624byte[] uriField = "example.com".getBytes(Charset.forName("US-ASCII"));
625byte[] payload = new byte[uriField.length + 1];              //add 1 for the URI Prefix
626byte payload[0] = 0x01;                                      //prefixes http://www. to the URI
627System.arraycopy(uriField, 0, payload, 1, uriField.length);  //appends URI to payload
628NdefRecord rtdUriRecord = new NdefRecord(
629    NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_URI, new byte[0], payload);
630</pre>
631
632<p>The intent filter for the previous NDEF records would look like this:</p>
633
634<pre>
635&lt;intent-filter&gt;
636    &lt;action android:name="android.nfc.action.NDEF_DISCOVERED" /&gt;
637    &lt;category android:name="android.intent.category.DEFAULT" /&gt;
638    &lt;data android:scheme="http"
639        android:host="example.com"
640        android:pathPrefix="" /&gt;
641&lt;/intent-filter&gt;
642</pre>
643
644<h3 id="ext-type">TNF_EXTERNAL_TYPE</h3>
645<p>You can create a {@link android.nfc.NdefRecord#TNF_EXTERNAL_TYPE} NDEF record in the following ways:</p>
646
647<p>Using the {@link android.nfc.NdefRecord#createExternal createExternal()} method:
648<pre>
649byte[] payload; //assign to your data
650String domain = "com.example"; //usually your app's package name
651String type = "externalType";
652NdefRecord extRecord = NdefRecord.createExternal(domain, type, payload);
653</pre>
654
655<p>Creating the {@link android.nfc.NdefRecord} manually:</p>
656<pre>
657byte[] payload;
658...
659NdefRecord extRecord = new NdefRecord(
660    NdefRecord.TNF_EXTERNAL_TYPE, "com.example:externalType", new byte[0], payload);
661</pre>
662
663<p>The intent filter for the previous NDEF records would look like this:</p>
664<pre>
665&lt;intent-filter&gt;
666    &lt;action android:name="android.nfc.action.NDEF_DISCOVERED" /&gt;
667    &lt;category android:name="android.intent.category.DEFAULT" /&gt;
668    &lt;data android:scheme="vnd.android.nfc"
669        android:host="ext"
670        android:pathPrefix="/com.example:externalType"/&gt;
671&lt;/intent-filter&gt;
672</pre>
673
674
675<p>Use TNF_EXTERNAL_TYPE for more generic NFC tag deployments to better support both
676Android-powered and non-Android-powered devices.</p>
677
678<p class="note"><strong>Note</strong>: URNs for {@link
679android.nfc.NdefRecord#TNF_EXTERNAL_TYPE} have a canonical format of:
680<code>urn:nfc:ext:example.com:externalType</code>, however the NFC Forum RTD specification
681declares that the <code>urn:nfc:ext:</code> portion of the URN must be ommitted from the
682NDEF record. So all you need to provide is the domain (<code>example.com</code> in the example)
683and type (<code>externalType</code> in the example) separated by a colon.
684When dispatching TNF_EXTERNAL_TYPE, Android converts the <code>urn:nfc:ext:example.com:externalType</code> URN to a
685<code>vnd.android.nfc://ext/example.com:externalType</code> URI, which is what the intent filter in the example
686declares.</p>
687
688<h3 id="aar">Android Application Records</h3>
689
690<p>
691Introduced in Android 4.0 (API level 14), an Android Application Record (AAR) provides a stronger
692certainty that your application is started when an NFC tag is scanned. An AAR has the package name
693of an application embedded inside an NDEF record. You can add an AAR to any NDEF record of your NDEF message,
694because Android searches the entire NDEF message for AARs. If it finds an AAR, it starts the application based
695on the package name inside the AAR. If the application is not present on the device,
696Google Play is launched to download the application.</p>
697
698<p>AARs are useful if you want to prevent other applications from filtering for the same intent and
699potentially handling specific tags that you have deployed. AARs are only supported at the
700application level, because of the package name constraint, and not at the Activity level as with
701intent filtering. If you want to handle an intent at the Activity level, <a
702href="#filtering-intents">use intent filters</a>.
703</p>
704
705
706
707<p>If a tag contains an AAR, the tag dispatch system dispatches in the following manner:</p>
708<ol>
709  <li>Try to start an Activity using an intent filter as normal. If the Activity that matches
710the intent also matches the AAR, start the Activity.</li>
711  <li>If the Activity that filters for the intent does not match the
712AAR, if multiple Activities can handle the intent, or if no Activity handles the intent, start the
713application specified by the AAR.</li>
714  <li>If no application can start with the AAR, go to Google Play to download the
715application based on the AAR.</li>
716</ol>
717
718</p>
719
720<p class="note"><strong>Note:</strong> You can override AARs and the intent dispatch system with the <a
721href="{@docRoot}guide/topics/connectivity/nfc/advanced-nfc.html#foreground-dispatch">foreground dispatch
722system</a>, which allows a foreground activity to have priority when an NFC tag is discovered.
723With this method, the activity must be in the foreground to
724override AARs and the intent dispatch system.</p>
725
726<p>If you still want to filter for scanned tags that do not contain an AAR, you can declare
727intent filters as normal. This is useful if your application is interested in other tags
728that do not contain an AAR. For example, maybe you want to guarantee that your application handles
729proprietary tags that you deploy as well as general tags deployed by third parties. Keep in mind
730that AARs are specific to Android 4.0 devices or later, so when deploying tags, you most likely want
731to use a combination of AARs and MIME types/URIs to support the widest range of devices. In
732addition, when you deploy NFC tags, think about how you want to write your NFC tags to enable
733support for the most devices (Android-powered and other devices). You can do this by
734defining a relatively unique MIME type or URI to make it easier for applications to distinguish.
735</p>
736
737<p>Android provides a simple API to create an AAR,
738{@link android.nfc.NdefRecord#createApplicationRecord createApplicationRecord()}. All you need to
739do is embed the AAR anywhere in your {@link android.nfc.NdefMessage}. You do not want
740to use the first record of your {@link android.nfc.NdefMessage}, unless the AAR is the only
741record in the {@link android.nfc.NdefMessage}. This is because the Android
742system checks the first record of an {@link android.nfc.NdefMessage} to determine the MIME type or
743URI of the tag, which is used to create an intent for applications to filter. The following code
744shows you how to create an AAR:</p>
745
746<pre>
747NdefMessage msg = new NdefMessage(
748        new NdefRecord[] {
749            ...,
750            NdefRecord.createApplicationRecord("com.example.android.beam")}
751</pre>
752
753
754<h2 id="p2p">Beaming NDEF Messages to Other Devices</h2>
755
756<p>Android Beam allows simple peer-to-peer data exchange between two Android-powered devices. The
757application that wants to beam data to another device must be in the foreground and the device
758receiving the data must not be locked. When the beaming device comes in close enough contact with a
759receiving device, the beaming device displays the "Touch to Beam" UI. The user can then choose
760whether or not to beam the message to the receiving device.</p>
761
762<p class="note"><strong>Note:</strong> Foreground NDEF pushing was available at API level 10,
763which provides similar functionality to Android Beam. These APIs have since been deprecated, but
764are available to support older devices. See {@link android.nfc.NfcAdapter#enableForegroundNdefPush
765enableForegroundNdefPush()} for more information.</p>
766
767<p>You can enable Android Beam for your application by calling one of the two methods:</p>
768  <ul>
769    <li>{@link android.nfc.NfcAdapter#setNdefPushMessage setNdefPushMessage()}: Accepts an
770{@link android.nfc.NdefMessage} to set as the message to beam. Automatically beams the message
771when two devices are in close enough proximity.</li>
772    <li>{@link android.nfc.NfcAdapter#setNdefPushMessageCallback setNdefPushMessageCallback()}:
773Accepts a callback that contains a
774{@link android.nfc.NfcAdapter.CreateNdefMessageCallback#createNdefMessage createNdefMessage()}
775which is called when a device is in range to beam data to. The callback lets you create
776the NDEF message only when necessary.</li>
777  </ul>
778
779<p>An activity can only push one NDEF message at a time, so {@link
780android.nfc.NfcAdapter#setNdefPushMessageCallback setNdefPushMessageCallback()} takes precedence
781over {@link android.nfc.NfcAdapter#setNdefPushMessage setNdefPushMessage()} if both are set. To use
782Android Beam, the following general guidelines must be met:
783</p>
784
785  <ul>
786    <li>The activity that is beaming the data must be in the foreground. Both devices must have
787their screens unlocked.</li>
788
789    <li>You must encapsulate the data that you are beaming in an {@link android.nfc.NdefMessage}
790    object.</li>
791
792    <li>The NFC device that is receiving the beamed data must support the
793    <code>com.android.npp</code> NDEF push protocol or NFC Forum's SNEP (Simple NDEF Exchange
794Protocol). The <code>com.android.npp</code> protocol is required for devices on API level 9 (Android
7952.3) to API level 13 (Android 3.2). <code>com.android.npp</code> and SNEP are both required on
796API level 14 (Android 4.0) and later.</li>
797</li>
798  </ul>
799
800  <p class="note"><strong>Note:</strong> If your activity enables Android Beam and is
801in the foreground, the standard intent dispatch system is disabled. However, if your activity also
802enables <a href="{@docRoot}guide/topics/connectivity/nfc/advanced-nfc.html#foreground-dispatch">foreground
803dispatching</a>, then it can still scan tags that match the intent filters set in the foreground
804dispatching.</p>
805
806  <p>To enable Android Beam:</p>
807
808  <ol>
809    <li>Create an {@link android.nfc.NdefMessage} that contains the {@link android.nfc.NdefRecord}s
810that you want to push onto the other device.</li>
811
812    <li>Call {@link
813android.nfc.NfcAdapter#setNdefPushMessage setNdefPushMessage()} with a {@link
814android.nfc.NdefMessage} or call {@link
815android.nfc.NfcAdapter#setNdefPushMessageCallback setNdefPushMessageCallback} passing in a {@link
816android.nfc.NfcAdapter.CreateNdefMessageCallback} object in the <code>onCreate()</code> method of
817your activity. These methods require at least one activity that you want to enable with Android
818Beam, along with an optional list of other activities to activate.
819
820<p>In general, you normally use {@link
821android.nfc.NfcAdapter#setNdefPushMessage setNdefPushMessage()} if your Activity only needs to
822push the same NDEF message at all times, when two devices are in range to communicate. You use
823{@link android.nfc.NfcAdapter#setNdefPushMessageCallback setNdefPushMessageCallback} when your
824application cares about the current context of the application and wants to push an NDEF message
825depending on what the user is doing in your application.</p>
826    </li>
827  </ol>
828
829<p>The following sample shows how a simple activity calls {@link
830android.nfc.NfcAdapter.CreateNdefMessageCallback} in the <code>onCreate()</code> method of an
831activity (see <a href="{@docRoot}resources/samples/AndroidBeamDemo/index.html">AndroidBeamDemo</a>
832for the complete sample). This example also has methods to help you create a MIME record:</p>
833
834<pre id="code-example">
835package com.example.android.beam;
836
837import android.app.Activity;
838import android.content.Intent;
839import android.nfc.NdefMessage;
840import android.nfc.NdefRecord;
841import android.nfc.NfcAdapter;
842import android.nfc.NfcAdapter.CreateNdefMessageCallback;
843import android.nfc.NfcEvent;
844import android.os.Bundle;
845import android.os.Parcelable;
846import android.widget.TextView;
847import android.widget.Toast;
848import java.nio.charset.Charset;
849
850
851public class Beam extends Activity implements CreateNdefMessageCallback {
852    NfcAdapter mNfcAdapter;
853    TextView textView;
854
855    &#064;Override
856    public void onCreate(Bundle savedInstanceState) {
857        super.onCreate(savedInstanceState);
858        setContentView(R.layout.main);
859        TextView textView = (TextView) findViewById(R.id.textView);
860        // Check for available NFC Adapter
861        mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
862        if (mNfcAdapter == null) {
863            Toast.makeText(this, "NFC is not available", Toast.LENGTH_LONG).show();
864            finish();
865            return;
866        }
867        // Register callback
868        mNfcAdapter.setNdefPushMessageCallback(this, this);
869    }
870
871    &#064;Override
872    public NdefMessage createNdefMessage(NfcEvent event) {
873        String text = ("Beam me up, Android!\n\n" +
874                "Beam Time: " + System.currentTimeMillis());
875        NdefMessage msg = new NdefMessage(
876                new NdefRecord[] { createMime(
877                        "application/vnd.com.example.android.beam", text.getBytes())
878         /**
879          * The Android Application Record (AAR) is commented out. When a device
880          * receives a push with an AAR in it, the application specified in the AAR
881          * is guaranteed to run. The AAR overrides the tag dispatch system.
882          * You can add it back in to guarantee that this
883          * activity starts when receiving a beamed message. For now, this code
884          * uses the tag dispatch system.
885          */
886          //,NdefRecord.createApplicationRecord("com.example.android.beam")
887        });
888        return msg;
889    }
890
891    &#064;Override
892    public void onResume() {
893        super.onResume();
894        // Check to see that the Activity started due to an Android Beam
895        if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
896            processIntent(getIntent());
897        }
898    }
899
900    &#064;Override
901    public void onNewIntent(Intent intent) {
902        // onResume gets called after this to handle the intent
903        setIntent(intent);
904    }
905
906    /**
907     * Parses the NDEF Message from the intent and prints to the TextView
908     */
909    void processIntent(Intent intent) {
910        textView = (TextView) findViewById(R.id.textView);
911        Parcelable[] rawMsgs = intent.getParcelableArrayExtra(
912                NfcAdapter.EXTRA_NDEF_MESSAGES);
913        // only one message sent during the beam
914        NdefMessage msg = (NdefMessage) rawMsgs[0];
915        // record 0 contains the MIME type, record 1 is the AAR, if present
916        textView.setText(new String(msg.getRecords()[0].getPayload()));
917    }
918}
919</pre>
920
921<p>Note that this code comments out an AAR, which you can remove. If you enable the AAR, the
922application specified in the AAR always receives the Android Beam message. If the application is not
923present, Google Play is started to download the application. Therefore, the following intent
924filter is not technically necessary for Android 4.0 devices or later if the AAR is used:
925</p>
926
927<pre>
928&lt;intent-filter&gt;
929  &lt;action android:name="android.nfc.action.NDEF_DISCOVERED"/&gt;
930  &lt;category android:name="android.intent.category.DEFAULT"/&gt;
931  &lt;data android:mimeType="application/vnd.com.example.android.beam"/&gt;
932&lt;/intent-filter&gt;
933</pre>
934<p>With this intent filter, the <code>com.example.android.beam</code> application now can be started
935when it scans an NFC tag or receives an Android Beam with an AAR of
936type <code>com.example.android.beam</code>, or when an NDEF formatted message contains a MIME record
937of type <code>application/vnd.com.example.android.beam</code>.</p>
938
939<p>Even though AARs guarantee an application is started or downloaded, intent filters are
940recommended, because they let you start an Activity of your choice in your
941application instead of always starting the main Activity within the package specified by an AAR.
942AARs do not have Activity level granularity. Also, because some Android-powered devices do not
943support AARs, you should also embed identifying information in the first NDEF record of your NDEF
944messages and filter for that as well, just in case. See <a href="#creating-records">Creating Common
945Types of NDEF records</a> for more information on how to create records.
946</p>
947