diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs index f3540e272e96e..b7710c3b20b5d 100644 --- a/docs/html/guide/guide_toc.cs +++ b/docs/html/guide/guide_toc.cs @@ -262,20 +262,20 @@
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.
+ +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 Table 1. 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}
+ + +| Class | + +Description | +
|---|---|
| {@link android.nfc.tech.TagTechnology} | + +The interface that all tag technology classes must implement. | +
| {@link android.nfc.tech.NfcA} | + +Provides access to NFC-A (ISO 14443-3A) properties and I/O operations. | +
| {@link android.nfc.tech.NfcB} | + +Provides access to NFC-B (ISO 14443-3B) properties and I/O operations. | +
| {@link android.nfc.tech.NfcF} | + +Provides access to NFC-F (JIS 6319-4) properties and I/O operations. | +
| {@link android.nfc.tech.NfcV} | + +Provides access to NFC-V (ISO 15693) properties and I/O operations. | +
| {@link android.nfc.tech.IsoDep} | + +Provides access to ISO-DEP (ISO 14443-4) properties and I/O operations. | +
| {@link android.nfc.tech.Ndef} | + +Provides access to NDEF data and operations on NFC tags that have been formatted as + NDEF. | +
| {@link android.nfc.tech.NdefFormatable} | + +Provides a format operations for tags that may be NDEF formattable. | +
The following tag technlogies are not required to be supported by Android-powered devices.
++Table 2. Optional supported tag technologies
+| Class | + +Description | +
|---|---|
| {@link android.nfc.tech.MifareClassic} | + +Provides access to MIFARE Classic properties and I/O operations, if this Android device + supports MIFARE. | +
| {@link android.nfc.tech.MifareUltralight} | + +Provides access to MIFARE Ultralight properties and I/O operations, if this Android + device supports MIFARE. | +
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:
+ +Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
get 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 get factory method. For example, to obtain an instance
+of {@link android.nfc.tech.MifareUltralight} from a {@link android.nfc.Tag}, do the following:
+
++MifareUltralight.get(intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)); ++
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.
+ +
+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;
+ }
+}
+
+
+
+
+ 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:
+ +onCreate() method of your activity:
+
+ +PendingIntent pendingIntent = PendingIntent.getActivity( + this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0); ++
null array of intent filters and technology filters, specifies
+ that you want to filter for all tags that fallback to the TAG_DISCOVERED
+ intent. The code snippet below handles all MIME types for NDEF_DISCOVERED. You
+ should only handle the ones that you need.
+
+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, };
+
+ Object.class.getName() method to obtain the class of the technology that you
+ want to support.
+
+techListsArray = new String[][] { new String[] { NfcF.class.getName() } };
+
+
+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
+}
+
+
+ See the +ForegroundDispatch sample from API Demos for the complete sample.
\ No newline at end of file diff --git a/docs/html/guide/topics/nfc/index.jd b/docs/html/guide/topics/nfc/index.jd index b486d3b081e9d..b86d72d418d0e 100644 --- a/docs/html/guide/topics/nfc/index.jd +++ b/docs/html/guide/topics/nfc/index.jd @@ -1,601 +1,33 @@ page.title=Near Field Communication @jd:body -Near Field Communication (NFC) is a set of short-range wireless technologies, typically - requiring a distance of 4cm or less. NFC operates at 13.56mhz, and at rates ranging from 106 - kbit/s to 848 kbit/s. NFC communication always involves an initiator and a target. The initiator - actively generates an RF field that can power a passive target. This enables NFC targets to take - very simple form factors such as tags, stickers or cards that do not require power. NFC - peer-to-peer communication is also possible, where both devices are powered.
+ requiring a distance of 4cm or less to initiate a connection. NFC allows you to share small + payloads of data between an NFC tag and an Android-powered device, or between two Android-powered + devices. -Compared to other wireless technologies such as Bluetooth or WiFi, NFC provides much lower - bandwidth and range, but enables low-cost, un-powered targets and does not require discovery or - pairing. Interactions can be initiated with just a tap.
- -An Android device with NFC hardware will typically act as an initiator when the screen is on. - This mode is also known as NFC reader/writer. It will actively look for NFC tags and start - activities to handle them. Android 2.3.3 also has some limited P2P support.
- -Tags can range in complexity, simple tags just offer read/write semantics, sometimes with +
Tags can range in complexity. Simple tags offer just read and write semantics, sometimes with one-time-programmable areas to make the card read-only. More complex tags offer math operations, and have cryptographic hardware to authenticate access to a sector. The most sophisticated tags - contain operating environments, allowing complex interactions with code executing on the tag.
- -The {@link android.nfc} package contains the high-level classes to interact with the local - device's NFC adapter, to represent discovered tags, and to use the NDEF data format.
- -| Class | - -Description | -
|---|---|
| {@link android.nfc.NfcManager} | - -A high level manager class that enumerates the NFC adapters on this Android device. Since - most Android devices only have one NFC adapter, you can just use the static helper {@link - android.nfc.NfcAdapter#getDefaultAdapter(Context)} for most situations. | -
| {@link android.nfc.NfcAdapter} | - -Represents the local NFC adapter. Defines the intent's used to request tag dispatch to - your activity, and provides methods to register for foreground tag dispatch and foreground - NDEF push. Foreground NDEF push is the only peer-to-peer support that is currently provided - in Android. | -
| {@link android.nfc.NdefMessage} and {@link android.nfc.NdefRecord} | - -NDEF is an NFC Forum defined data structure, designed to efficiently store data on NFC - tags, such as text, URL's, and other MIME types. A {@link android.nfc.NdefMessage} acts as a - container for the data that you want to transmit or read. One {@link android.nfc.NdefMessage} - object contains zero or more {@link android.nfc.NdefRecord}s. Each NDEF record has a type - such as text, URL, smart poster, or any MIME data. The type of the first NDEF record in the - NDEF message is used to dispatch a tag to an activity on Android. | -
| {@link android.nfc.Tag} | - -Represents a passive NFC target. These can come in many form factors such as a tag, card,
- key fob, or even a phone doing card emulation. When a tag is discovered, a {@link
- android.nfc.Tag} object is created and wrapped inside an Intent. The NFC dispatch system
- sends the intent to a compatible activity using startActivity(). You can use the
- {@link android.nfc.Tag#getTechList getTechList()} method to determine the technologies
- supported by this tag and create the corresponding {@link android.nfc.tech.TagTechnology}
- object with one of classes provided by {@link android.nfc.tech}. |
-
The {@link android.nfc.tech} package contains classes to query properties and perform I/O - operations on a tag. The classes are divided to represent different NFC technologies that can be - available on a Tag:
- -| Class | - -Description | -
|---|---|
| {@link android.nfc.tech.TagTechnology} | - -The interface that all tag technology classes must implement. | -
| {@link android.nfc.tech.NfcA} | - -Provides access to NFC-A (ISO 14443-3A) properties and I/O operations. | -
| {@link android.nfc.tech.NfcB} | - -Provides access to NFC-B (ISO 14443-3B) properties and I/O operations. | -
| {@link android.nfc.tech.NfcF} | - -Provides access to NFC-F (JIS 6319-4) properties and I/O operations. | -
| {@link android.nfc.tech.NfcV} | - -Provides access to NFC-V (ISO 15693) properties and I/O operations. | -
| {@link android.nfc.tech.IsoDep} | - -Provides access to ISO-DEP (ISO 14443-4) properties and I/O operations. | -
| {@link android.nfc.tech.Ndef} | - -Provides access to NDEF data and operations on NFC tags that have been formatted as - NDEF. | -
| {@link android.nfc.tech.NdefFormatable} | - -Provides a format operations for tags that may be NDEF formattable. | -
| {@link android.nfc.tech.MifareClassic} | - -Provides access to MIFARE Classic properties and I/O operations, if this Android device - supports MIFARE. | -
| {@link android.nfc.tech.MifareUltralight} | - -Provides access to MIFARE Ultralight properties and I/O operations, if this Android - device supports MIFARE. | -
Before you can access a device's NFC hardware and properly handle NFC intents, declare these
- items in your AndroidManifest.xml file:
<uses-permission> element to access the NFC hardware:
- -<uses-permission android:name="android.permission.NFC" /> --
-<uses-sdk android:minSdkVersion="10"/> --
-<uses-feature android:name="android.hardware.nfc" android:required="true" /> --
-<intent-filter> - <action android:name="android.nfc.action.NDEF_DISCOVERED"/> - <data android:mimeType="mime/type" /> -</intent-filter> - -<intent-filter> - <action android:name="android.nfc.action.TECH_DISCOVERED"/> - <meta-data android:name="android.nfc.action.TECH_DISCOVERED" - android:resource="@xml/nfc_tech_filter.xml" /> -</intent-filter> - -<intent-filter> - <action android:name="android.nfc.action.TAG_DISCOVERED"/> -</intent-filter> -- -
The three intent filters are prioritized and behave in specific ways. Declare only the - ones that your Activity needs to handle. For more information on how to handle these filters, - see the section about The Tag Dispatch System.
-View the AndroidManifest.xml from the - NFCDemo sample to see a complete example.
- -When an Android device scans an NFC tag, the desired behavior is to have the most appropriate - Activity handle the intent without asking the user what application to use. Because devices scan - NFC tags at a very short range, it is likely that making users manually select an Activity forces - them to move the device away from the tag and break the connection. You should develop your - Activity to only handle the NFC tags that your Activity cares about to prevent the Activity - Chooser from appearing. Android provides two systems to help you correctly identify an NFC tag - that your Activity should handle: the Intent dispatch system and the foreground Activity dispatch - system.
- -The intent dispatch system checks the intent filters of all the Activities along with the - types of data that the Activities support to find the best Activity that can handle the NFC tag. - If multiple Activities specify the same intent filter and data to handle, then the Activity - Chooser is presented to the user as a last resort.
- -The foreground dispatch system allows an Activity application to override the intent dispatch - system and have priority when an NFC tag is scanned. The Activity handling the request must be - running in the foreground of the device. When an NFC tag is scanned and matches the intent and - data type that the foreground dispatch Activity defines, the intent is immediately sent to the - Activity even if another Activity can handle the intent. If the Activity cannot handle the - intent, the foreground dispatch system falls back to the intent dispatch system.
- -The intent dispatch system specifies three intents that each have a priority. The intents that - start when a device scans a tag depend on the type of tag scanned. In general, the intents are - started in the following manner:
- -android.nfc.action.NDEF_DISCOVERED: This intent starts when a tag that contains
- an NDEF payload is scanned. This is the highest priority intent. The Android system does not
- let you specify this intent generically to handle all data types. You must specify
- <data> elements in the AndroidManifest.xml along with this
- intent to correctly handle NFC tags that start this intent. For example, to handle a
- NDEF_DISCOVERED intent that contains plain text, specify the following filter in
- your AndroidManifest.xml file:
- -<intent-filter> - <action android:name="android.nfc.action.NDEF_DISCOVERED"/> - <data android:mimeType="text/plain" /> -</intent-filter> -- -
If the NDEF_DISCOVERED intent is started, the TECH_DISCOVERED
- and TAG_DISCOVERED intents are not started. This intent does not start if an
- unknown tag is scanned or if the tag does not contain an NDEF payload.
android.nfc.action.TECH_DISCOVERED: If the NDEF_DISCOVERED intent
- does not start or is not filtered by any Activity on the device, this intent starts if the tag
- is known. The TECH_DISCOVERED intent requires that you specify the technologies
- that you want to support in an XML resource file. For more information, see the section about
- Specifying tag technologies to handle.android.nfc.action.TAG_DISCOVERED: This intent starts if no Activities handle
- the NDEF_DISCOVERED and TECH_DISCOVERED intents or if the tag that is
- scanned is unknown.If your Activity declares the android.nfc.action.TECH_DISCOVERED intent in your
- AndroidManifest.xml file, you must create an XML resource file that specifies the
- technologies that your Activity supports within a tech-list set. Your Activity is
- considered a match if a tech-list set is a subset of the technologies that are
- supported by the tag, which you can obtain by calling {@link android.nfc.Tag#getTechList
- getTechList()}.
For example, if the tag that is scanned supports MifareClassic, NdefFormatable, and NfcA, your
- tech-list set must specify all three, two, or one of the technologies (and nothing
- else) in order for your Activity to be matched.
The following sample defines all of the technologies. You can remove the ones that you do not
- need. Save this file (you can name it anything you wish) in the
- <project-root>/res/xml folder.
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <tech-list> - <tech>android.nfc.tech.IsoDep</tech> - <tech>android.nfc.tech.NfcA</tech> - <tech>android.nfc.tech.NfcB</tech> - <tech>android.nfc.tech.NfcF</tech> - <tech>android.nfc.tech.NfcV</tech> - <tech>android.nfc.tech.Ndef</tech> - <tech>android.nfc.tech.NdefFormatable</tech> - <tech>android.nfc.tech.MifareClassic</tech> - <tech>android.nfc.tech.MifareUltralight</tech> - </tech-list> -</resources> -- -
You can also specify multiple tech-list sets. Each of the tech-list
- sets is considered independently, and your Activity is considered a match if any single
- tech-list set is a subset of the technologies that are returned by {@link
- android.nfc.Tag#getTechList getTechList()}. This provides AND and OR
- semantics for matching technologies. The following example matches tags that can support the
- NfcA and Ndef technologies or can support the NfcB and Ndef technologies:
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <tech-list> - <tech>android.nfc.tech.NfcA</tech> - <tech>android.nfc.tech.Ndef</tech> - </tech-list> -</resources> - -<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <tech-list> - <tech>android.nfc.tech.NfcB</tech> - <tech>android.nfc.tech.Ndef</tech> - </tech-list> -</resources> -- -
In your AndroidManifest.xml file, specify the resource file that you just created
- in the <meta-data> element inside the <activity>
- element like in the following example:
-<activity> -... -<intent-filter> - <action android:name="android.nfc.action.TECH_DISCOVERED"/> -</intent-filter> - -<meta-data android:name="android.nfc.action.TECH_DISCOVERED" - android:resource="@xml/nfc_tech_filter" /> -... -</activity> -- -
The foreground dispatch system allows an Activity to intercept an intent and claim priority - over other Activities that handle the same intent. The system is easy to use and 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:
- --PendingIntent pendingIntent = PendingIntent.getActivity( - this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0); --
null array of intent filters and for the technology filters, you
- receive a TAG_DISCOVERED intent for all tags discovered. Note that the snippet
- below handles all MIME types. You should only handle the ones that you need.
-
- 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,
- };
-
- Object.class.getName() method to obtain the class of the technology that you
- want to support.
-
-
- techListsArray = new String[][] { new String[] { NfcF.class.getName() } };
-
-
-
-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
-}
-
- See the ForegroundDispatch - sample from API Demos for the complete sample.
- -Data on NFC tags are encoded in raw bytes, so you must convert the bytes to something human - readable if you are presenting the data to the user. When writing to NFC tags, you must write - them in bytes as well. Android provides APIs to help write messages that conform to the NDEF - standard, which was developed by the NFC Forum to - standardized data on tags. Using this standard ensures that your data will be supported by all - Android NFC devices if you are writing to tags. However, many tag technologies use their own - standard for storing data and are supported by Android as well, but you have to implement your - own protocol stack to read and write to these tags. You can find a full list of the supported - technologies in {@link android.nfc.tech} and an overview of the technologies in the {@link - android.nfc.tech.TagTechnology} interface. This section is a brief overview of how to work with - NDEF messages in the context of the Android system. It is not meant to be a complete discussion - of the NDEF specification, but highlights the main things that you need to be aware of when - working with NDEF messages in Android.
- -To facilitate working with NDEF messages, Android provides the {@link android.nfc.NdefRecord} - and {@link android.nfc.NdefMessage} to encapsulate the raw bytes that represent NDEF messages. An - {@link android.nfc.NdefMessage} is the container for zero or more {@link - android.nfc.NdefRecord}s. Each {@link android.nfc.NdefRecord} has its own unique type name - format, record type, and ID to distinguish them from other records within the same {@link - android.nfc.NdefMessage}. You can store different types of records of varying length in a single - {@link android.nfc.NdefMessage}. The size constraint of the NFC tag determines how big your - {@link android.nfc.NdefMessage} can be.
- -Tags that support the {@link android.nfc.tech.Ndef} and {@link - android.nfc.tech.NdefFormatable} technologies return and accept {@link android.nfc.NdefMessage} - objects as parameters for read and write operations. You need to create your own logic to read - and write bytes for other tag technologies in {@link android.nfc.tech}.
- -You can download technical specifications for different types of NDEF message standards, such - as plain text and Smart Posters, at the NFC Forum - website. The NFCDemo sample application also declares sample - plain text and SmartPoster NDEF messages.
- -When a device comes in proximity to an NFC tag, the appropriate intent is started on the
- device, notifying interested applications that a NFC tag was scanned. By previously declaring the
- appropriate intent filter in your AndroidManifest.xml file or using foreground
- dispatching, your application can request to handle the intent.
The following method (slightly modified from the NFCDemo sample application), handles the
- TAG_DISCOVERED intent and iterates through an array obtained from the intent that
- contains the NDEF payload:
-NdefMessage[] getNdefMessages(Intent intent) {
- // Parse the intent
- NdefMessage[] msgs = null;
- String action = intent.getAction();
- if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)) {
- Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
- if (rawMsgs != null) {
- msgs = new NdefMessage[rawMsgs.length];
- for (int i = 0; i < rawMsgs.length; i++) {
- msgs[i] = (NdefMessage) rawMsgs[i];
- }
- }
- else {
- // Unknown tag type
- byte[] empty = new byte[] {};
- NdefRecord record = new NdefRecord(NdefRecord.TNF_UNKNOWN, empty, empty, empty);
- NdefMessage msg = new NdefMessage(new NdefRecord[] {record});
- msgs = new NdefMessage[] {msg};
- }
- }
- else {
- Log.e(TAG, "Unknown intent " + intent);
- finish();
- }
- return msgs;
-}
-
-
- Keep in mind that the data that the device reads is in bytes, so you must implement your own
- logic if you need to present the data in a readable format to the user. The classes in
- com.example.android.nfc.record of the NFCDemo sample show you how to parse some
- common types of NDEF messages such as plain text or a SmartPoster.
Writing to an NFC tag involves constructing your NDEF message in bytes and using the - appropriate tag technology for the tag that you are writing to. The following code sample shows - you how to write a simple text message to a {@link android.nfc.tech.NdefFormatable} tag:
-
-NdefFormatable tag = NdefFormatable.get(t);
-Locale locale = Locale.US;
-final byte[] langBytes = locale.getLanguage().getBytes(Charsets.US_ASCII);
-String text = "Tag, you're it!";
-final byte[] textBytes = text.getBytes(Charsets.UTF_8);
-final int utfBit = 0;
-final char status = (char) (utfBit + langBytes.length);
-final byte[] data = Bytes.concat(new byte[] {(byte) status}, langBytes, textBytes);
-NdefRecord record = NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], data);
-try {
- NdefRecord[] records = {text};
- NdefMessage message = new NdefMessage(records);
- tag.connect();
- tag.format(message);
-}
-catch (Exception e){
- //do error handling
-}
-
-
- Support for simple peer-to-peer data exchange is supported by the foreground push feature, - which is enabled with the {@link android.nfc.NfcAdapter#enableForegroundNdefPush} method. To use - this feature:
- -com.android.npp NDEF push protocol, which is optional for Android devices.If your Activity enables the foreground push feature and is in the foreground, - the standard intent dispatch system is disabled. However, if your Activity also enables - foreground dispatching, then it can still scan tags that match the intent filters set in the - foreground dispatching.
- -To enable foreground dispatching:
- -
-public void onResume() {
- super.onResume();
- if (mAdapter != null)
- mAdapter.enableForegroundNdefPush(this, myNdefMessage);
-}
-public void onPause() {
- super.onPause();
- if (mAdapter != null)
- mAdapter.disableForegroundNdefPush(this);
-}
-
- When the Activity is in the foreground, you can now tap the device to another device and push - the data to it. See the ForegroundNdefPush - sample in API Demos for a simple example of peer-to-peer data exchange.
\ No newline at end of file + contain operating environments, allowing complex interactions with code executing on the tag. + The data stored in the tag can also be written in a variety of formats, but many of the Android + framework APIs are based around a NFC Forum standard + called NDEF (NFC Data Exchange Format). + +This document describes the basic NFC tasks you perform in Android. It explains how to send and +receive NFC data in the form of NDEF messages and describes the Android framework APIs that support +these features. For more advanced topics, including a discussion of working with non-NDEF data, +see Advanced NFC.
+ + +There are two major uses cases when working with NDEF data and Android:
+ +Reading NDEF data from an NFC tag is handled with the tag dispatch +system, which analyzes discovered NFC tags, appropriately categorizes the data, and starts +an application that is interested in the categorized data. An application that wants to handle the +scanned NFC tag can declare an intent filter and +request to handle the data.
+ +The Android Beam™ feature allows a device to push an NDEF message onto +another device by physically tapping the devices together. This interaction provides an easier way +to send data than other wireless technologies like Bluetooth, because with NFC, no manual device +discovery or pairing is required. The connection is automatically started when two devices come +into range. Android Beam is available through a set of NFC APIs, so any application can transmit +information between devices. For example, the Contacts, Browser, and YouTube applications use +Android Beam to share contacts, web pages, and videos with other devices. +
+ + +Android-powered devices are usually looking for NFC tags when the screen +is unlocked, unless NFC is disabled in the device's Settings menu. +When an Android-powered device discovers an NFC tag, the desired behavior +is to have the most appropriate activity handle the intent without asking the user what application +to use. Because devices scan NFC tags at a very short range, it is likely that making users manually +select an activity would force them to move the device away from the tag and break the connection. +You should develop your activity to only handle the NFC tags that your activity cares about to +prevent the Activity Chooser from appearing.
+ +To help you with this goal, Android provides a special tag dispatch system that analyzes scanned +NFC tags, parses them, and tries to locate applications that are interested in the scanned data. It +does this by:
+ +Before you begin writing your NFC applications, it is important to understand the different +types of NFC tags, how the tag dispatch system parses NFC tags, and the special work that the tag +dispatch system does when it detects an NDEF message. NFC tags come in a +wide array of technologies and can also have data written to them in many different ways. +Android has the most support for the NDEF standard, which is defined by the NFC Forum. +
+ +NDEF data is encapsulated inside a message ({@link android.nfc.NdefMessage}) that contains one +or more records ({@link android.nfc.NdefRecord}). Each NDEF record must be well-formed according to +the specification of the type of record that you want to create. Android +also supports other types of tags that do not contain NDEF data, which you can work with by using +the classes in the {@link android.nfc.tech} package. To learn more +about these technologies, see the Advanced +NFC topic. Working with these other types of tags involves +writing your own protocol stack to communicate with the tags, so we recommend using NDEF when +possible for ease of development and maximum support for Android-powered devices. +
+ +Note: +To download complete NDEF specifications, go to the NFC Forum Specification Download site and see +Creating common types of NDEF records for examples of how to +construct NDEF records.
+ +Now that you have some background in NFC tags, the following sections describe in more detail how +Android handles NDEF formatted tags. When an Android-powered device scans an NFC tag containing NDEF +formatted data, it parses the message and tries to figure out the data's MIME type or identifying +URI. To do this, the system reads the first {@link android.nfc.NdefRecord} inside the {@link +android.nfc.NdefMessage} to determine how to interpret the entire NDEF message (an NDEF message can +have multiple NDEF records). In a well-formed NDEF message, the first {@link android.nfc.NdefRecord} +contains the following fields: +
The tag dispatch system uses the TNF and type fields to try to map a MIME type or URI to the +NDEF message. If successful, it encapsulates that information inside of a {@link +android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} intent along with the actual payload. However, there +are cases when the tag dispatch system cannot determine the type of data based on the first NDEF +record. This happens when the NDEF data cannot be mapped to a MIME type or URI, or when the +NFC tag does not contain NDEF data to begin with. In such cases, a {@link +android.nfc.Tag} object that has information about the tag's technologies and the payload are +encapsulated inside of a {@link android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED} intent instead.
+ ++Table 1. describes how the tag dispatch system maps TNF and type +fields to MIME types or URIs. It also describes which TNFs cannot be mapped to a MIME type or URI. +In these cases, the tag dispatch system falls back to +{@link android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED}. + +
For example, if the tag dispatch system encounters a record of type {@link +android.nfc.NdefRecord#TNF_ABSOLUTE_URI}, it maps the variable length type field of that record +into a URI. The tag dispatch system encapsulates that URI in the data field of an {@link +android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} intent along with other information about the tag, +such as the payload. On the other hand, if it encounters a record of type {@link +android.nfc.NdefRecord#TNF_UNKNOWN}, it creates an intent that encapsulates the tag's technologies +instead.
+ + ++ Table 1. Supported TNFs and their mappings
+| Type Name Format (TNF) | +Mapping | +
|---|---|
| {@link android.nfc.NdefRecord#TNF_ABSOLUTE_URI} | +URI based on the type field. | +{@link android.nfc.NdefRecord#TNF_EMPTY} | +Falls back to {@link android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED}. | + +{@link android.nfc.NdefRecord#TNF_EXTERNAL_TYPE} | +URI based on the URN in the type field. The URN is encoded into the NDEF type field in
+ a shortened form: <domain_name>:<service_name>.
+ Android maps this to a URI in the form:
+ vnd.android.nfc://ext/<domain_name>:<service_name>. |
+
+ {@link android.nfc.NdefRecord#TNF_MIME_MEDIA} | +MIME type based on the type field. | + +{@link android.nfc.NdefRecord#TNF_UNCHANGED} | +Invalid in the first record, so falls back to + {@link android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED}. | + +{@link android.nfc.NdefRecord#TNF_UNKNOWN} | +Falls back to {@link android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED}. | + +{@link android.nfc.NdefRecord#TNF_WELL_KNOWN} | +MIME type or URI depending on the Record Type Definition (RTD), which you set in the +type field. See Table 2. for more information on +available RTDs and their mappings. | + +
+ Table 2. Supported RTDs for TNF_WELL_KNOWN and their +mappings
+| Record Type Definition (RTD) | +Mapping | +
|---|---|
| {@link android.nfc.NdefRecord#RTD_ALTERNATIVE_CARRIER} | +Falls back to {@link android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED}. | +{@link android.nfc.NdefRecord#RTD_HANDOVER_CARRIER} | +Falls back to {@link android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED}. | + +{@link android.nfc.NdefRecord#RTD_HANDOVER_REQUEST} | +Falls back to {@link android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED}. | + +{@link android.nfc.NdefRecord#RTD_HANDOVER_SELECT} | +Falls back to {@link android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED}. | + +{@link android.nfc.NdefRecord#RTD_SMART_POSTER} | +URI based on parsing the payload. | + +{@link android.nfc.NdefRecord#RTD_TEXT} | +MIME type of text/plain. |
+
+ {@link android.nfc.NdefRecord#RTD_URI} | +URI based on payload. | + +
When the tag dispatch system is done creating an intent that encapsulates the NFC tag and its +identifying information, it sends the intent to an interested application that +filters for the intent. If more than one application can handle the intent, the Activity Chooser +is presented so the user can select the Activity. The tag dispatch system defines three intents, +which are listed in order of highest to lowest priority:
+ +The basic way the tag dispatch system works is as follows:
+ +
+
+Figure 1. Tag Dispatch System
+ + +Whenever possible, work with NDEF messages and the {@link +android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} intent, because it is the most specific out of +the three. This intent allows you to start your application at a more appropriate time than the +other two intents, giving the user a better experience.
+ +Before you can access a device's NFC hardware and properly handle NFC intents, declare these
+ items in your AndroidManifest.xml file:
<uses-permission> element to access the NFC hardware:
+ +<uses-permission android:name="android.permission.NFC" /> ++
+<uses-sdk android:minSdkVersion="10"/> ++
uses-feature element so that your application shows up in the Android
+Market only for devices that have NFC hardware:
+ +<uses-feature android:name="android.hardware.nfc" android:required="true" /> ++
If your application uses NFC functionality, but that functionality is not crucial to your
+application, you can omit the uses-feature element and check for NFC avalailbility at
+runtime by checking to see if {@link android.nfc.NfcAdapter#getDefaultAdapter getDefaultAdapter()}
+is null.
To start your application when an NFC tag that you want to handle is scanned, your application +can filter for one, two, or all three of the NFC intents in the Android manifest. However, you +usually want to filter for the {@link android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} intent for the +most control of when your application starts. The {@link +android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED} intent is a fallback for {@link +android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} when no applications filter for + {@link android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} or for when the payload is not +NDEF. Filtering for {@link android.nfc.NfcAdapter#ACTION_TAG_DISCOVERED} is usually too general of a +category to filter on. Many applications will filter for {@link +android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} or {@link +android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED} before {@link +android.nfc.NfcAdapter#ACTION_TAG_DISCOVERED}, so your application has a low probability of +starting. {@link android.nfc.NfcAdapter#ACTION_TAG_DISCOVERED} is only available as a last resort +for applications to filter for in the cases where no other applications are installed to handle the +{@link android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} or {@link +android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED}intent.
+ +Because NFC tag deployments vary and are many times not under your control, this is not always +possible, which is why you can fallback to the other two intents when necessary. When you have +control over the types of tags and data written, it is recommended that you use NDEF to format your +tags. The following sections describe how to filter for each type of intent.
+ + +
+To filter for {@link android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} intents, declare the
+intent filter along with the type of data that you want to filter for. The
+following example filters for {@link android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED}
+intents with a MIME type of text/plain:
+
+<intent-filter> + <action android:name="android.nfc.action.NDEF_DISCOVERED"/> + <category android:name="android.intent.category.DEFAULT"/> + <data android:mimeType="text/plain" /> +</intent-filter> ++
The following example filters for a URI in the form of
+http://developer.android.com/index.html.
+
+<intent-filter> + <action android:name="android.nfc.action.NDEF_DISCOVERED"/> + <category android:name="android.intent.category.DEFAULT"/> + <data android:scheme="http" + android:host="developer.android.com" + android:pathPrefix="/index.html" /> +</intent-filter> ++ + +
If your activity filters for the {@link android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED} intent,
+you must create an XML resource file that specifies the technologies that your activity supports
+within a tech-list set. Your activity is
+ considered a match if a tech-list set is a subset of the technologies that are
+ supported by the tag, which you can obtain by calling {@link android.nfc.Tag#getTechList
+ getTechList()}.
For example, if the tag that is scanned supports MifareClassic, NdefFormatable, and NfcA, your
+ tech-list set must specify all three, two, or one of the technologies (and nothing
+ else) in order for your activity to be matched.
The following sample defines all of the technologies. You can remove the ones that you do not
+ need. Save this file (you can name it anything you wish) in the
+ <project-root>/res/xml folder.
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <tech-list> + <tech>android.nfc.tech.IsoDep</tech> + <tech>android.nfc.tech.NfcA</tech> + <tech>android.nfc.tech.NfcB</tech> + <tech>android.nfc.tech.NfcF</tech> + <tech>android.nfc.tech.NfcV</tech> + <tech>android.nfc.tech.Ndef</tech> + <tech>android.nfc.tech.NdefFormatable</tech> + <tech>android.nfc.tech.MifareClassic</tech> + <tech>android.nfc.tech.MifareUltralight</tech> + </tech-list> +</resources> ++ +
You can also specify multiple tech-list sets. Each of the tech-list
+ sets is considered independently, and your activity is considered a match if any single
+ tech-list set is a subset of the technologies that are returned by {@link
+ android.nfc.Tag#getTechList getTechList()}. This provides AND and OR
+ semantics for matching technologies. The following example matches tags that can support the
+ NfcA and Ndef technologies or can support the NfcB and Ndef technologies:
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <tech-list> + <tech>android.nfc.tech.NfcA</tech> + <tech>android.nfc.tech.Ndef</tech> + </tech-list> +</resources> + +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <tech-list> + <tech>android.nfc.tech.NfcB</tech> + <tech>android.nfc.tech.Ndef</tech> + </tech-list> +</resources> ++ +
In your AndroidManifest.xml file, specify the resource file that you just created
+ in the <meta-data> element inside the <activity>
+ element like in the following example:
+<activity> +... +<intent-filter> + <action android:name="android.nfc.action.TECH_DISCOVERED"/> +</intent-filter> + +<meta-data android:name="android.nfc.action.TECH_DISCOVERED" + android:resource="@xml/nfc_tech_filter" /> +... +</activity> ++ +
For more information about working with tag technologies and the {@link +android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED} intent, see Working with Supported Tag +Technologies in the Advanced NFC document.
+To filter for {@link android.nfc.NfcAdapter#ACTION_TAG_DISCOVERED} use the following intent +filter:
+ + +<intent-filter> + <action android:name="android.nfc.action.TAG_DISCOVERED"/> +</intent-filter> ++ + + +
If an activity starts because of an NFC intent, you can obtain information about the scanned NFC +tag from the intent. Intents can contain the following extras depending on the tag that was scanned: + +
To obtain these extras, check to see if your activity was launched with one of +the NFC intents to ensure that a tag was scanned, and then obtain the extras out of the +intent. The following example checks for the {@link android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} +intent and gets the NDEF messages from an intent extra.
+ +
+public void onResume() {
+ super.onResume();
+ ...
+ if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
+ Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
+ if (rawMsgs != null) {
+ msgs = new NdefMessage[rawMsgs.length];
+ for (int i = 0; i < rawMsgs.length; i++) {
+ msgs[i] = (NdefMessage) rawMsgs[i];
+ }
+ }
+ }
+ //process the msgs array
+}
+
+
+Alternatively, you can obtain a {@link android.nfc.Tag} object from the intent, which will +contain the payload and allow you to enumerate the tag's technologies:
+ +Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);+ + +
This section describes how to create common types of NDEF records to help you when writing to +NFC tags or sending data with Android Beam. It also describes how to create the corresponding +intent filter for the record. All of these NDEF record examples should be in the first NDEF +record of the NDEF message that you are writing to a tag or beaming.
+ +Given the following {@link android.nfc.NdefRecord#TNF_ABSOLUTE_URI} NDEF record, which is +stored as the first record inside of an {@link android.nfc.NdefMessage}:
+ +
+NdefRecord uriRecord = new NdefRecord(
+ NdefRecord.TNF_ABSOLUTE_URI ,
+ "http://developer.android.com/index.html".getBytes(Charset.forName("US-ASCII")),
+ new byte[0], new byte[0]);
+
+
+the intent filter would look like this:
++<intent-filter> + <action android:name="android.nfc.action.NDEF_DISCOVERED" /> + <category android:name="android.intent.category.DEFAULT" /> + <data android:scheme="http" + android:host="developer.android.com" + android:pathPrefix="/index.html" /> +</intent-filter> ++ + +
Given the following {@link android.nfc.NdefRecord#TNF_MIME_MEDIA} NDEF record, which is stored as +the first record inside +of an {@link android.nfc.NdefMessage}:
+
+NdefRecord mimeRecord = new NdefRecord(
+ NdefRecord.TNF_MIME_MEDIA ,
+ "application/com.example.android.beam".getBytes(Charset.forName("US-ASCII")),
+ new byte[0], "Beam me up, Android!".getBytes(Charset.forName("US-ASCII")));
+
+
+the intent filter would look like this:
++<intent-filter> + <action android:name="android.nfc.action.NDEF_DISCOVERED" /> + <category android:name="android.intent.category.DEFAULT" /> + <data android:mimeType="application/com.example.android.beam" /> +</intent-filter> ++ + +
Given the following {@link android.nfc.NdefRecord#TNF_WELL_KNOWN} NDEF record, which is stored as +the first record inside of an {@link android.nfc.NdefMessage}:
+
+public NdefRecord createTextRecord(String payload, Locale locale, boolean encodeInUtf8) {
+ byte[] langBytes = locale.getLanguage().getBytes(Charset.forName("US-ASCII"));
+ Charset utfEncoding = encodeInUtf8 ? Charset.forName("UTF-8") : Charset.forName("UTF-16");
+ byte[] textBytes = payload.getBytes(utfEncoding);
+ int utfBit = encodeInUtf8 ? 0 : (1 << 7);
+ char status = (char) (utfBit + langBytes.length);
+ byte[] data = new byte[1 + langBytes.length + textBytes.length];
+ data[0] = (byte) status;
+ System.arraycopy(langBytes, 0, data, 1, langBytes.length);
+ System.arraycopy(textBytes, 0, data, 1 + langBytes.length, textBytes.length);
+ NdefRecord record = new NdefRecord(NdefRecord.TNF_WELL_KNOWN,
+ NdefRecord.RTD_TEXT, new byte[0], data);
+ return record;
+}
+
+
+the intent filter would look like this:
++<intent-filter> + <action android:name="android.nfc.action.NDEF_DISCOVERED" /> + <category android:name="android.intent.category.DEFAULT" /> + <data android:mimeType="text/plain" /> +</intent-filter> ++ + +
Given the following {@link android.nfc.NdefRecord#TNF_WELL_KNOWN} NDEF record, which is stored as +the first record inside of an {@link android.nfc.NdefMessage}:
+ +
+byte[] uriField = "example.com".getBytes(Charset.forName("US-ASCII"));
+byte[] payload = new byte[uriField.length + 1]; //add 1 for the URI Prefix
+byte payload[0] = 0x01; //prefixes http://www. to the URI
+System.arraycopy(uriField, 0, payload, 1, uriField.length); //appends URI to payload
+NdefRecord rtdUriRecord = new NdefRecord(
+ NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_URI, new byte[0], payload);
+
+
+the intent filter would look like this:
+ ++<intent-filter> + <action android:name="android.nfc.action.NDEF_DISCOVERED" /> + <category android:name="android.intent.category.DEFAULT" /> + <data android:scheme="http" + android:host="example.com" + android:pathPrefix="" /> +</intent-filter> ++ +
Given the following {@link android.nfc.NdefRecord#TNF_EXTERNAL_TYPE} NDEF record, which is stored +as the first record inside of an {@link android.nfc.NdefMessage}:
+ ++byte[] payload; +... +NdefRecord mimeRecord = new NdefRecord( + NdefRecord.TNF_EXTERNAL_TYPE, "example.com:externalType", new byte[0], payload); ++ +
the intent filter would look like this:
++<intent-filter> + <action android:name="android.nfc.action.NDEF_DISCOVERED" /> + <category android:name="android.intent.category.DEFAULT" /> + <data android:scheme="vnd.android.nfc" + android:host="ext" + android:pathPrefix="/example.com:externalType"/> +</intent-filter> ++ + +
Use TNF_EXTERNAL_TYPE for more generic NFC tag deployments to better support both +Android-powered and non-Android-powered devices.
+ +Note: URNs for {@link
+android.nfc.NdefRecord#TNF_EXTERNAL_TYPE} have a canonical format of:
+urn:nfc:ext:example.com:externalType, however the NFC Forum RTD specification
+declares that the urn:nfc:ext: portion of the URN must be ommitted from the
+NDEF record. So all you need to provide is the domain (example.com in the example)
+and type (externalType in the example) separated by a colon.
+When dispatching TNF_EXTERNAL_TYPE, Android converts the urn:nfc:ext:example.com:externalType URN to a
+vnd.android.nfc://ext/example.com:externalType URI, which is what the intent filter in the example
+declares.
+Introduced in Android 4.0 (API level 14), an Android Application Record (AAR) provides a stronger +certainty that your application is started when an NFC tag is scanned. An AAR has the package name +of an application embedded inside an NDEF record. You can add an AAR to any NDEF record of your NDEF message, +because Android searches the entire NDEF message for AARs. If it finds an AAR, it starts the application based +on the package name inside the AAR. If the application is not present on the device, +Android Market is launched to download the application.
+ +AARs are useful if you want to prevent other applications from filtering for the same intent and +potentially handling specific tags that you have deployed. AARs are only supported at the +application level, because of the package name constraint, and not at the Activity level as with +intent filtering. If you want to handle an intent at the Activity level, use intent filters. +
+ + + +If a tag contains an AAR, the tag dispatch system dispatches in the following manner:
+Note: You can override AARs and the intent dispatch system with the foreground dispatch +system, which allows a foreground activity to have priority when an NFC tag is discovered. +With this method, the activity must be in the foreground to +override AARs and the intent dispatch system.
+ +If you still want to filter for scanned tags that do not contain an AAR, you can declare +intent filters as normal. This is useful if your application is interested in other tags +that do not contain an AAR. For example, maybe you want to guarantee that your application handles +proprietary tags that you deploy as well as general tags deployed by third parties. Keep in mind +that AARs are specific to Android 4.0 devices or later, so when deploying tags, you most likely want +to use a combination of AARs and MIME types/URIs to support the widest range of devices. In +addition, when you deploy NFC tags, think about how you want to write your NFC tags to enable +support for the most devices (Android-powered and other devices). You can do this by +defining a relatively unique MIME type or URI to make it easier for applications to distinguish. +
+ +Android provides a simple API to create an AAR, +{@link android.nfc.NdefRecord#createApplicationRecord createApplicationRecord()}. All you need to +do is embed the AAR anywhere in your {@link android.nfc.NdefMessage}. You do not want +to use the first record of your {@link android.nfc.NdefMessage}, unless the AAR is the only +record in the {@link android.nfc.NdefMessage}. This is because the Android +system checks the first record of an {@link android.nfc.NdefMessage} to determine the MIME type or +URI of the tag, which is used to create an intent for applications to filter. The following code +shows you how to create an AAR:
+ +
+NdefMessage msg = new NdefMessage(
+ new NdefRecord[] {
+ ...,
+ NdefRecord.createApplicationRecord("com.example.android.beam")}
+
+
+
+Android Beam allows simple peer-to-peer data exchange between two Android-powered devices. The +application that wants to beam data to another device must be in the foreground and the device +receiving the data must not be locked. When the beaming device comes in close enough contact with a +receiving device, the beaming device displays the "Touch to Beam" UI. The user can then choose +whether or not to beam the message to the receiving device.
+ +Note: Foreground NDEF pushing was available at API level 10, +which provides similar functionality to Android Beam. These APIs have since been deprecated, but +are available to support older devices. See {@link android.nfc.NfcAdapter#enableForegroundNdefPush +enableForegroundNdefPush()} for more information.
+ +You can enable Android Beam for your application by calling one of the two methods:
+An activity can only push one NDEF message at a time, so {@link +android.nfc.NfcAdapter#setNdefPushMessageCallback setNdefPushMessageCallback()} takes precedence +over {@link android.nfc.NfcAdapter#setNdefPushMessage setNdefPushMessage()} if both are set. To use +Android Beam, the following general guidelines must be met: +
+ +com.android.npp NDEF push protocol or NFC Forum's SNEP (Simple NDEF Exchange
+Protocol). The com.android.npp protocol is required for devices on API level 9 (Android
+2.3) to API level 13 (Android 3.2). com.android.npp and SNEP are both required on
+API level 14 (Android 4.0) and later.Note: If your activity enables Android Beam and is +in the foreground, the standard intent dispatch system is disabled. However, if your activity also +enables foreground +dispatching, then it can still scan tags that match the intent filters set in the foreground +dispatching.
+ +To enable Android Beam:
+ +onCreate() method of
+your activity. These methods require at least one activity that you want to enable with Android
+Beam, along with an optional list of other activities to activate.
+
+In general, you normally use {@link +android.nfc.NfcAdapter#setNdefPushMessage setNdefPushMessage()} if your Activity only needs to +push the same NDEF message at all times, when two devices are in range to communicate. You use +{@link android.nfc.NfcAdapter#setNdefPushMessageCallback setNdefPushMessageCallback} when your +application cares about the current context of the application and wants to push an NDEF message +depending on what the user is doing in your application.
+The following sample shows how a simple activity calls {@link
+android.nfc.NfcAdapter.CreateNdefMessageCallback} in the onCreate() method of an
+activity (see for the
+complete sample). This example also has methods to help you create a MIME record:
+package com.example.android.beam;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.nfc.NdefMessage;
+import android.nfc.NdefRecord;
+import android.nfc.NfcAdapter;
+import android.nfc.NfcAdapter.CreateNdefMessageCallback;
+import android.nfc.NfcEvent;
+import android.os.Bundle;
+import android.os.Parcelable;
+import android.widget.TextView;
+import android.widget.Toast;
+import java.nio.charset.Charset;
+
+
+public class Beam extends Activity implements CreateNdefMessageCallback {
+ NfcAdapter mNfcAdapter;
+ TextView textView;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main);
+ TextView textView = (TextView) findViewById(R.id.textView);
+ // Check for available NFC Adapter
+ mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
+ if (mNfcAdapter == null) {
+ Toast.makeText(this, "NFC is not available", Toast.LENGTH_LONG).show();
+ finish();
+ return;
+ }
+ // Register callback
+ mNfcAdapter.setNdefPushMessageCallback(this, this);
+ }
+
+ @Override
+ public NdefMessage createNdefMessage(NfcEvent event) {
+ String text = ("Beam me up, Android!\n\n" +
+ "Beam Time: " + System.currentTimeMillis());
+ NdefMessage msg = new NdefMessage(
+ new NdefRecord[] { createMimeRecord(
+ "application/com.example.android.beam", text.getBytes())
+ /**
+ * The Android Application Record (AAR) is commented out. When a device
+ * receives a push with an AAR in it, the application specified in the AAR
+ * is guaranteed to run. The AAR overrides the tag dispatch system.
+ * You can add it back in to guarantee that this
+ * activity starts when receiving a beamed message. For now, this code
+ * uses the tag dispatch system.
+ */
+ //,NdefRecord.createApplicationRecord("com.example.android.beam")
+ });
+ return msg;
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ // Check to see that the Activity started due to an Android Beam
+ if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
+ processIntent(getIntent());
+ }
+ }
+
+ @Override
+ public void onNewIntent(Intent intent) {
+ // onResume gets called after this to handle the intent
+ setIntent(intent);
+ }
+
+ /**
+ * Parses the NDEF Message from the intent and prints to the TextView
+ */
+ void processIntent(Intent intent) {
+ textView = (TextView) findViewById(R.id.textView);
+ Parcelable[] rawMsgs = intent.getParcelableArrayExtra(
+ NfcAdapter.EXTRA_NDEF_MESSAGES);
+ // only one message sent during the beam
+ NdefMessage msg = (NdefMessage) rawMsgs[0];
+ // record 0 contains the MIME type, record 1 is the AAR, if present
+ textView.setText(new String(msg.getRecords()[0].getPayload()));
+ }
+
+ /**
+ * Creates a custom MIME type encapsulated in an NDEF record
+ */
+ public NdefRecord createMimeRecord(String mimeType, byte[] payload) {
+ byte[] mimeBytes = mimeType.getBytes(Charset.forName("US-ASCII"));
+ NdefRecord mimeRecord = new NdefRecord(
+ NdefRecord.TNF_MIME_MEDIA, mimeBytes, new byte[0], payload);
+ return mimeRecord;
+ }
+}
+
+
+Note that this code comments out an AAR, which you can remove. If you enable the AAR, the +application specified in the AAR always receives the Android Beam message. If the application is not +present, the Android Market is started to download the application. Therefore, the following intent +filter is not technically necessary for Android 4.0 devices or later if the AAR is used: +
+ ++<intent-filter> + <action android:name="android.nfc.action.NDEF_DISCOVERED"/> + <category android:name="android.intent.category.DEFAULT"/> + <data android:mimeType="application/com.example.android.beam"/> +</intent-filter> ++
With this intent filter, the com.example.android.beam application now can be started
+when it scans an NFC tag or receives an Android Beam with an AAR of
+type com.example.android.beam, or when an NDEF formatted message contains a MIME record
+of type application/com.example.android.beam.
Even though AARs guarantee an application is started or downloaded, intent filters are +recommended, because they let you start an Activity of your choice in your +application instead of always starting the main Activity within the package specified by an AAR. +AARs do not have Activity level granularity. Also, because some Android-powered devices do not +support AARs, you should also embed identifying information in the first NDEF record of your NDEF +messages and filter for that as well, just in case. See Creating Common +Types of NDEF records for more information on how to create records. +
diff --git a/docs/html/images/nfc_tag_dispatch.png b/docs/html/images/nfc_tag_dispatch.png new file mode 100644 index 0000000000000..70ed71102797c Binary files /dev/null and b/docs/html/images/nfc_tag_dispatch.png differ