diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java index b2ff6c4a97305..622bcdb0ba9ca 100644 --- a/core/java/android/nfc/NfcAdapter.java +++ b/core/java/android/nfc/NfcAdapter.java @@ -26,8 +26,11 @@ 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; @@ -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"; diff --git a/core/java/android/nfc/Tag.java b/core/java/android/nfc/Tag.java index 2305fb9f6a5e1..b676975b297fc 100644 --- a/core/java/android/nfc/Tag.java +++ b/core/java/android/nfc/Tag.java @@ -38,9 +38,9 @@ import java.util.Arrays; *
* {@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 ({@link #getId} and the - * set of technologies it contains ({@link #getTechList}). Arrays passed to and - * returned by this class are *not* cloned, so be careful not to modify them. + * 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. *
* 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 @@ -48,53 +48,60 @@ import java.util.Arrays; * *
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. + * *
- * The Tag dispatch mechanism was designed to give a high probability of dispatching - * a tag to the correct application without showing the user an Application 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 is broken. - * *
* 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 such as Javacard, allowing complex interactions with the - * applets executing on the tag. Use {@link TagTechnology} classes to access a broad + * 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. *
*/ diff --git a/core/java/android/nfc/tech/Ndef.java b/core/java/android/nfc/tech/Ndef.java index 657eb64d9e7dd..6727d6ad50901 100644 --- a/core/java/android/nfc/tech/Ndef.java +++ b/core/java/android/nfc/tech/Ndef.java @@ -136,7 +136,6 @@ public final class Ndef extends BasicTagTechnology { * @param tag an MIFARE Classic compatible tag * @return MIFARE Classic object */ - public static Ndef get(Tag tag) { if (!tag.hasTech(TagTechnology.NDEF)) return null; try {