From a8d3f02aaae6423bb969916d64283d3559faa3ff Mon Sep 17 00:00:00 2001 From: Nick Pelly Date: Wed, 2 Feb 2011 22:37:40 -0800 Subject: [PATCH] DO NOT MERGE Reconcile documentation updates from gingerbread to honeycomb. Change-Id: I8c199906beb5cd3c290ded123d6aefd0d1697f30 --- core/java/android/nfc/NfcAdapter.java | 183 ++++++++--- core/java/android/nfc/NfcSecureElement.java | 24 +- core/java/android/nfc/Tag.java | 119 ++++++-- core/java/android/nfc/tech/IsoDep.java | 91 ++++-- core/java/android/nfc/tech/MifareClassic.java | 288 ++++++++++++++---- .../android/nfc/tech/MifareUltralight.java | 103 +++++-- core/java/android/nfc/tech/Ndef.java | 162 +++++++--- .../java/android/nfc/tech/NdefFormatable.java | 67 +++- core/java/android/nfc/tech/NfcA.java | 58 ++-- core/java/android/nfc/tech/NfcB.java | 59 ++-- core/java/android/nfc/tech/NfcF.java | 57 ++-- core/java/android/nfc/tech/NfcV.java | 58 ++-- core/java/android/nfc/tech/TagTechnology.java | 113 +++++-- 13 files changed, 1019 insertions(+), 363 deletions(-) diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java index d30a0c68f8fe4..622bcdb0ba9ca 100644 --- a/core/java/android/nfc/NfcAdapter.java +++ b/core/java/android/nfc/NfcAdapter.java @@ -26,14 +26,17 @@ import android.content.Context; import android.content.IntentFilter; import android.content.pm.IPackageManager; import android.content.pm.PackageManager; +import android.nfc.tech.MifareClassic; +import android.nfc.tech.Ndef; +import android.nfc.tech.NfcA; +import android.nfc.tech.NfcF; import android.os.IBinder; -import android.os.Parcel; import android.os.RemoteException; import android.os.ServiceManager; import android.util.Log; /** - * Represents the device's local NFC adapter. + * Represents the local NFC adapter. *

* Use the helper {@link #getDefaultAdapter(Context)} to get the default NFC * adapter for this Android device. @@ -43,30 +46,85 @@ public final class NfcAdapter { /** * Intent to start an activity when a tag with NDEF payload is discovered. - * If the tag has and NDEF payload this intent is started before - * {@link #ACTION_TECH_DISCOVERED}. * - * If any activities respond to this intent neither + *

The system inspects the first {@link NdefRecord} in the first {@link NdefMessage} and + * looks for a URI, SmartPoster, or MIME record. If a URI or SmartPoster record is found the + * intent will contain the URI in its data field. If a MIME record is found the intent will + * contain the MIME type in its type field. This allows activities to register + * {@link IntentFilter}s targeting specific content on tags. Activities should register the + * most specific intent filters possible to avoid the activity chooser dialog, which can + * disrupt the interaction with the tag as the user interacts with the screen. + * + *

If the tag has an NDEF payload this intent is started before + * {@link #ACTION_TECH_DISCOVERED}. If any activities respond to this intent neither * {@link #ACTION_TECH_DISCOVERED} or {@link #ACTION_TAG_DISCOVERED} will be started. */ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) public static final String ACTION_NDEF_DISCOVERED = "android.nfc.action.NDEF_DISCOVERED"; /** - * Intent to started when a tag is discovered. The data URI is formated as - * {@code vnd.android.nfc://tag/} with the path having a directory entry for each technology - * in the {@link Tag#getTechList()} is sorted ascending order. + * Intent to start an activity when a tag is discovered and activities are registered for the + * specific technologies on the tag. * - * This intent is started after {@link #ACTION_NDEF_DISCOVERED} and before - * {@link #ACTION_TAG_DISCOVERED} + *

To receive this intent an activity must include an intent filter + * for this action and specify the desired tech types in a + * manifest meta-data entry. Here is an example manfiest entry: + *

+     *   <activity android:name=".nfc.TechFilter" android:label="NFC/TechFilter">
+     *       <!-- Add a technology filter -->
+     *       <intent-filter>
+     *           <action android:name="android.nfc.action.TECH_DISCOVERED" />
+     *       </intent-filter>
      *
-     * If any activities respond to this intent {@link #ACTION_TAG_DISCOVERED} will not be started.
+     *       <meta-data android:name="android.nfc.action.TECH_DISCOVERED"
+     *           android:resource="@xml/filter_nfc"
+     *       />
+     *   </activity>
+     * 
+ * + *

The meta-data XML file should contain one or more tech-list entries + * each consisting or one or more tech entries. The tech entries refer + * to the qualified class name implementing the technology, for example "android.nfc.tech.NfcA". + * + *

A tag matches if any of the + * tech-list sets is a subset of {@link Tag#getTechList() Tag.getTechList()}. Each + * of the tech-lists is considered independently and the + * activity is considered a match is any single tech-list matches the tag that was + * discovered. This provides AND and OR semantics for filtering desired techs. Here is an + * example that will match any tag using {@link NfcF} or any tag using {@link NfcA}, + * {@link MifareClassic}, and {@link Ndef}: + * + *

+     * <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+     *     <!-- capture anything using NfcF -->
+     *     <tech-list>
+     *         <tech>android.nfc.tech.NfcF</tech>
+     *     </tech-list>
+     *
+     *     <!-- OR -->
+     *
+     *     <!-- capture all MIFARE Classics with NDEF payloads -->
+     *     <tech-list>
+     *         <tech>android.nfc.tech.NfcA</tech>
+     *         <tech>android.nfc.tech.MifareClassic</tech>
+     *         <tech>android.nfc.tech.Ndef</tech>
+     *     </tech-list>
+     * </resources>
+     * 
+ * + *

This intent is started after {@link #ACTION_NDEF_DISCOVERED} and before + * {@link #ACTION_TAG_DISCOVERED}. If any activities respond to {@link #ACTION_NDEF_DISCOVERED} + * this intent will not be started. If any activities respond to this intent + * {@link #ACTION_TAG_DISCOVERED} will not be started. */ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) public static final String ACTION_TECH_DISCOVERED = "android.nfc.action.TECH_DISCOVERED"; /** * Intent to start an activity when a tag is discovered. + * + *

This intent will not be started when a tag is discovered if any activities respond to + * {@link #ACTION_NDEF_DISCOVERED} or {@link #ACTION_TECH_DISCOVERED} for the current tag. */ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) public static final String ACTION_TAG_DISCOVERED = "android.nfc.action.TAG_DISCOVERED"; @@ -78,17 +136,23 @@ public final class NfcAdapter { public static final String ACTION_TAG_LEFT_FIELD = "android.nfc.action.TAG_LOST"; /** - * Mandatory Tag extra for the ACTION_TAG intents. + * Mandatory extra containing the {@link Tag} that was discovered for the + * {@link #ACTION_NDEF_DISCOVERED}, {@link #ACTION_TECH_DISCOVERED}, and + * {@link #ACTION_TAG_DISCOVERED} intents. */ public static final String EXTRA_TAG = "android.nfc.extra.TAG"; /** - * Optional NdefMessage[] extra for the ACTION_TAG intents. + * Optional extra containing an array of {@link NdefMessage} present on the discovered tag for + * the {@link #ACTION_NDEF_DISCOVERED}, {@link #ACTION_TECH_DISCOVERED}, and + * {@link #ACTION_TAG_DISCOVERED} intents. */ public static final String EXTRA_NDEF_MESSAGES = "android.nfc.extra.NDEF_MESSAGES"; /** - * Optional byte[] extra for the tag identifier. + * Optional extra containing a byte array containing the ID of the discovered tag for + * the {@link #ACTION_NDEF_DISCOVERED}, {@link #ACTION_TECH_DISCOVERED}, and + * {@link #ACTION_TAG_DISCOVERED} intents. */ public static final String EXTRA_ID = "android.nfc.extra.ID"; @@ -359,14 +423,13 @@ public final class NfcAdapter { /** * Return true if this NFC Adapter has any features enabled. - *

- * If this method returns false, then applications should request the user - * turn on NFC tag discovery in Settings. - *

- * If this method returns false, the NFC hardware is guaranteed not to - * perform or respond to any NFC communication. * - * @return true if this NFC Adapter is enabled to discover new tags + *

Application may use this as a helper to suggest that the user + * should turn on NFC in Settings. + *

If this method returns false, the NFC hardware is guaranteed not to + * generate or respond to any NFC transactions. + * + * @return true if this NFC Adapter has any features enabled */ public boolean isEnabled() { try { @@ -414,17 +477,37 @@ public final class NfcAdapter { } /** - * Enables foreground dispatching to the given Activity. This will force all NFC Intents that - * match the given filters to be delivered to the activity bypassing the standard dispatch - * mechanism. If no IntentFilters are given all the PendingIntent will be invoked for every - * dispatch Intent. + * Enable foreground dispatch to the given Activity. * - * This method must be called from the main thread. + *

This will give give priority to the foreground activity when + * dispatching a discovered {@link Tag} to an application. + * + *

If any IntentFilters are provided to this method they are used to match dispatch Intents + * for both the {@link NfcAdapter#ACTION_NDEF_DISCOVERED} and + * {@link NfcAdapter#ACTION_TAG_DISCOVERED}. Since {@link NfcAdapter#ACTION_TECH_DISCOVERED} + * relies on meta data outside of the IntentFilter matching for that dispatch Intent is handled + * by passing in the tech lists separately. Each first level entry in the tech list represents + * an array of technologies that must all be present to match. If any of the first level sets + * match then the dispatch is routed through the given PendingIntent. In other words, the second + * level is ANDed together and the first level entries are ORed together. + * + *

If you pass {@code null} for both the {@code filters} and {@code techLists} parameters + * that acts a wild card and will cause the foreground activity to receive all tags via the + * {@link NfcAdapter#ACTION_TAG_DISCOVERED} intent. + * + *

This method must be called from the main thread, and only when the activity is in the + * foreground (resumed). Also, activities must call {@link #disableForegroundDispatch} before + * the completion of their {@link Activity#onPause} callback to disable foreground dispatch + * after it has been enabled. + * + *

Requires the {@link android.Manifest.permission#NFC} permission. * * @param activity the Activity to dispatch to * @param intent the PendingIntent to start for the dispatch * @param filters the IntentFilters to override dispatching for, or null to always dispatch - * @throws IllegalStateException + * @param techLists the tech lists used to perform matching for dispatching of the + * {@link NfcAdapter#ACTION_TECH_DISCOVERED} intent + * @throws IllegalStateException if the Activity is not currently in the foreground */ public void enableForegroundDispatch(Activity activity, PendingIntent intent, IntentFilter[] filters, String[][] techLists) { @@ -450,13 +533,18 @@ public final class NfcAdapter { } /** - * Disables foreground activity dispatching setup with - * {@link #enableForegroundDispatch}. + * Disable foreground dispatch to the given activity. * - *

This must be called before the Activity returns from - * it's onPause() or this method will throw an IllegalStateException. + *

After calling {@link #enableForegroundDispatch}, an activity + * must call this method before its {@link Activity#onPause} callback + * completes. * *

This method must be called from the main thread. + * + *

Requires the {@link android.Manifest.permission#NFC} permission. + * + * @param activity the Activity to disable dispatch to + * @throws IllegalStateException if the Activity has already been paused */ public void disableForegroundDispatch(Activity activity) { ActivityThread.currentActivityThread().unregisterOnActivityPausedListener(activity, @@ -484,13 +572,24 @@ public final class NfcAdapter { } /** - * Enable NDEF message push over P2P while this Activity is in the foreground. For this to - * function properly the other NFC device being scanned must support the "com.android.npp" - * NDEF push protocol. + * Enable NDEF message push over P2P while this Activity is in the foreground. * - *

NOTE While foreground NDEF push is active standard tag dispatch is disabled. + *

For this to function properly the other NFC device being scanned must + * support the "com.android.npp" NDEF push protocol. Support for this + * protocol is currently optional for Android NFC devices. + * + *

This method must be called from the main thread. + * + *

NOTE: While foreground NDEF push is active standard tag dispatch is disabled. * Only the foreground activity may receive tag discovered dispatches via * {@link #enableForegroundDispatch}. + * + *

Requires the {@link android.Manifest.permission#NFC} permission. + * + * @param activity the foreground Activity + * @param msg a NDEF Message to push over P2P + * @throws IllegalStateException if the Activity is not currently in the foreground + * @throws OperationNotSupportedException if this Android device does not support NDEF push */ public void enableForegroundNdefPush(Activity activity, NdefMessage msg) { if (activity == null || msg == null) { @@ -510,13 +609,19 @@ public final class NfcAdapter { } /** - * Disables foreground NDEF push setup with - * {@link #enableForegroundNdefPush}. + * Disable NDEF message push over P2P. * - *

This must be called before the Activity returns from - * it's onPause() or this method will throw an IllegalStateException. + *

After calling {@link #enableForegroundNdefPush}, an activity + * must call this method before its {@link Activity#onPause} callback + * completes. * *

This method must be called from the main thread. + * + *

Requires the {@link android.Manifest.permission#NFC} permission. + * + * @param activity the Foreground activity + * @throws IllegalStateException if the Activity has already been paused + * @throws OperationNotSupportedException if this Android device does not support NDEF push */ public void disableForegroundNdefPush(Activity activity) { ActivityThread.currentActivityThread().unregisterOnActivityPausedListener(activity, diff --git a/core/java/android/nfc/NfcSecureElement.java b/core/java/android/nfc/NfcSecureElement.java index ea2846ea99598..3b5f39eaac8a9 100755 --- a/core/java/android/nfc/NfcSecureElement.java +++ b/core/java/android/nfc/NfcSecureElement.java @@ -35,8 +35,8 @@ public final class NfcSecureElement { private static final String TAG = "NfcSecureElement"; private INfcSecureElement mService; - - + + /** * @hide */ @@ -68,7 +68,7 @@ public final class NfcSecureElement { public byte [] exchangeAPDU(int handle,byte [] data) throws IOException { - + // Perform exchange APDU try { @@ -85,7 +85,7 @@ public final class NfcSecureElement { } public void closeSecureElementConnection(int handle) throws IOException { - + try { int status = mService.closeSecureElementConnection(handle); // Handle potential errors @@ -96,14 +96,14 @@ public final class NfcSecureElement { Log.e(TAG, "RemoteException in closeSecureElement(): ", e); } } - - + + /** * Returns target type. constants. - * + * * @return Secure Element technology type. The possible values are defined in * {@link TagTechnology} - * + * */ public int[] getSecureElementTechList(int handle) throws IOException { try { @@ -113,16 +113,16 @@ public final class NfcSecureElement { return null; } } - + /** * Returns Secure Element UID. - * + * * @return Secure Element UID. */ public byte[] getSecureElementUid(int handle) throws IOException { - + byte[] uid = null; - try { + try { uid = mService.getSecureElementUid(handle); // Handle potential errors if (uid == null) { diff --git a/core/java/android/nfc/Tag.java b/core/java/android/nfc/Tag.java index 45a34470c2835..b676975b297fc 100644 --- a/core/java/android/nfc/Tag.java +++ b/core/java/android/nfc/Tag.java @@ -16,6 +16,7 @@ package android.nfc; +import android.content.Context; import android.nfc.tech.IsoDep; import android.nfc.tech.MifareClassic; import android.nfc.tech.MifareUltralight; @@ -33,27 +34,76 @@ import android.os.Parcelable; import java.util.Arrays; /** - * Represents a (generic) discovered tag. + * Represents an NFC tag that has been discovered. *

- * A tag is a passive NFC element, such as NFC Forum Tag's, MIFARE class Tags, - * Sony FeliCa Tags, etc. + * {@link Tag} is an immutable object that represents the state of a NFC tag at + * the time of discovery. It can be used as a handle to {@link TagTechnology} classes + * to perform advanced operations, or directly queried for its ID via {@link #getId} and the + * set of technologies it contains via {@link #getTechList}. Arrays passed to and + * returned by this class are not cloned, so be careful not to modify them. *

- * Tag's have a type and usually have a UID. + * A new tag object is created every time a tag is discovered (comes into range), even + * if it is the same physical tag. If a tag is removed and then returned into range, then + * only the most recent tag object can be successfully used to create a {@link TagTechnology}. + * + *

Tag Dispatch

+ * When a tag is discovered, a {@link Tag} object is created and passed to a + * single activity via the {@link NfcAdapter#EXTRA_TAG} extra in an + * {@link android.content.Intent} via {@link Context#startActivity}. A four stage dispatch is used + * to select the + * most appropriate activity to handle the tag. The Android OS executes each stage in order, + * and completes dispatch as soon as a single matching activity is found. If there are multiple + * matching activities found at any one stage then the Android activity chooser dialog is shown + * to allow the user to select the activity to receive the tag. + * + *

The Tag dispatch mechanism was designed to give a high probability of dispatching + * a tag to the correct activity without showing the user an activity chooser dialog. + * This is important for NFC interactions because they are very transient -- if a user has to + * move the Android device to choose an application then the connection will likely be broken. + * + *

1. Foreground activity dispatch

+ * A foreground activity that has called + * {@link NfcAdapter#enableForegroundDispatch NfcAdapter.enableForegroundDispatch()} is + * given priority. See the documentation on + * {@link NfcAdapter#enableForegroundDispatch NfcAdapter.enableForegroundDispatch()} for + * its usage. + *

2. NDEF data dispatch

+ * If the tag contains NDEF data the system inspects the first {@link NdefRecord} in the first + * {@link NdefMessage}. If the record is a URI, SmartPoster, or MIME data + * {@link Context#startActivity} is called with {@link NfcAdapter#ACTION_NDEF_DISCOVERED}. For URI + * and SmartPoster records the URI is put into the intent's data field. For MIME records the MIME + * type is put in the intent's type field. This allows activities to register to be launched only + * when data they know how to handle is present on a tag. This is the preferred method of handling + * data on a tag since NDEF data can be stored on many types of tags and doesn't depend on a + * specific tag technology. + * See {@link NfcAdapter#ACTION_NDEF_DISCOVERED} for more detail. If the tag does not contain + * NDEF data, or if no activity is registered + * for {@link NfcAdapter#ACTION_NDEF_DISCOVERED} with a matching data URI or MIME type then dispatch + * moves to stage 3. + *

3. Tag Technology dispatch

+ * {@link Context#startActivity} is called with {@link NfcAdapter#ACTION_TECH_DISCOVERED} to + * dispatch the tag to an activity that can handle the technologies present on the tag. + * Technologies are defined as sub-classes of {@link TagTechnology}, see the package + * {@link android.nfc.tech}. The Android OS looks for an activity that can handle one or + * more technologies in the tag. See {@link NfcAdapter#ACTION_TECH_DISCOVERED} for more detail. + *

4. Fall-back dispatch

+ * If no activity has been matched then {@link Context#startActivity} is called with + * {@link NfcAdapter#ACTION_TAG_DISCOVERED}. This is intended as a fall-back mechanism. + * See {@link NfcAdapter#ACTION_TAG_DISCOVERED}. + * + *

NFC Tag Background

+ * An NFC tag is a passive NFC device, powered by the NFC field of this Android device while + * it is in range. Tag's can come in many forms, such as stickers, cards, key fobs, or + * even embedded in a more sophisticated device. *

- * {@link Tag} objects are passed to applications via the {@link NfcAdapter#EXTRA_TAG} extra - * in {@link NfcAdapter#ACTION_TAG_DISCOVERED} intents. A {@link Tag} object is immutable - * and represents the state of the tag at the time of discovery. It can be - * directly queried for its UID and Type, or used to create a {@link TagTechnology} using the - * static get() methods on the varios tech classes. + * Tags can have a wide range of capabilities. Simple tags just offer read/write semantics, + * and contain some one time + * programmable areas to make read-only. More complex tags offer math operations + * and per-sector access control and authentication. The most sophisticated tags + * contain operating environments allowing complex interactions with the + * code executing on the tag. Use {@link TagTechnology} classes to access a broad + * range of capabilities available in NFC tags. *

- * A {@link Tag} can be used to create a {@link TagTechnology} only while the tag is in - * range. If it is removed and then returned to range, then the most recent - * {@link Tag} object (in {@link NfcAdapter#ACTION_TAG_DISCOVERED}) should be used to create a - * {@link TagTechnology}. - *

This is an immutable data class. All properties are set at Tag discovery - * time and calls on this class will retrieve those read-only properties, and - * not cause any further RF activity or block. Note however that arrays passed to and - * returned by this class are *not* cloned, so be careful not to modify them. */ public final class Tag implements Parcelable { /*package*/ final byte[] mId; @@ -149,21 +199,35 @@ public final class Tag implements Parcelable { /** * Get the Tag Identifier (if it has one). - *

Tag ID is usually a serial number for the tag. - * - * @return ID, or null if it does not exist + *

The tag identifier is a low level serial number, used for anti-collision + * and identification. + *

Most tags have a stable unique identifier + * (UID), but some tags will generate a random ID every time they are discovered + * (RID), and there are some tags with no ID at all (the byte array will be zero-sized). + *

The size and format of an ID is specific to the RF technology used by the tag. + *

This function retrieves the ID as determined at discovery time, and does not + * perform any further RF communication or block. + * @return ID as byte array, never null */ public byte[] getId() { return mId; } /** - * Returns technologies present in the tag that this implementation understands, - * or a zero length array if there are no supported technologies on this tag. - * - * The elements of the list are the names of the classes implementing the technology. - * + * Get the technologies available in this tag, as fully qualified class names. + *

+ * A technology is an implementation of the {@link TagTechnology} interface, + * and can be instantiated by calling the static get(Tag) + * method on the implementation with this Tag. The {@link TagTechnology} + * object can then be used to perform advanced, technology-specific operations on a tag. + *

+ * Android defines a mandatory set of technologies that must be correctly + * enumerated by all Android NFC devices, and an optional + * set of proprietary technologies. + * See {@link TagTechnology} for more details. + *

* The ordering of the returned array is undefined and should not be relied upon. + * @return an array of fully-qualified {@link TagTechnology} class-names. */ public String[] getTechList() { return mTechStringList; @@ -176,7 +240,7 @@ public final class Tag implements Parcelable { } return false; } - + /** @hide */ public Bundle getTechExtras(int tech) { int pos = -1; @@ -198,6 +262,9 @@ public final class Tag implements Parcelable { return mTagService; } + /** + * Human-readable description of the tag, for debugging. + */ @Override public String toString() { StringBuilder sb = new StringBuilder("TAG ") diff --git a/core/java/android/nfc/tech/IsoDep.java b/core/java/android/nfc/tech/IsoDep.java index 774982ed88e68..9c3074ba4e2f2 100644 --- a/core/java/android/nfc/tech/IsoDep.java +++ b/core/java/android/nfc/tech/IsoDep.java @@ -24,18 +24,17 @@ import android.util.Log; import java.io.IOException; /** - * A low-level connection to a {@link Tag} using the ISO-DEP technology, also known as - * ISO1443-4. + * Provides access to ISO-DEP (ISO 14443-4) properties and I/O operations on a {@link Tag}. * - *

You can acquire this kind of connection with {@link #get}. - * Use this class to send and receive data with {@link #transceive transceive()}. + *

Acquire an {@link IsoDep} object using {@link #get}. + *

The primary ISO-DEP I/O operation is {@link #transceive}. Applications must + * implement their own protocol stack on top of {@link #transceive}. + *

Tags that enumerate the {@link IsoDep} technology in {@link Tag#getTechList} + * will also enumerate + * {@link NfcA} or {@link NfcB} (since IsoDep builds on top of either of these). * - *

Applications must implement their own protocol stack on top of - * {@link #transceive transceive()}. - * - *

Note: - * Use of this class requires the {@link android.Manifest.permission#NFC} - * permission. + *

Note: Methods that perform I/O operations + * require the {@link android.Manifest.permission#NFC} permission. */ public final class IsoDep extends BasicTagTechnology { private static final String TAG = "NFC"; @@ -49,10 +48,13 @@ public final class IsoDep extends BasicTagTechnology { private byte[] mHistBytes = null; /** - * Returns an instance of this tech for the given tag. If the tag doesn't support - * this tech type null is returned. + * Get an instance of {@link IsoDep} for the given tag. + *

Does not cause any RF activity and does not block. + *

Returns null if {@link IsoDep} was not enumerated in {@link Tag#getTechList}. + * This indicates the tag does not support ISO-DEP. * - * @param tag The tag to get the tech from + * @param tag an ISO-DEP compatible tag + * @return ISO-DEP object */ public static IsoDep get(Tag tag) { if (!tag.hasTech(TagTechnology.ISO_DEP)) return null; @@ -62,7 +64,7 @@ public final class IsoDep extends BasicTagTechnology { return null; } } - + /** @hide */ public IsoDep(Tag tag) throws RemoteException { @@ -75,13 +77,16 @@ public final class IsoDep extends BasicTagTechnology { } /** - * Sets the timeout of an IsoDep transceive transaction in milliseconds. - * If the transaction has not completed before the timeout, - * any ongoing {@link #transceive} operation will be - * aborted and the connection to the tag is lost. This setting is applied - * only to the {@link Tag} object linked to this technology and will be - * reset when {@link IsoDep#close} is called. - * The default transaction timeout is 300 milliseconds. + * Set the timeout of {@link #transceive} in milliseconds. + *

The timeout only applies to ISO-DEP {@link #transceive}, and is + * reset to a default value when {@link #close} is called. + *

Setting a longer timeout may be useful when performing + * transactions that require a long processing time on the tag + * such as key generation. + * + *

Requires the {@link android.Manifest.permission#NFC} permission. + * + * @param timeout timeout value in milliseconds */ public void setTimeout(int timeout) { try { @@ -102,29 +107,53 @@ public final class IsoDep extends BasicTagTechnology { } /** - * Return the historical bytes if the tag is using {@link NfcA}, null otherwise. + * Return the ISO-DEP historical bytes for {@link NfcA} tags. + *

Does not cause any RF activity and does not block. + *

The historical bytes can be used to help identify a tag. They are present + * only on {@link IsoDep} tags that are based on {@link NfcA} RF technology. + * If this tag is not {@link NfcA} then null is returned. + *

In ISO 14443-4 terminology, the historical bytes are a subset of the RATS + * response. + * + * @return ISO-DEP historical bytes, or null if this is not a {@link NfcA} tag */ public byte[] getHistoricalBytes() { return mHistBytes; } /** - * Return the hi layer response bytes if the tag is using {@link NfcB}, null otherwise. + * Return the higher layer response bytes for {@link NfcB} tags. + *

Does not cause any RF activity and does not block. + *

The higher layer response bytes can be used to help identify a tag. + * They are present only on {@link IsoDep} tags that are based on {@link NfcB} + * RF technology. If this tag is not {@link NfcB} then null is returned. + *

In ISO 14443-4 terminology, the higher layer bytes are a subset of the + * ATTRIB response. + * + * @return ISO-DEP historical bytes, or null if this is not a {@link NfcB} tag */ public byte[] getHiLayerResponse() { return mHiLayerResponse; } /** - * Send data to a tag and receive the response. - *

- * This method will block until the response is received. It can be canceled - * with {@link #close}. - *

Requires {@link android.Manifest.permission#NFC} permission. + * Send raw ISO-DEP data to the tag and receive the response. * - * @param data bytes to send - * @return bytes received in response - * @throws IOException if the target is lost or connection closed + *

Applications must only send the INF payload, and not the start of frame and + * end of frame indicators. Applications do not need to fragment the payload, it + * will be automatically fragmented and defragmented by {@link #transceive} if + * it exceeds FSD/FSC limits. + * + *

This is an I/O operation and will block until complete. It must + * not be called from the main application thread. A blocked call will be canceled with + * {@link IOException} if {@link #close} is called from another thread. + * + *

Requires the {@link android.Manifest.permission#NFC} permission. + * + * @param data command bytes to send, must not be null + * @return response bytes received, will not be null + * @throws TagLostException if the tag leaves the field + * @throws IOException if there is an I/O failure, or this operation is canceled */ public byte[] transceive(byte[] data) throws IOException { return transceive(data, true); diff --git a/core/java/android/nfc/tech/MifareClassic.java b/core/java/android/nfc/tech/MifareClassic.java index d337eada0a6c7..9a2f2bd5124bd 100644 --- a/core/java/android/nfc/tech/MifareClassic.java +++ b/core/java/android/nfc/tech/MifareClassic.java @@ -25,32 +25,64 @@ import java.nio.ByteBuffer; import java.nio.ByteOrder; /** - * Technology class representing MIFARE Classic tags (also known as MIFARE Standard). + * Provides access to MIFARE Classic properties and I/O operations on a {@link Tag}. * - *

Support for this technology type is optional. If the NFC stack doesn't support this technology - * MIFARE Classic tags will still be scanned, but will only show the NfcA technology. + *

Acquire a {@link MifareClassic} object using {@link #get}. * - *

MIFARE Classic tags have sectors that each contain blocks. The block size is constant at - * 16 bytes, but the number of sectors and the sector size varies by product. MIFARE has encryption - * built in and each sector has two keys associated with it, as well as ACLs to determine what - * level acess each key grants. Before operating on a sector you must call either - * {@link #authenticateSectorWithKeyA(int, byte[])} or - * {@link #authenticateSectorWithKeyB(int, byte[])} to gain authorization for your request. + *

MIFARE Classic is also known as MIFARE Standard. + *

MIFARE Classic tags are divided into sectors, and each sector is sub-divided into + * blocks. Block size is always 16 bytes ({@link #BLOCK_SIZE}. Sector size varies. + *

+ * + *

MIFARE Classic tags require authentication on a per-sector basis before any + * other I/O operations on that sector can be performed. There are two keys per sector, + * and ACL bits determine what I/O operations are allowed on that sector after + * authenticating with a key. {@see #authenticateSectorWithKeyA} and + * {@see #authenticateSectorWithKeyB}. + * + *

Three well-known authentication keys are defined in this class: + * {@link #KEY_DEFAULT}, {@link #KEY_MIFARE_APPLICATION_DIRECTORY}, + * {@link #KEY_NFC_FORUM}. + *