diff options
Diffstat (limited to 'docs/html/guide/topics/nfc/advanced-nfc.jd')
-rw-r--r-- | docs/html/guide/topics/nfc/advanced-nfc.jd | 300 |
1 files changed, 300 insertions, 0 deletions
diff --git a/docs/html/guide/topics/nfc/advanced-nfc.jd b/docs/html/guide/topics/nfc/advanced-nfc.jd new file mode 100644 index 0000000..b43b559 --- /dev/null +++ b/docs/html/guide/topics/nfc/advanced-nfc.jd @@ -0,0 +1,300 @@ +page.title=Advanced NFC +@jd:body + +<div id="qv-wrapper"> +<div id="qv"> + <h2>In this document</h2> + <ol> + <li><a href="#tag-tech">Working with Supported Tag Technologies</a> + <ol> + <li><a href="#tech-intent">Working with tag technologies and the ACTION_TECH_DISCOVERED + intent</a></li> + <li><a href="#read-write">Reading and writing to tags</a></li> + </ol></li> + <li><a href="#foreground-dispatch">Using the Foreground Dispatch System</a></li> + </ol> +</div> +</div> + +<p>This document describes advanced NFC topics, such as working with various tag technologies, +writing to NFC tags, and foreground dispatching, which allows an application in the foreground to +handle intents even when other applications filter for the same ones.</p> + +<h2 id="tag-tech">Working with Supported Tag Technologies</h2> +<p>When working with NFC tags and Android-powered devices, the main format you use to read +and write data on tags is NDEF. When a device scans a tag with NDEF data, Android provides support +in parsing the message and delivering it in an {@link android.nfc.NdefMessage} when +possible. There are cases, however, when you scan a tag that does not contain +NDEF data or when the NDEF data could not be mapped to a MIME type or URI. +In these cases, you need to open communication directly with the tag and read and write to it with +your own protocol (in raw bytes). Android provides generic support for these use cases with the +{@link android.nfc.tech} package, which is described in <a href="#tech-table">Table 1</a>. You can +use the {@link android.nfc.Tag#getTechList getTechList()} method to determine the technologies +supported by the tag and create the corresponding {@link android.nfc.tech.TagTechnology} +object with one of classes provided by {@link android.nfc.tech} </p> + +<p class="table-caption" id="table1"> +<strong>Table 1.</strong> Supported tag technologies</p> +<table id="tech-table"> + + <tr> + <th>Class</th> + + <th>Description</th> + </tr> + + <tr> + <td>{@link android.nfc.tech.TagTechnology}</td> + + <td>The interface that all tag technology classes must implement.</td> + </tr> + + <tr> + <td>{@link android.nfc.tech.NfcA}</td> + + <td>Provides access to NFC-A (ISO 14443-3A) properties and I/O operations.</td> + </tr> + + <tr> + <td>{@link android.nfc.tech.NfcB}</td> + + <td>Provides access to NFC-B (ISO 14443-3B) properties and I/O operations.</td> + </tr> + + <tr> + <td>{@link android.nfc.tech.NfcF}</td> + + <td>Provides access to NFC-F (JIS 6319-4) properties and I/O operations.</td> + </tr> + + <tr> + <td>{@link android.nfc.tech.NfcV}</td> + + <td>Provides access to NFC-V (ISO 15693) properties and I/O operations.</td> + </tr> + + <tr> + <td>{@link android.nfc.tech.IsoDep}</td> + + <td>Provides access to ISO-DEP (ISO 14443-4) properties and I/O operations.</td> + </tr> + + <tr> + <td>{@link android.nfc.tech.Ndef}</td> + + <td>Provides access to NDEF data and operations on NFC tags that have been formatted as + NDEF.</td> + </tr> + + <tr> + <td>{@link android.nfc.tech.NdefFormatable}</td> + + <td>Provides a format operations for tags that may be NDEF formattable.</td> + </tr> + </table> +<p>The following tag technlogies are not required to be supported by Android-powered devices.</p> + <p class="table-caption" id="table2"> +<strong>Table 2.</strong> Optional supported tag technologies</p> + <table> + <tr> + <th>Class</th> + + <th>Description</th> + </tr> + <tr> + <td>{@link android.nfc.tech.MifareClassic}</td> + + <td>Provides access to MIFARE Classic properties and I/O operations, if this Android device + supports MIFARE.</td> + </tr> + + <tr> + <td>{@link android.nfc.tech.MifareUltralight}</td> + + <td>Provides access to MIFARE Ultralight properties and I/O operations, if this Android + device supports MIFARE.</td> + </tr> + </table> + +<h3 id="tech-intent">Working with tag technologies and the ACTION_TECH_DISCOVERED intent</h3> +<p>When a device scans a tag that has NDEF data on it, but could not be mapped to a MIME or URI, +the tag dispatch system tries to start an activity with the {@link +android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED} +intent. The {@link android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED} is also used when a tag +with non-NDEF data is scanned. Having this fallback allows you to work with the data on the tag +directly if the tag dispatch system could not parse it for you. The basic steps when working with +tag technologies are as follows:</p> + +<ol> + <li>Filter for an {@link android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED} intent specifying the +tag technologies that you want to handle. See <a +href="{@docRoot}guide/topics/nfc/nfc.html#tech-disc">Filtering for NFC +intents</a> for more information. In general, the tag dispatch system tries to start a {@link +android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED} intent when an NDEF message +cannot be mapped to a MIME type or URI, or if the tag scanned did not contain NDEF data. For +more information on how this is determined, see <a +href="{@docRoot}guide/topics/nfc/nfc.html#tag-dispatch">The Tag Dispatch System</a>.</li> + <li>When your application receives the intent, obtain the {@link android.nfc.Tag} object from +the intent: +<pre>Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);</pre></li> +<li>Obtain an instance of a {@link android.nfc.tech.TagTechnology}, by calling one of the +<code>get</code> factory methods of the classes in the {@link android.nfc.tech} package. You can +enumerate the supported technologies of the tag by calling {@link android.nfc.Tag#getTechList +getTechList()} before calling a <code>get</code> factory method. For example, to obtain an instance +of {@link android.nfc.tech.MifareUltralight} from a {@link android.nfc.Tag}, do the following: + +<pre> +MifareUltralight.get(intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)); +</pre> +</li> +</ol> + + + +<h3 id="read-write">Reading and writing to tags</h3> + +<p>Reading and writing to an NFC tag involves obtaining the tag from the intent and +opening communication with the tag. You must define your own protocol stack to read and write data +to the tag. Keep in mind, however, that you can still read and write NDEF data when working +directly with a tag. It is up to you how you want to structure things. The +following example shows how to work with a MIFARE Ultralight tag.</p> + +<pre> +package com.example.android.nfc; + +import android.nfc.Tag; +import android.nfc.tech.MifareUltralight; +import android.util.Log; +import java.io.IOException; +import java.nio.charset.Charset; + +public class MifareUltralightTagTester { + + private static final String TAG = MifareUltralightTagTester.class.getSimpleName(); + + public void writeTag(Tag tag, String tagText) { + MifareUltralight ultralight = MifareUltralight.get(tag); + try { + ultralight.connect(); + ultralight.writePage(4, "abcd".getBytes(Charset.forName("US-ASCII"))); + ultralight.writePage(5, "efgh".getBytes(Charset.forName("US-ASCII"))); + ultralight.writePage(6, "ijkl".getBytes(Charset.forName("US-ASCII"))); + ultralight.writePage(7, "mnop".getBytes(Charset.forName("US-ASCII"))); + } catch (IOException e) { + Log.e(TAG, "IOException while closing MifareUltralight...", e); + } finally { + try { + ultralight.close(); + } catch (IOException e) { + Log.e(TAG, "IOException while closing MifareUltralight...", e); + } + } + } + + public String readTag(Tag tag) { + MifareUltralight mifare = MifareUltralight.get(tag); + try { + mifare.connect(); + byte[] payload = mifare.readPages(4); + return new String(payload, Charset.forName("US-ASCII")); + } catch (IOException e) { + Log.e(TAG, "IOException while writing MifareUltralight + message...", e); + } finally { + if (mifare != null) { + try { + mifare.close(); + } + catch (IOException e) { + Log.e(TAG, "Error closing tag...", e); + } + } + } + return null; + } +} +</pre> + +</pre> + + <h2 id="foreground-dispatch">Using the Foreground Dispatch System</h2> + + <p>The foreground dispatch system allows an activity to intercept an intent and claim +priority over other activities that handle the same intent. Using this system involves + constructing a few data structures for the Android system to be able to send the appropriate + intents to your application. To enable the foreground dispatch system:</p> + + <ol> + <li>Add the following code in the <code>onCreate()</code> method of your activity: + + <ol> + <li>Create a {@link android.app.PendingIntent} object so the Android system can populate it + with the details of the tag when it is scanned. + <pre> +PendingIntent pendingIntent = PendingIntent.getActivity( + this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0); +</pre> + </li> + + <li>Declare intent filters to handle the intents that you want to intercept. The foreground + dispatch system checks the specified intent filters with the intent that is received when + the device scans a tag. If it matches, then your application handles the intent. If it does + not match, the foreground dispatch system falls back to the intent dispatch system. + Specifying a <code>null</code> array of intent filters and technology filters, specifies + that you want to filter for all tags that fallback to the <code>TAG_DISCOVERED</code> + intent. The code snippet below handles all MIME types for <code>NDEF_DISCOVERED</code>. You + should only handle the ones that you need. +<pre> +IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED); + try { + ndef.addDataType("*/*"); /* Handles all MIME based dispatches. + You should specify only the ones that you need. */ + } + catch (MalformedMimeTypeException e) { + throw new RuntimeException("fail", e); + } + intentFiltersArray = new IntentFilter[] {ndef, }; +</pre> + </li> + + <li>Set up an array of tag technologies that your application wants to handle. Call the + <code>Object.class.getName()</code> method to obtain the class of the technology that you + want to support. +<pre> +techListsArray = new String[][] { new String[] { NfcF.class.getName() } }; +</pre> + </li> + </ol> + </li> + + <li>Override the following activity lifecycle callbacks and add logic to enable and disable the + foreground dispatch when the activity loses ({@link android.app.Activity#onPause onPause()}) + and regains ({@link android.app.Activity#onResume onResume()}) focus. {@link + android.nfc.NfcAdapter#enableForegroundDispatch enableForegroundDispatch()} must be called from +the main thread and only when the activity is in the foreground (calling in {@link +android.app.Activity#onResume onResume()} guarantees this). You also need to implement the {@link + android.app.Activity#onNewIntent onNewIntent} callback to process the data from the scanned NFC + tag.</li> + +<pre> +public void onPause() { + super.onPause(); + mAdapter.disableForegroundDispatch(this); +} + +public void onResume() { + super.onResume(); + mAdapter.enableForegroundDispatch(this, pendingIntent, intentFiltersArray, techListsArray); +} + +public void onNewIntent(Intent intent) { + Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); + //do something with tagFromIntent +} +</pre> + </li> + </ol> + + <p>See the <a href= +"{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/nfc/ForegroundDispatch.html"> +ForegroundDispatch</a> sample from API Demos for the complete sample.</p>
\ No newline at end of file |