Skip to content

Commit 1ff3921

Browse files
Robert LyAndroid (Google) Code Review
authored andcommitted
Merge "cherrypick from master - docs: nfc updates Change-Id: Iaa782911f14b11bc896ac9ef06db2c43104d1dac" into ics-mr0
2 parents 2bd3c2f + 83a75a5 commit 1ff3921

File tree

5 files changed

+1275
-612
lines changed

5 files changed

+1275
-612
lines changed

docs/html/guide/guide_toc.cs

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -262,20 +262,20 @@ localized titles are added in the language order specified below.
262262
</ul>
263263
</li>
264264
<li class="toggle-list">
265-
<div><a href="<?cs var:toroot ?>guide/topics/renderscript/index.html">
266-
<span class="en">RenderScript</span>
267-
</a></div>
268-
<ul>
269-
<li><a href="<?cs var:toroot ?>guide/topics/renderscript/graphics.html">
270-
<span class="en">Graphics</span>
271-
</a>
272-
</li>
273-
<li><a href="<?cs var:toroot ?>guide/topics/renderscript/compute.html">
274-
<span class="en">Compute</span>
275-
</a>
276-
</li>
277-
</ul>
278-
</li>
265+
<div><a href="<?cs var:toroot ?>guide/topics/renderscript/index.html">
266+
<span class="en">RenderScript</span></a>
267+
</div>
268+
<ul>
269+
<li><a href="<?cs var:toroot ?>guide/topics/renderscript/graphics.html">
270+
<span class="en">Graphics</span>
271+
</a>
272+
</li>
273+
<li><a href="<?cs var:toroot ?>guide/topics/renderscript/compute.html">
274+
<span class="en">Compute</span>
275+
</a>
276+
</li>
277+
</ul>
278+
</li>
279279

280280
<li class="toggle-list">
281281
<div><a href="<?cs var:toroot ?>guide/topics/media/index.html">
@@ -332,9 +332,15 @@ localized titles are added in the language order specified below.
332332
<li><a href="<?cs var:toroot?>guide/topics/wireless/bluetooth.html">
333333
<span class="en">Bluetooth</span></a>
334334
</li>
335-
<li><a href="<?cs var:toroot?>guide/topics/nfc/index.html">
336-
<span class="en">Near Field Communication</span>
337-
</a></li>
335+
<li class="toggle-list">
336+
<div><a href="<?cs var:toroot?>guide/topics/nfc/index.html">
337+
<span class="en">Near Field Communication</span></a> <span class="new">updated</span>
338+
</div>
339+
<ul>
340+
<li><a href="<?cs var:toroot ?>guide/topics/nfc/nfc.html">NFC Basics</a></li>
341+
<li><a href="<?cs var:toroot ?>guide/topics/nfc/advanced-nfc.html">Advanced NFC</a></li>
342+
</ul>
343+
</li>
338344
<li class="toggle-list">
339345
<div><a href="<?cs var:toroot?>guide/topics/usb/index.html">
340346
<span class="en">USB</span></a>
@@ -715,7 +721,7 @@ localized titles are added in the language order specified below.
715721
<li class="toggle-list">
716722
<div><a href="<?cs var:toroot ?>guide/practices/ui_guidelines/index.html">
717723
<span class="en">UI Guidelines</span>
718-
</a></div>
724+
</a> <span class="new-child">updated</span></div>
719725
<ul>
720726
<li class="toggle-list">
721727
<div><a href="<?cs var:toroot ?>guide/practices/ui_guidelines/icon_design.html">
Lines changed: 303 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,303 @@
1+
page.title=Advanced NFC
2+
@jd:body
3+
4+
<div id="qv-wrapper">
5+
<div id="qv">
6+
<h2>In this document</h2>
7+
<ol>
8+
<li><a href="#tag-tech">Working with Supported Tag Technologies</a>
9+
<ol>
10+
<li><a href="#tech-intent">Working with tag technologies and the ACTION_TECH_DISCOVERED
11+
intent</a></li>
12+
<li><a href="#read-write">Reading and writing to tags</a></li>
13+
</ol></li>
14+
<li><a href="#foreground-dispatch">Using the Foreground Dispatch System</a></li>
15+
</ol>
16+
</div>
17+
</div>
18+
19+
<p>This document describes advanced NFC topics, such as working with various tag technologies,
20+
writing to NFC tags, and foreground dispatching, which allows an application in the foreground to
21+
handle intents even when other applications filter for the same ones.</p>
22+
23+
<h2 id="tag-tech">Working with Supported Tag Technologies</h2>
24+
<p>When working with NFC tags and Android-powered devices, the main format you use to read
25+
and write data on tags is NDEF. When a device scans a tag with NDEF data, Android provides support
26+
in parsing the message and delivering it in an {@link android.nfc.NdefMessage} when
27+
possible. There are cases, however, when you scan a tag that does not contain
28+
NDEF data or when the NDEF data could not be mapped to a MIME type or URI.
29+
In these cases, you need to open communication directly with the tag and read and write to it with
30+
your own protocol (in raw bytes). Android provides generic support for these use cases with the
31+
{@link android.nfc.tech} package, which is described in <a href="#tech-table">Table 1</a>. You can
32+
use the {@link android.nfc.Tag#getTechList getTechList()} method to determine the technologies
33+
supported by the tag and create the corresponding {@link android.nfc.tech.TagTechnology}
34+
object with one of classes provided by {@link android.nfc.tech} </p>
35+
36+
37+
<table>
38+
39+
<p class="table-caption" id="table1">
40+
<strong>Table 1.</strong> Supported tag technologies</p>
41+
<table id="tech-table">
42+
43+
<tr>
44+
<th>Class</th>
45+
46+
<th>Description</th>
47+
</tr>
48+
49+
<tr>
50+
<td>{@link android.nfc.tech.TagTechnology}</td>
51+
52+
<td>The interface that all tag technology classes must implement.</td>
53+
</tr>
54+
55+
<tr>
56+
<td>{@link android.nfc.tech.NfcA}</td>
57+
58+
<td>Provides access to NFC-A (ISO 14443-3A) properties and I/O operations.</td>
59+
</tr>
60+
61+
<tr>
62+
<td>{@link android.nfc.tech.NfcB}</td>
63+
64+
<td>Provides access to NFC-B (ISO 14443-3B) properties and I/O operations.</td>
65+
</tr>
66+
67+
<tr>
68+
<td>{@link android.nfc.tech.NfcF}</td>
69+
70+
<td>Provides access to NFC-F (JIS 6319-4) properties and I/O operations.</td>
71+
</tr>
72+
73+
<tr>
74+
<td>{@link android.nfc.tech.NfcV}</td>
75+
76+
<td>Provides access to NFC-V (ISO 15693) properties and I/O operations.</td>
77+
</tr>
78+
79+
<tr>
80+
<td>{@link android.nfc.tech.IsoDep}</td>
81+
82+
<td>Provides access to ISO-DEP (ISO 14443-4) properties and I/O operations.</td>
83+
</tr>
84+
85+
<tr>
86+
<td>{@link android.nfc.tech.Ndef}</td>
87+
88+
<td>Provides access to NDEF data and operations on NFC tags that have been formatted as
89+
NDEF.</td>
90+
</tr>
91+
92+
<tr>
93+
<td>{@link android.nfc.tech.NdefFormatable}</td>
94+
95+
<td>Provides a format operations for tags that may be NDEF formattable.</td>
96+
</tr>
97+
</table>
98+
<p>The following tag technlogies are not required to be supported by Android-powered devices.</p>
99+
<p class="table-caption" id="table2">
100+
<strong>Table 2.</strong> Optional supported tag technologies</p>
101+
<table>
102+
<tr>
103+
<th>Class</th>
104+
105+
<th>Description</th>
106+
</tr>
107+
<tr>
108+
<td>{@link android.nfc.tech.MifareClassic}</td>
109+
110+
<td>Provides access to MIFARE Classic properties and I/O operations, if this Android device
111+
supports MIFARE.</td>
112+
</tr>
113+
114+
<tr>
115+
<td>{@link android.nfc.tech.MifareUltralight}</td>
116+
117+
<td>Provides access to MIFARE Ultralight properties and I/O operations, if this Android
118+
device supports MIFARE.</td>
119+
</tr>
120+
</table>
121+
122+
<h3 id="tech-intent">Working with tag technologies and the ACTION_TECH_DISCOVERED intent</h3>
123+
<p>When a device scans a tag that has NDEF data on it, but could not be mapped to a MIME or URI,
124+
the tag dispatch system tries to start an activity with the {@link
125+
android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED}
126+
intent. The {@link android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED} is also used when a tag
127+
with non-NDEF data is scanned. Having this fallback allows you to work with the data on the tag
128+
directly if the tag dispatch system could not parse it for you. The basic steps when working with
129+
tag technologies are as follows:</p>
130+
131+
<ol>
132+
<li>Filter for an {@link android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED} intent specifying the
133+
tag technologies that you want to handle. See <a
134+
href="{@docRoot}guide/topics/nfc/nfc.html#tech-disc">Filtering for NFC
135+
intents</a> for more information. In general, the tag dispatch system tries to start a {@link
136+
android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED} intent when an NDEF message
137+
cannot be mapped to a MIME type or URI, or if the tag scanned did not contain NDEF data. For
138+
more information on how this is determined, see <a
139+
href="{@docRoot}guide/topics/nfc/nfc.html#tag-dispatch">The Tag Dispatch System</a>.</li>
140+
<li>When your application receives the intent, obtain the {@link android.nfc.Tag} object from
141+
the intent:
142+
<pre>Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);</pre></li>
143+
<li>Obtain an instance of a {@link android.nfc.tech.TagTechnology}, by calling one of the
144+
<code>get</code> factory methods of the classes in the {@link android.nfc.tech} package. You can
145+
enumerate the supported technologies of the tag by calling {@link android.nfc.Tag#getTechList
146+
getTechList()} before calling a <code>get</code> factory method. For example, to obtain an instance
147+
of {@link android.nfc.tech.MifareUltralight} from a {@link android.nfc.Tag}, do the following:
148+
149+
<pre>
150+
MifareUltralight.get(intent.getParcelableExtra(NfcAdapter.EXTRA_TAG));
151+
</pre>
152+
</li>
153+
</ol>
154+
155+
156+
157+
<h3 id="read-write">Reading and writing to tags</h3>
158+
159+
<p>Reading and writing to an NFC tag involves obtaining the tag from the intent and
160+
opening communication with the tag. You must define your own protocol stack to read and write data
161+
to the tag. Keep in mind, however, that you can still read and write NDEF data when working
162+
directly with a tag. It is up to you how you want to structure things. The
163+
following example shows how to work with a MIFARE Ultralight tag.</p>
164+
165+
<pre>
166+
package com.example.android.nfc;
167+
168+
import android.nfc.Tag;
169+
import android.nfc.tech.MifareUltralight;
170+
import android.util.Log;
171+
import java.io.IOException;
172+
import java.nio.charset.Charset;
173+
174+
public class MifareUltralightTagTester {
175+
176+
private static final String TAG = MifareUltralightTagTester.class.getSimpleName();
177+
178+
public void writeTag(Tag tag, String tagText) {
179+
MifareUltralight ultralight = MifareUltralight.get(tag);
180+
try {
181+
ultralight.connect();
182+
ultralight.writePage(4, "abcd".getBytes(Charset.forName("US-ASCII")));
183+
ultralight.writePage(5, "efgh".getBytes(Charset.forName("US-ASCII")));
184+
ultralight.writePage(6, "ijkl".getBytes(Charset.forName("US-ASCII")));
185+
ultralight.writePage(7, "mnop".getBytes(Charset.forName("US-ASCII")));
186+
} catch (IOException e) {
187+
Log.e(TAG, "IOException while closing MifareUltralight...", e);
188+
} finally {
189+
try {
190+
ultralight.close();
191+
} catch (IOException e) {
192+
Log.e(TAG, "IOException while closing MifareUltralight...", e);
193+
}
194+
}
195+
}
196+
197+
public String readTag(Tag tag) {
198+
MifareUltralight mifare = MifareUltralight.get(tag);
199+
try {
200+
mifare.connect();
201+
byte[] payload = mifare.readPages(4);
202+
return new String(payload, Charset.forName("US-ASCII"));
203+
} catch (IOException e) {
204+
Log.e(TAG, "IOException while writing MifareUltralight
205+
message...", e);
206+
} finally {
207+
if (mifare != null) {
208+
try {
209+
mifare.close();
210+
}
211+
catch (IOException e) {
212+
Log.e(TAG, "Error closing tag...", e);
213+
}
214+
}
215+
}
216+
return null;
217+
}
218+
}
219+
</pre>
220+
221+
</pre>
222+
223+
<h2 id="foreground-dispatch">Using the Foreground Dispatch System</h2>
224+
225+
<p>The foreground dispatch system allows an activity to intercept an intent and claim
226+
priority over other activities that handle the same intent. Using this system involves
227+
constructing a few data structures for the Android system to be able to send the appropriate
228+
intents to your application. To enable the foreground dispatch system:</p>
229+
230+
<ol>
231+
<li>Add the following code in the <code>onCreate()</code> method of your activity:
232+
233+
<ol type="a">
234+
<li>Create a {@link android.app.PendingIntent} object so the Android system can populate it
235+
with the details of the tag when it is scanned.
236+
<pre>
237+
PendingIntent pendingIntent = PendingIntent.getActivity(
238+
this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
239+
</pre>
240+
</li>
241+
242+
<li>Declare intent filters to handle the intents that you want to intercept. The foreground
243+
dispatch system checks the specified intent filters with the intent that is received when
244+
the device scans a tag. If it matches, then your application handles the intent. If it does
245+
not match, the foreground dispatch system falls back to the intent dispatch system.
246+
Specifying a <code>null</code> array of intent filters and technology filters, specifies
247+
that you want to filter for all tags that fallback to the <code>TAG_DISCOVERED</code>
248+
intent. The code snippet below handles all MIME types for <code>NDEF_DISCOVERED</code>. You
249+
should only handle the ones that you need.
250+
<pre>
251+
IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
252+
try {
253+
ndef.addDataType("*/*"); /* Handles all MIME based dispatches.
254+
You should specify only the ones that you need. */
255+
}
256+
catch (MalformedMimeTypeException e) {
257+
throw new RuntimeException("fail", e);
258+
}
259+
intentFiltersArray = new IntentFilter[] {ndef, };
260+
</pre>
261+
</li>
262+
263+
<li>Set up an array of tag technologies that your application wants to handle. Call the
264+
<code>Object.class.getName()</code> method to obtain the class of the technology that you
265+
want to support.
266+
<pre>
267+
techListsArray = new String[][] { new String[] { NfcF.class.getName() } };
268+
</pre>
269+
</li>
270+
</ol>
271+
</li>
272+
273+
<li>Override the following activity lifecycle callbacks and add logic to enable and disable the
274+
foreground dispatch when the activity loses ({@link android.app.Activity#onPause onPause()})
275+
and regains ({@link android.app.Activity#onResume onResume()}) focus. {@link
276+
android.nfc.NfcAdapter#enableForegroundDispatch enableForegroundDispatch()} must be called from
277+
the main thread and only when the activity is in the foreground (calling in {@link
278+
android.app.Activity#onResume onResume()} guarantees this). You also need to implement the {@link
279+
android.app.Activity#onNewIntent onNewIntent} callback to process the data from the scanned NFC
280+
tag.</li>
281+
282+
<pre>
283+
public void onPause() {
284+
super.onPause();
285+
mAdapter.disableForegroundDispatch(this);
286+
}
287+
288+
public void onResume() {
289+
super.onResume();
290+
mAdapter.enableForegroundDispatch(this, pendingIntent, intentFiltersArray, techListsArray);
291+
}
292+
293+
public void onNewIntent(Intent intent) {
294+
Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
295+
//do something with tagFromIntent
296+
}
297+
</pre>
298+
</li>
299+
</ol>
300+
301+
<p>See the <a href=
302+
"{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/nfc/ForegroundDispatch.html">
303+
ForegroundDispatch</a> sample from API Demos for the complete sample.</p>

0 commit comments

Comments
 (0)