diff options
-rw-r--r-- | api/current.xml | 283 | ||||
-rw-r--r-- | core/java/android/app/ActivityThread.java | 10 | ||||
-rw-r--r-- | core/java/android/nfc/NfcAdapter.java | 24 | ||||
-rw-r--r-- | core/java/android/nfc/Tag.java | 4 | ||||
-rw-r--r-- | core/java/android/nfc/technology/BasicTagTechnology.java | 75 | ||||
-rw-r--r-- | core/java/android/nfc/technology/IsoDep.java | 20 | ||||
-rw-r--r-- | core/java/android/nfc/technology/MifareClassic.java | 88 | ||||
-rw-r--r-- | core/java/android/nfc/technology/MifareUltralight.java | 68 | ||||
-rw-r--r-- | core/java/android/nfc/technology/Ndef.java | 32 | ||||
-rw-r--r-- | core/java/android/nfc/technology/NdefFormatable.java | 7 | ||||
-rw-r--r-- | core/java/android/nfc/technology/NfcA.java | 18 | ||||
-rw-r--r-- | core/java/android/nfc/technology/NfcB.java | 17 | ||||
-rw-r--r-- | core/java/android/nfc/technology/NfcF.java | 18 | ||||
-rw-r--r-- | core/java/android/nfc/technology/NfcV.java | 20 | ||||
-rw-r--r-- | core/java/android/nfc/technology/TagTechnology.java | 67 |
15 files changed, 356 insertions, 395 deletions
diff --git a/api/current.xml b/api/current.xml index aefa932..5e364f9 100644 --- a/api/current.xml +++ b/api/current.xml @@ -100830,7 +100830,7 @@ <parameter name="activity" type="android.app.Activity"> </parameter> </method> -<method name="disableNdefPushDispatch" +<method name="disableForegroundNdefPush" return="void" abstract="false" native="false" @@ -101111,17 +101111,6 @@ > <implements name="android.nfc.technology.TagTechnology"> </implements> -<method name="checkConnected" - return="void" - abstract="false" - native="false" - synchronized="false" - static="false" - final="false" - deprecated="not deprecated" - visibility="public" -> -</method> <method name="close" return="void" abstract="false" @@ -101192,21 +101181,6 @@ <exception name="IOException" type="java.io.IOException"> </exception> </method> -<method name="transceive" - return="byte[]" - abstract="false" - native="false" - synchronized="false" - static="false" - final="false" - deprecated="not deprecated" - visibility="public" -> -<parameter name="data" type="byte[]"> -</parameter> -<exception name="IOException" type="java.io.IOException"> -</exception> -</method> </class> <class name="IsoDep" extends="android.nfc.technology.BasicTagTechnology" @@ -101216,23 +101190,18 @@ deprecated="not deprecated" visibility="public" > -<constructor name="IsoDep" - type="android.nfc.technology.IsoDep" +<method name="getHiLayerResponse" + return="byte[]" + abstract="false" + native="false" + synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public" > -<parameter name="adapter" type="android.nfc.NfcAdapter"> -</parameter> -<parameter name="tag" type="android.nfc.Tag"> -</parameter> -<parameter name="extras" type="android.os.Bundle"> -</parameter> -<exception name="RemoteException" type="android.os.RemoteException"> -</exception> -</constructor> -<method name="getHiLayerResponse" +</method> +<method name="getHistoricalBytes" return="byte[]" abstract="false" native="false" @@ -101243,7 +101212,7 @@ visibility="public" > </method> -<method name="getHistoricalBytes" +<method name="transceive" return="byte[]" abstract="false" native="false" @@ -101253,6 +101222,10 @@ deprecated="not deprecated" visibility="public" > +<parameter name="data" type="byte[]"> +</parameter> +<exception name="IOException" type="java.io.IOException"> +</exception> </method> </class> <class name="MifareClassic" @@ -101263,22 +101236,6 @@ deprecated="not deprecated" visibility="public" > -<constructor name="MifareClassic" - type="android.nfc.technology.MifareClassic" - static="false" - final="false" - deprecated="not deprecated" - visibility="public" -> -<parameter name="adapter" type="android.nfc.NfcAdapter"> -</parameter> -<parameter name="tag" type="android.nfc.Tag"> -</parameter> -<parameter name="extras" type="android.os.Bundle"> -</parameter> -<exception name="RemoteException" type="android.os.RemoteException"> -</exception> -</constructor> <method name="authenticateBlock" return="boolean" abstract="false" @@ -101471,6 +101428,21 @@ <exception name="IOException" type="java.io.IOException"> </exception> </method> +<method name="transceive" + return="byte[]" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="data" type="byte[]"> +</parameter> +<exception name="IOException" type="java.io.IOException"> +</exception> +</method> <method name="transfer" return="void" abstract="false" @@ -101621,17 +101593,6 @@ visibility="public" > </field> -<field name="TYPE_DESFIRE" - type="int" - transient="false" - volatile="false" - value="3" - static="true" - final="true" - deprecated="not deprecated" - visibility="public" -> -</field> <field name="TYPE_PLUS" type="int" transient="false" @@ -101654,17 +101615,6 @@ visibility="public" > </field> -<field name="TYPE_ULTRALIGHT" - type="int" - transient="false" - volatile="false" - value="4" - static="true" - final="true" - deprecated="not deprecated" - visibility="public" -> -</field> <field name="TYPE_UNKNOWN" type="int" transient="false" @@ -101685,22 +101635,6 @@ deprecated="not deprecated" visibility="public" > -<constructor name="MifareUltralight" - type="android.nfc.technology.MifareUltralight" - static="false" - final="false" - deprecated="not deprecated" - visibility="public" -> -<parameter name="adapter" type="android.nfc.NfcAdapter"> -</parameter> -<parameter name="tag" type="android.nfc.Tag"> -</parameter> -<parameter name="extras" type="android.os.Bundle"> -</parameter> -<exception name="RemoteException" type="android.os.RemoteException"> -</exception> -</constructor> <method name="getType" return="int" abstract="false" @@ -101722,12 +101656,12 @@ deprecated="not deprecated" visibility="public" > -<parameter name="block" type="int"> +<parameter name="page" type="int"> </parameter> <exception name="IOException" type="java.io.IOException"> </exception> </method> -<method name="readOTP" +<method name="transceive" return="byte[]" abstract="false" native="false" @@ -101737,21 +101671,6 @@ deprecated="not deprecated" visibility="public" > -<exception name="IOException" type="java.io.IOException"> -</exception> -</method> -<method name="writeBlock" - return="void" - abstract="false" - native="false" - synchronized="false" - static="false" - final="false" - deprecated="not deprecated" - visibility="public" -> -<parameter name="block" type="int"> -</parameter> <parameter name="data" type="byte[]"> </parameter> <exception name="IOException" type="java.io.IOException"> @@ -101767,7 +101686,7 @@ deprecated="not deprecated" visibility="public" > -<parameter name="block" type="int"> +<parameter name="page" type="int"> </parameter> <parameter name="data" type="byte[]"> </parameter> @@ -101838,21 +101757,6 @@ visibility="public" > </method> -<method name="getExtraNdefMessage" - return="android.nfc.NdefMessage[]" - abstract="false" - native="false" - synchronized="false" - static="false" - final="false" - deprecated="not deprecated" - visibility="public" -> -<exception name="FormatException" type="android.nfc.FormatException"> -</exception> -<exception name="IOException" type="java.io.IOException"> -</exception> -</method> <method name="getMaxSize" return="int" abstract="false" @@ -101914,25 +101818,6 @@ <exception name="IOException" type="java.io.IOException"> </exception> </method> -<method name="writeExtraNdefMessage" - return="void" - abstract="false" - native="false" - synchronized="false" - static="false" - final="false" - deprecated="not deprecated" - visibility="public" -> -<parameter name="i" type="int"> -</parameter> -<parameter name="msg" type="android.nfc.NdefMessage"> -</parameter> -<exception name="FormatException" type="android.nfc.FormatException"> -</exception> -<exception name="IOException" type="java.io.IOException"> -</exception> -</method> <method name="writeNdefMessage" return="void" abstract="false" @@ -102051,24 +101936,19 @@ deprecated="not deprecated" visibility="public" > -<constructor name="NfcA" - type="android.nfc.technology.NfcA" +<method name="getAtqa" + return="byte[]" + abstract="false" + native="false" + synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public" > -<parameter name="adapter" type="android.nfc.NfcAdapter"> -</parameter> -<parameter name="tag" type="android.nfc.Tag"> -</parameter> -<parameter name="extras" type="android.os.Bundle"> -</parameter> -<exception name="RemoteException" type="android.os.RemoteException"> -</exception> -</constructor> -<method name="getAtqa" - return="byte[]" +</method> +<method name="getSak" + return="short" abstract="false" native="false" synchronized="false" @@ -102078,8 +101958,8 @@ visibility="public" > </method> -<method name="getSak" - return="short" +<method name="transceive" + return="byte[]" abstract="false" native="false" synchronized="false" @@ -102088,6 +101968,10 @@ deprecated="not deprecated" visibility="public" > +<parameter name="data" type="byte[]"> +</parameter> +<exception name="IOException" type="java.io.IOException"> +</exception> </method> </class> <class name="NfcB" @@ -102098,23 +101982,18 @@ deprecated="not deprecated" visibility="public" > -<constructor name="NfcB" - type="android.nfc.technology.NfcB" +<method name="getApplicationData" + return="byte[]" + abstract="false" + native="false" + synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public" > -<parameter name="adapter" type="android.nfc.NfcAdapter"> -</parameter> -<parameter name="tag" type="android.nfc.Tag"> -</parameter> -<parameter name="extras" type="android.os.Bundle"> -</parameter> -<exception name="RemoteException" type="android.os.RemoteException"> -</exception> -</constructor> -<method name="getApplicationData" +</method> +<method name="getProtocolInfo" return="byte[]" abstract="false" native="false" @@ -102125,7 +102004,7 @@ visibility="public" > </method> -<method name="getProtocolInfo" +<method name="transceive" return="byte[]" abstract="false" native="false" @@ -102135,6 +102014,10 @@ deprecated="not deprecated" visibility="public" > +<parameter name="data" type="byte[]"> +</parameter> +<exception name="IOException" type="java.io.IOException"> +</exception> </method> </class> <class name="NfcF" @@ -102145,23 +102028,18 @@ deprecated="not deprecated" visibility="public" > -<constructor name="NfcF" - type="android.nfc.technology.NfcF" +<method name="getManufacturer" + return="byte[]" + abstract="false" + native="false" + synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public" > -<parameter name="adapter" type="android.nfc.NfcAdapter"> -</parameter> -<parameter name="tag" type="android.nfc.Tag"> -</parameter> -<parameter name="extras" type="android.os.Bundle"> -</parameter> -<exception name="RemoteException" type="android.os.RemoteException"> -</exception> -</constructor> -<method name="getManufacturer" +</method> +<method name="getSystemCode" return="byte[]" abstract="false" native="false" @@ -102172,7 +102050,7 @@ visibility="public" > </method> -<method name="getSystemCode" +<method name="transceive" return="byte[]" abstract="false" native="false" @@ -102182,6 +102060,10 @@ deprecated="not deprecated" visibility="public" > +<parameter name="data" type="byte[]"> +</parameter> +<exception name="IOException" type="java.io.IOException"> +</exception> </method> </class> <class name="NfcV" @@ -102192,23 +102074,18 @@ deprecated="not deprecated" visibility="public" > -<constructor name="NfcV" - type="android.nfc.technology.NfcV" +<method name="getDsfId" + return="byte" + abstract="false" + native="false" + synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public" > -<parameter name="adapter" type="android.nfc.NfcAdapter"> -</parameter> -<parameter name="tag" type="android.nfc.Tag"> -</parameter> -<parameter name="extras" type="android.os.Bundle"> -</parameter> -<exception name="RemoteException" type="android.os.RemoteException"> -</exception> -</constructor> -<method name="getDsfId" +</method> +<method name="getResponseFlags" return="byte" abstract="false" native="false" @@ -102219,8 +102096,8 @@ visibility="public" > </method> -<method name="getResponseFlags" - return="byte" +<method name="transceive" + return="byte[]" abstract="false" native="false" synchronized="false" @@ -102229,6 +102106,10 @@ deprecated="not deprecated" visibility="public" > +<parameter name="data" type="byte[]"> +</parameter> +<exception name="IOException" type="java.io.IOException"> +</exception> </method> </class> <interface name="TagTechnology" diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index e3fa32c..162d9eb 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -1439,6 +1439,16 @@ public final class ActivityThread { } } + public void unregisterOnActivityPausedListener(Activity activity, + OnActivityPausedListener listener) { + synchronized (mOnPauseListeners) { + ArrayList<OnActivityPausedListener> list = mOnPauseListeners.get(activity); + if (list != null) { + list.remove(listener); + } + } + } + public final ActivityInfo resolveActivityInfo(Intent intent) { ActivityInfo aInfo = intent.resolveActivityInfo( mInitialApplication.getPackageManager(), PackageManager.GET_SHARED_LIBRARY_FILES); diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java index 28d53f5..f6605b8 100644 --- a/core/java/android/nfc/NfcAdapter.java +++ b/core/java/android/nfc/NfcAdapter.java @@ -436,7 +436,7 @@ public final class NfcAdapter { } try { ActivityThread.currentActivityThread().registerOnActivityPausedListener(activity, - new ForegroundDispatchPausedListener()); + mForegroundDispatchListener); sService.enableForegroundDispatch(activity.getComponentName(), intent, filters); } catch (RemoteException e) { attemptDeadServiceRecovery(e); @@ -453,15 +453,17 @@ public final class NfcAdapter { * <p>This method must be called from the main thread. */ public void disableForegroundDispatch(Activity activity) { + ActivityThread.currentActivityThread().unregisterOnActivityPausedListener(activity, + mForegroundDispatchListener); disableForegroundDispatchInternal(activity, false); } - class ForegroundDispatchPausedListener implements OnActivityPausedListener { + OnActivityPausedListener mForegroundDispatchListener = new OnActivityPausedListener() { @Override public void onPaused(Activity activity) { disableForegroundDispatchInternal(activity, true); } - } + }; void disableForegroundDispatchInternal(Activity activity, boolean force) { try { @@ -488,7 +490,7 @@ public final class NfcAdapter { } try { ActivityThread.currentActivityThread().registerOnActivityPausedListener(activity, - new ForegroundDispatchPausedListener()); + mForegroundNdefPushListener); sService.enableForegroundNdefPush(activity.getComponentName(), msg); } catch (RemoteException e) { attemptDeadServiceRecovery(e); @@ -504,18 +506,20 @@ public final class NfcAdapter { * * <p>This method must be called from the main thread. */ - public void disableNdefPushDispatch(Activity activity) { - disableForegroundDispatchInternal(activity, false); + public void disableForegroundNdefPush(Activity activity) { + ActivityThread.currentActivityThread().unregisterOnActivityPausedListener(activity, + mForegroundNdefPushListener); + disableForegroundNdefPushInternal(activity, false); } - class ForegroundNdefPushPausedListener implements OnActivityPausedListener { + OnActivityPausedListener mForegroundNdefPushListener = new OnActivityPausedListener() { @Override public void onPaused(Activity activity) { - disableNdefPushDispatchInternal(activity, true); + disableForegroundNdefPushInternal(activity, true); } - } + }; - void disableNdefPushDispatchInternal(Activity activity, boolean force) { + void disableForegroundNdefPushInternal(Activity activity, boolean force) { try { sService.disableForegroundNdefPush(activity.getComponentName()); if (!force && !activity.isResumed()) { diff --git a/core/java/android/nfc/Tag.java b/core/java/android/nfc/Tag.java index 7bd2289..8e2360a 100644 --- a/core/java/android/nfc/Tag.java +++ b/core/java/android/nfc/Tag.java @@ -36,8 +36,8 @@ import java.util.Arrays; /** * Represents a (generic) discovered tag. * <p> - * A tag is a passive NFC element, such as NFC Forum Tag's, Mifare class Tags, - * Sony Felica Tags. + * A tag is a passive NFC element, such as NFC Forum Tag's, MIFARE class Tags, + * Sony FeliCa Tags, etc. * <p> * Tag's have a type and usually have a UID. * <p> diff --git a/core/java/android/nfc/technology/BasicTagTechnology.java b/core/java/android/nfc/technology/BasicTagTechnology.java index f529ee5..6d3292b 100644 --- a/core/java/android/nfc/technology/BasicTagTechnology.java +++ b/core/java/android/nfc/technology/BasicTagTechnology.java @@ -39,10 +39,7 @@ import android.util.Log; /*package*/ final INfcAdapter mService; /*package*/ final INfcTag mTagService; - /** - * @hide - */ - public BasicTagTechnology(NfcAdapter adapter, Tag tag, int tech) throws RemoteException { + BasicTagTechnology(NfcAdapter adapter, Tag tag, int tech) throws RemoteException { int[] techList = tag.getTechnologyList(); int i; @@ -64,46 +61,36 @@ import android.util.Log; mSelectedTechnology = tech; } - /** - * @hide - */ - public BasicTagTechnology(NfcAdapter adapter, Tag tag) throws RemoteException { + BasicTagTechnology(NfcAdapter adapter, Tag tag) throws RemoteException { this(adapter, tag, tag.getTechnologyList()[0]); } - /** - * Get the {@link Tag} this connection is associated with. - * <p>Requires {@link android.Manifest.permission#NFC} permission. - */ @Override public Tag getTag() { return mTag; } - public void checkConnected() { + /** Internal helper to throw IllegalStateException if the technology isn't connected */ + void checkConnected() { if ((mTag.getConnectedTechnology() != getTechnologyId()) || (mTag.getConnectedTechnology() == -1)) { throw new IllegalStateException("Call connect() first!"); } } - /** - * <p>Requires {@link android.Manifest.permission#NFC} permission. - */ @Override public int getTechnologyId() { return mSelectedTechnology; } /** - * Helper to indicate if {@link #transceive transceive()} calls might succeed. + * Helper to indicate if {@link #connect} has succeeded. * <p> * Does not cause RF activity, and does not block. - * <p>Requires {@link android.Manifest.permission#NFC} permission. * @return true if {@link #connect} has completed successfully and the {@link Tag} is believed * to be within range. Applications must still handle {@link java.io.IOException} - * while using {@link #transceive transceive()}, in case connection is lost after this method - * returns true. + * while using methods that require a connection in case the connection is lost after this + * method returns. */ public boolean isConnected() { if (!mIsConnected) { @@ -118,16 +105,6 @@ import android.util.Log; } } - /** - * Connect to the {@link Tag} associated with this connection. - * <p> - * This method blocks until the connection is established. - * <p> - * {@link #close} can be called from another thread to cancel this connection - * attempt. - * <p>Requires {@link android.Manifest.permission#NFC} permission. - * @throws IOException if the target is lost, or connect canceled - */ @Override public void connect() throws IOException { try { @@ -146,17 +123,6 @@ import android.util.Log; } } - /** - * Re-connect to the {@link Tag} associated with this connection. - * <p> - * Reconnecting to a tag can be used to reset the state of the tag itself. - * This method blocks until the connection is re-established. - * <p> - * {@link #close} can be called from another thread to cancel this connection - * attempt. - * <p>Requires {@link android.Manifest.permission#NFC} permission. - * @throws IOException if the target is lost, or connect canceled - */ @Override public void reconnect() throws IOException { if (!mIsConnected) { @@ -179,16 +145,6 @@ import android.util.Log; } } - /** - * Close this connection. - * <p> - * Causes blocking operations such as {@link #transceive transceive()} or {@link #connect} to - * be canceled and immediately throw {@link java.io.IOException}. - * <p> - * Once this method is called, this object cannot be re-used and should be discarded. Further - * calls to {@link #transceive transceive()} or {@link #connect} will fail. - * <p>Requires {@link android.Manifest.permission#NFC} permission. - */ @Override public void close() { try { @@ -204,7 +160,7 @@ import android.util.Log; } } - /** internal transceive */ + /** Internal transceive */ /*package*/ byte[] transceive(byte[] data, boolean raw) throws IOException { checkConnected(); @@ -219,19 +175,4 @@ import android.util.Log; throw new IOException("NFC service died"); } } - - /** - * Send data to a tag and receive the response. - * <p> - * This method will block until the response is received. It can be canceled - * with {@link #close}. - * <p>Requires {@link android.Manifest.permission#NFC} permission. - * - * @param data bytes to send - * @return bytes received in response - * @throws IOException if the target is lost or connection closed - */ - public byte[] transceive(byte[] data) throws IOException { - return transceive(data, true); - } } diff --git a/core/java/android/nfc/technology/IsoDep.java b/core/java/android/nfc/technology/IsoDep.java index 03c518e..0a5b1b1 100644 --- a/core/java/android/nfc/technology/IsoDep.java +++ b/core/java/android/nfc/technology/IsoDep.java @@ -46,6 +46,7 @@ public final class IsoDep extends BasicTagTechnology { private byte[] mHiLayerResponse = null; private byte[] mHistBytes = null; + /** @hide */ public IsoDep(NfcAdapter adapter, Tag tag, Bundle extras) throws RemoteException { super(adapter, tag, TagTechnology.ISO_DEP); @@ -56,16 +57,31 @@ public final class IsoDep extends BasicTagTechnology { } /** - * 3A only + * Return the historical bytes if the tag is using {@link NfcA}, null otherwise. */ public byte[] getHistoricalBytes() { return mHistBytes; } /** - * 3B only + * Return the hi layer response bytes if the tag is using {@link NfcB}, null otherwise. */ public byte[] getHiLayerResponse() { return mHiLayerResponse; } + + /** + * Send data to a tag and receive the response. + * <p> + * This method will block until the response is received. It can be canceled + * with {@link #close}. + * <p>Requires {@link android.Manifest.permission#NFC} permission. + * + * @param data bytes to send + * @return bytes received in response + * @throws IOException if the target is lost or connection closed + */ + public byte[] transceive(byte[] data) throws IOException { + return transceive(data, true); + } } diff --git a/core/java/android/nfc/technology/MifareClassic.java b/core/java/android/nfc/technology/MifareClassic.java index 3be38fe..fc3e8b3 100644 --- a/core/java/android/nfc/technology/MifareClassic.java +++ b/core/java/android/nfc/technology/MifareClassic.java @@ -24,21 +24,22 @@ import android.os.RemoteException; import java.io.IOException; /** - * Concrete class for TagTechnology.MIFARE_CLASSIC + * Technology class representing MIFARE Classic tags (also known as MIFARE Standard). * - * MIFARE Classic has n sectors, with varying sizes, although - * they are at least the same pattern for any one MIFARE Classic - * product. Each sector has two keys. Authentication with the correct - * key is needed before access to any sector. + * <p>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. * - * Each sector has k blocks. - * Block size is constant across the whole MIFARE classic family. + * <p>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 #authenticateSector(int, byte[], boolean)} or + * {@link #authenticateBlock(int, byte[], boolean)} to gain authorize your request. */ public final class MifareClassic extends BasicTagTechnology { /** - * The well-known, default MIFARE read key. - * Use this key to effectively make the payload in this sector - * public. + * The well-known default MIFARE read key. All keys are set to this at the factory. + * Using this key will effectively make the payload in the sector public. */ public static final byte[] KEY_DEFAULT = {(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF}; @@ -53,39 +54,45 @@ public final class MifareClassic extends BasicTagTechnology { public static final byte[] KEY_NFC_FORUM = {(byte)0xD3,(byte)0xF7,(byte)0xD3,(byte)0xF7,(byte)0xD3,(byte)0xF7}; + /** A MIFARE Classic tag */ public static final int TYPE_CLASSIC = 0; + /** A MIFARE Plus tag */ public static final int TYPE_PLUS = 1; + /** A MIFARE Pro tag */ public static final int TYPE_PRO = 2; - public static final int TYPE_DESFIRE = 3; - public static final int TYPE_ULTRALIGHT = 4; + /** The tag type is unknown */ public static final int TYPE_UNKNOWN = 5; + /** The tag contains 16 sectors, each holding 4 blocks. */ public static final int SIZE_1K = 1024; + /** The tag contains 32 sectors, each holding 4 blocks. */ public static final int SIZE_2K = 2048; + /** + * The tag contains 40 sectors. The first 32 sectors contain 4 blocks and the last 8 sectors + * contain 16 blocks. + */ public static final int SIZE_4K = 4096; + /** The tag contains 5 sectors, each holding 4 blocks. */ public static final int SIZE_MINI = 320; + /** The capacity is unknown */ public static final int SIZE_UNKNOWN = 0; private boolean mIsEmulated; private int mType; private int mSize; + /** @hide */ public MifareClassic(NfcAdapter adapter, Tag tag, Bundle extras) throws RemoteException { super(adapter, tag, TagTechnology.MIFARE_CLASSIC); - // Check if this could actually be a Mifare + // Check if this could actually be a MIFARE Classic NfcA a = (NfcA) adapter.getTechnology(tag, TagTechnology.NFC_A); - //short[] ATQA = getATQA(tag); mIsEmulated = false; mType = TYPE_UNKNOWN; mSize = SIZE_UNKNOWN; switch (a.getSak()) { - case 0x00: - // could be UL or UL-C - mType = TYPE_ULTRALIGHT; - break; case 0x08: // Type == classic // Size = 1K @@ -122,7 +129,7 @@ public final class MifareClassic extends BasicTagTechnology { // TODO this really should be a short, not byte if (a.getAtqa()[0] == 0x03) { // Type == DESFIRE - mType = TYPE_DESFIRE; + break; } else { // Type == MF+ // SL = SL3 @@ -160,27 +167,25 @@ public final class MifareClassic extends BasicTagTechnology { mType = TYPE_PRO; mSize = SIZE_4K; break; - default: - // Unknown mifare - mType = TYPE_UNKNOWN; - mSize = SIZE_UNKNOWN; - break; } } - // Immutable data known at discovery time + /** Returns the size of the tag, determined at discovery time */ public int getSize() { return mSize; } + /** Returns the size of the tag, determined at discovery time */ public int getType() { return mType; } + /** Returns true if the tag is emulated, determined at discovery time */ public boolean isEmulated() { return mIsEmulated; } + /** Returns the number of sectors on this tag, determined at discovery time */ public int getSectorCount() { switch (mSize) { case SIZE_1K: { @@ -201,10 +206,12 @@ public final class MifareClassic extends BasicTagTechnology { } } + /** Returns the sector size, determined at discovery time */ public int getSectorSize(int sector) { return getBlockCount(sector) * 16; } + /** Returns the total block count, determined at discovery time */ public int getTotalBlockCount() { int totalBlocks = 0; for (int sec = 0; sec < getSectorCount(); sec++) { @@ -214,6 +221,7 @@ public final class MifareClassic extends BasicTagTechnology { return totalBlocks; } + /** Returns the block count for the given sector, determined at discovery time */ public int getBlockCount(int sector) { if (sector >= getSectorCount()) { throw new IllegalArgumentException("this card only has " + getSectorCount() + @@ -237,8 +245,8 @@ public final class MifareClassic extends BasicTagTechnology { // Methods that require connect() /** - * Authenticate for a given block. - * Note that this will authenticate the entire sector the block belongs to. + * Authenticate the entire sector that the given block resides in. + * <p>This requires a that the tag be connected. */ public boolean authenticateBlock(int block, byte[] key, boolean keyA) { checkConnected(); @@ -274,6 +282,7 @@ public final class MifareClassic extends BasicTagTechnology { /** * Authenticate for a given sector. + * <p>This requires a that the tag be connected. */ public boolean authenticateSector(int sector, byte[] key, boolean keyA) { checkConnected(); @@ -288,6 +297,7 @@ public final class MifareClassic extends BasicTagTechnology { /** * Sector indexing starts at 0. * Block indexing starts at 0, and resets in each sector. + * <p>This requires a that the tag be connected. * @throws IOException */ public byte[] readBlock(int sector, int block) throws IOException { @@ -295,11 +305,11 @@ public final class MifareClassic extends BasicTagTechnology { byte addr = (byte) ((firstBlockInSector(sector) + block) & 0xff); return readBlock(addr); - } /** * Reads absolute block index. + * <p>This requires a that the tag be connected. * @throws IOException */ public byte[] readBlock(int block) throws IOException { @@ -313,6 +323,7 @@ public final class MifareClassic extends BasicTagTechnology { /** * Writes absolute block index. + * <p>This requires a that the tag be connected. * @throws IOException */ public void writeBlock(int block, byte[] data) throws IOException { @@ -329,6 +340,7 @@ public final class MifareClassic extends BasicTagTechnology { /** * Writes relative block in sector. + * <p>This requires a that the tag be connected. * @throws IOException */ public void writeBlock(int sector, int block, byte[] data) throws IOException { @@ -342,7 +354,6 @@ public final class MifareClassic extends BasicTagTechnology { public void increment(int block) throws IOException { checkConnected(); - byte addr = (byte) block; byte[] incr_cmd = { (byte) 0xC1, (byte) block }; transceive(incr_cmd, false); @@ -351,7 +362,6 @@ public final class MifareClassic extends BasicTagTechnology { public void decrement(int block) throws IOException { checkConnected(); - byte addr = (byte) block; byte[] decr_cmd = { (byte) 0xC0, (byte) block }; transceive(decr_cmd, false); @@ -360,7 +370,6 @@ public final class MifareClassic extends BasicTagTechnology { public void transfer(int block) throws IOException { checkConnected(); - byte addr = (byte) block; byte[] trans_cmd = { (byte) 0xB0, (byte) block }; transceive(trans_cmd, false); @@ -369,9 +378,24 @@ public final class MifareClassic extends BasicTagTechnology { public void restore(int block) throws IOException { checkConnected(); - byte addr = (byte) block; byte[] rest_cmd = { (byte) 0xC2, (byte) block }; transceive(rest_cmd, false); } + + /** + * Send raw NfcA data to a tag and receive the response. + * <p> + * This method will block until the response is received. It can be canceled + * with {@link #close}. + * <p>Requires {@link android.Manifest.permission#NFC} permission. + * <p>This requires a that the tag be connected. + * + * @param data bytes to send + * @return bytes received in response + * @throws IOException if the target is lost or connection closed + */ + public byte[] transceive(byte[] data) throws IOException { + return transceive(data, true); + } } diff --git a/core/java/android/nfc/technology/MifareUltralight.java b/core/java/android/nfc/technology/MifareUltralight.java index 525b85b..5c8cb3c 100644 --- a/core/java/android/nfc/technology/MifareUltralight.java +++ b/core/java/android/nfc/technology/MifareUltralight.java @@ -16,33 +16,35 @@ package android.nfc.technology; -import java.io.IOException; - import android.nfc.NfcAdapter; import android.nfc.Tag; import android.os.Bundle; import android.os.RemoteException; +import java.io.IOException; + /** - * Concrete class for TagTechnology.MIFARE_ULTRALIGHT + * Technology class representing MIFARE Ultralight and MIFARE Ultralight C tags. * - * MIFARE Ultralight has n sectors, with varying sizes, although - * they are at least the same pattern for any one MIFARE Ultralight - * product. Each sector has two keys. Authentication with the correct - * key is needed before access to any sector. + * <p>Support for this technology type is optional. If the NFC stack doesn't support this technology + * MIFARE Ultralight class tags will still be scanned, but will only show the NfcA technology. * - * Each sector has k blocks. - * Block size is constant across the whole MIFARE Ultralight family. + * <p>MIFARE Ultralight class tags have a series of 4 bytes pages that can be individually written + * and read in chunks of 4 for a total read of 16 bytes. */ public final class MifareUltralight extends BasicTagTechnology { + /** A MIFARE Ultralight tag */ public static final int TYPE_ULTRALIGHT = 1; + /** A MIFARE Ultralight C tag */ public static final int TYPE_ULTRALIGHT_C = 2; + /** The tag type is unknown */ public static final int TYPE_UNKNOWN = 10; private static final int NXP_MANUFACTURER_ID = 0x04; private int mType; + /** @hide */ public MifareUltralight(NfcAdapter adapter, Tag tag, Bundle extras) throws RemoteException { super(adapter, tag, TagTechnology.MIFARE_ULTRALIGHT); @@ -57,49 +59,59 @@ public final class MifareUltralight extends BasicTagTechnology { } } + /** Returns the type of the tag */ public int getType() { return mType; } // Methods that require connect() /** + * Reads a single 16 byte block from the given page offset. + * + * <p>This requires a that the tag be connected. + * * @throws IOException */ - public byte[] readBlock(int block) throws IOException { + public byte[] readBlock(int page) throws IOException { checkConnected(); - byte[] blockread_cmd = { 0x30, (byte)block }; // phHal_eMifareRead + byte[] blockread_cmd = { 0x30, (byte) page}; // phHal_eMifareRead return transceive(blockread_cmd, false); } /** + * Writes a 4 byte page to the tag. + * + * <p>This requires a that the tag be connected. + * + * @param page The offset of the page to write + * @param data The data to write * @throws IOException */ - public byte[] readOTP() throws IOException { - checkConnected(); - - return readBlock(3); // OTP is at page 3 - } - - public void writePage(int block, byte[] data) throws IOException { + public void writePage(int page, byte[] data) throws IOException { checkConnected(); byte[] pagewrite_cmd = new byte[data.length + 2]; pagewrite_cmd[0] = (byte) 0xA2; - pagewrite_cmd[1] = (byte) block; + pagewrite_cmd[1] = (byte) page; System.arraycopy(data, 0, pagewrite_cmd, 2, data.length); transceive(pagewrite_cmd, false); } - public void writeBlock(int block, byte[] data) throws IOException { - checkConnected(); - - byte[] blockwrite_cmd = new byte[data.length + 2]; - blockwrite_cmd[0] = (byte) 0xA0; - blockwrite_cmd[1] = (byte) block; - System.arraycopy(data, 0, blockwrite_cmd, 2, data.length); - - transceive(blockwrite_cmd, false); + /** + * Send raw NfcA data to a tag and receive the response. + * <p> + * This method will block until the response is received. It can be canceled + * with {@link #close}. + * <p>Requires {@link android.Manifest.permission#NFC} permission. + * <p>This requires a that the tag be connected. + * + * @param data bytes to send + * @return bytes received in response + * @throws IOException if the target is lost or connection closed + */ + public byte[] transceive(byte[] data) throws IOException { + return transceive(data, true); } } diff --git a/core/java/android/nfc/technology/Ndef.java b/core/java/android/nfc/technology/Ndef.java index 5f05b58..1c0afde 100644 --- a/core/java/android/nfc/technology/Ndef.java +++ b/core/java/android/nfc/technology/Ndef.java @@ -100,15 +100,6 @@ public final class Ndef extends BasicTagTechnology { } /** - * Get optional extra NDEF messages. - * Some tags may contain extra NDEF messages, but not all - * implementations will be able to read them. - */ - public NdefMessage[] getExtraNdefMessage() throws IOException, FormatException { - throw new UnsupportedOperationException(); - } - - /** * Get NDEF tag type. * <p>Returns one of {@link #NFC_FORUM_TYPE_1}, {@link #NFC_FORUM_TYPE_2}, * {@link #NFC_FORUM_TYPE_3}, {@link #NFC_FORUM_TYPE_4}, @@ -208,22 +199,6 @@ public final class Ndef extends BasicTagTechnology { } /** - * Attempt to write extra NDEF messages. - * Implementations may be able to write extra NDEF - * message after the first primary message, but it is not - * guaranteed. Even if it can be written, other implementations - * may not be able to read NDEF messages after the primary message. - * It is recommended to use additional NDEF records instead. - * - * @throws IOException - */ - public void writeExtraNdefMessage(int i, NdefMessage msg) throws IOException, FormatException { - checkConnected(); - - throw new UnsupportedOperationException(); - } - - /** * Indicates whether a tag can be made read-only with * {@link #makeReadonly()} */ @@ -263,11 +238,4 @@ public final class Ndef extends BasicTagTechnology { return false; } } - - @Override - public byte[] transceive(byte[] data) { - checkConnected(); - - throw new UnsupportedOperationException(); - } } diff --git a/core/java/android/nfc/technology/NdefFormatable.java b/core/java/android/nfc/technology/NdefFormatable.java index 0901607..e2fd034 100644 --- a/core/java/android/nfc/technology/NdefFormatable.java +++ b/core/java/android/nfc/technology/NdefFormatable.java @@ -91,11 +91,4 @@ public final class NdefFormatable extends BasicTagTechnology { Log.e(TAG, "NFC service dead", e); } } - - @Override - public byte[] transceive(byte[] data) { - checkConnected(); - - throw new UnsupportedOperationException(); - } } diff --git a/core/java/android/nfc/technology/NfcA.java b/core/java/android/nfc/technology/NfcA.java index 20fe09e..0615a10 100644 --- a/core/java/android/nfc/technology/NfcA.java +++ b/core/java/android/nfc/technology/NfcA.java @@ -21,6 +21,8 @@ import android.nfc.Tag; import android.os.Bundle; import android.os.RemoteException; +import java.io.IOException; + /** * A low-level connection to a {@link Tag} using the NFC-A technology, also known as * ISO1443-3A. @@ -44,6 +46,7 @@ public final class NfcA extends BasicTagTechnology { private short mSak; private byte[] mAtqa; + /** @hide */ public NfcA(NfcAdapter adapter, Tag tag, Bundle extras) throws RemoteException { super(adapter, tag, TagTechnology.NFC_A); mSak = extras.getShort(EXTRA_SAK); @@ -63,4 +66,19 @@ public final class NfcA extends BasicTagTechnology { public short getSak() { return mSak; } + + /** + * Send data to a tag and receive the response. + * <p> + * This method will block until the response is received. It can be canceled + * with {@link #close}. + * <p>Requires {@link android.Manifest.permission#NFC} permission. + * + * @param data bytes to send + * @return bytes received in response + * @throws IOException if the target is lost or connection closed + */ + public byte[] transceive(byte[] data) throws IOException { + return transceive(data, true); + } } diff --git a/core/java/android/nfc/technology/NfcB.java b/core/java/android/nfc/technology/NfcB.java index 767558e..c14b98d 100644 --- a/core/java/android/nfc/technology/NfcB.java +++ b/core/java/android/nfc/technology/NfcB.java @@ -21,6 +21,8 @@ import android.nfc.Tag; import android.os.Bundle; import android.os.RemoteException; +import java.io.IOException; + /** * A low-level connection to a {@link Tag} using the NFC-B technology, also known as * ISO1443-3B. @@ -44,6 +46,7 @@ public final class NfcB extends BasicTagTechnology { private byte[] mAppData; private byte[] mProtInfo; + /** @hide */ public NfcB(NfcAdapter adapter, Tag tag, Bundle extras) throws RemoteException { super(adapter, tag, TagTechnology.NFC_B); @@ -67,4 +70,18 @@ public final class NfcB extends BasicTagTechnology { return mProtInfo; } + /** + * Send data to a tag and receive the response. + * <p> + * This method will block until the response is received. It can be canceled + * with {@link #close}. + * <p>Requires {@link android.Manifest.permission#NFC} permission. + * + * @param data bytes to send + * @return bytes received in response + * @throws IOException if the target is lost or connection closed + */ + public byte[] transceive(byte[] data) throws IOException { + return transceive(data, true); + } } diff --git a/core/java/android/nfc/technology/NfcF.java b/core/java/android/nfc/technology/NfcF.java index f7f1fd3..434e5df 100644 --- a/core/java/android/nfc/technology/NfcF.java +++ b/core/java/android/nfc/technology/NfcF.java @@ -21,6 +21,8 @@ import android.nfc.Tag; import android.os.Bundle; import android.os.RemoteException; +import java.io.IOException; + /** * A low-level connection to a {@link Tag} using the NFC-F technology, also known as * JIS6319-4. @@ -44,6 +46,7 @@ public final class NfcF extends BasicTagTechnology { private byte[] mSystemCode = null; private byte[] mManufacturer = null; + /** @hide */ public NfcF(NfcAdapter adapter, Tag tag, Bundle extras) throws RemoteException { super(adapter, tag, TagTechnology.NFC_F); @@ -60,4 +63,19 @@ public final class NfcF extends BasicTagTechnology { public byte[] getManufacturer() { return mManufacturer; } + + /** + * Send data to a tag and receive the response. + * <p> + * This method will block until the response is received. It can be canceled + * with {@link #close}. + * <p>Requires {@link android.Manifest.permission#NFC} permission. + * + * @param data bytes to send + * @return bytes received in response + * @throws IOException if the target is lost or connection closed + */ + public byte[] transceive(byte[] data) throws IOException { + return transceive(data, true); + } } diff --git a/core/java/android/nfc/technology/NfcV.java b/core/java/android/nfc/technology/NfcV.java index 4b51119..142ef9d 100644 --- a/core/java/android/nfc/technology/NfcV.java +++ b/core/java/android/nfc/technology/NfcV.java @@ -21,8 +21,10 @@ import android.nfc.Tag; import android.os.Bundle; import android.os.RemoteException; +import java.io.IOException; + /** - * A low-level connection to a {@link Tag} using the NFC-V technology, also known as + * A low-level connection to a {@link Tag} using NFC vicinity technology, also known as * ISO15693. * * <p>You can acquire this kind of connection with {@link NfcAdapter#getTechnology}. @@ -45,6 +47,7 @@ public final class NfcV extends BasicTagTechnology { private byte mRespFlags; private byte mDsfId; + /** @hide */ public NfcV(NfcAdapter adapter, Tag tag, Bundle extras) throws RemoteException { super(adapter, tag, TagTechnology.NFC_V); @@ -59,4 +62,19 @@ public final class NfcV extends BasicTagTechnology { public byte getDsfId() { return mDsfId; } + + /** + * Send data to a tag and receive the response. + * <p> + * This method will block until the response is received. It can be canceled + * with {@link #close}. + * <p>Requires {@link android.Manifest.permission#NFC} permission. + * + * @param data bytes to send + * @return bytes received in response + * @throws IOException if the target is lost or connection closed + */ + public byte[] transceive(byte[] data) throws IOException { + return transceive(data, true); + } } diff --git a/core/java/android/nfc/technology/TagTechnology.java b/core/java/android/nfc/technology/TagTechnology.java index 62216c1..96f1724 100644 --- a/core/java/android/nfc/technology/TagTechnology.java +++ b/core/java/android/nfc/technology/TagTechnology.java @@ -22,47 +22,60 @@ import java.io.IOException; public interface TagTechnology { /** - * This object is an instance of {@link NfcA} + * This technology is an instance of {@link NfcA}. + * <p>Support for this technology type is mandatory. */ public static final int NFC_A = 1; /** - * This object is an instance of {@link NfcB} + * This technology is an instance of {@link NfcB}. + * <p>Support for this technology type is mandatory. */ public static final int NFC_B = 2; /** - * This object is an instance of {@link IsoDep} + * This technology is an instance of {@link IsoDep}. + * <p>Support for this technology type is mandatory. */ public static final int ISO_DEP = 3; /** - * This object is an instance of {@link NfcF} + * This technology is an instance of {@link NfcF}. + * <p>Support for this technology type is mandatory. */ public static final int NFC_F = 4; /** - * This object is an instance of {@link NfcV} + * This technology is an instance of {@link NfcV}. + * <p>Support for this technology type is mandatory. */ public static final int NFC_V = 5; /** - * This object is an instance of {@link Ndef} + * This technology is an instance of {@link Ndef}. + * <p>Support for this technology type is mandatory. */ public static final int NDEF = 6; /** - * This object is an instance of {@link NdefFormatable} + * This technology is an instance of {@link NdefFormatable}. + * <p>Support for this technology type is mandatory. */ public static final int NDEF_FORMATABLE = 7; /** - * This object is an instance of {@link MifareClassic} + * This technology is an instance of {@link MifareClassic}. + * <p>Support for this technology type is optional. If a stack doesn't support this technology + * type tags using it must still be discovered and present the lower level radio interface + * technologies in use. */ public static final int MIFARE_CLASSIC = 8; /** - * This object is an instance of {@link MifareUltralight} + * This technology is an instance of {@link MifareUltralight}. + * <p>Support for this technology type is optional. If a stack doesn't support this technology + * type tags using it must still be discovered and present the lower level radio interface + * technologies in use. */ public static final int MIFARE_ULTRALIGHT = 9; @@ -72,23 +85,51 @@ public interface TagTechnology { public int getTechnologyId(); /** - * Get the backing tag object. + * Get the {@link Tag} object this technology came from. */ public Tag getTag(); /** - * @throws IOException + * Opens a connection to the {@link Tag} enabling interactive commands. The command set + * varies by the technology type. + * + * <p>This method blocks until the connection has been established. + * + * <p>A call to {@link #close} from another thread will cancel a blocked call and cause an + * IOException to be thrown on the thread that is blocked. + * + * @see #reconnect() + * @see #close() + * @throws IOException if the target is lost, or connect canceled */ public void connect() throws IOException; /** + * Re-connect to the {@link Tag} associated with this connection. Reconnecting to a tag can be + * used to reset the state of the tag itself. + * + * <p>This method blocks until the connection is re-established. + * + * <p>A call to {@link #close} from another thread will cancel a blocked call and cause an + * IOException to be thrown on the thread that is blocked. + * + * @see #connect() + * @see #close() * @throws IOException */ public void reconnect() throws IOException; /** - * Non-blocking. Immediately causes all blocking calls - * to throw IOException. + * Closes the connection to the {@link Tag}. This call is non-blocking and causes all blocking + * operations such as {@link #connect} to be canceled and immediately throw + * {@link java.io.IOException} on the thread that is blocked. + * + * <p> + * Once this method is called, this object cannot be re-used and should be discarded. Further + * calls to {@link #connect} will fail. + * + * @see #connect() + * @see #reconnect() */ public void close(); } |