Javadoc updates for NFC.
Change-Id: Ibd91829979576297599fbcc9eb8054924af1d527
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 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 @@
}
try {
ActivityThread.currentActivityThread().registerOnActivityPausedListener(activity,
- new ForegroundDispatchPausedListener());
+ mForegroundDispatchListener);
sService.enableForegroundDispatch(activity.getComponentName(), intent, filters);
} catch (RemoteException e) {
attemptDeadServiceRecovery(e);
@@ -453,15 +453,17 @@
* <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 @@
}
try {
ActivityThread.currentActivityThread().registerOnActivityPausedListener(activity,
- new ForegroundDispatchPausedListener());
+ mForegroundNdefPushListener);
sService.enableForegroundNdefPush(activity.getComponentName(), msg);
} catch (RemoteException e) {
attemptDeadServiceRecovery(e);
@@ -504,18 +506,20 @@
*
* <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 @@
/**
* 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 @@
/*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 @@
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 @@
}
}
- /**
- * 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 @@
}
}
- /**
- * 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 @@
}
}
- /**
- * 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 @@
}
}
- /** internal transceive */
+ /** Internal transceive */
/*package*/ byte[] transceive(byte[] data, boolean raw) throws IOException {
checkConnected();
@@ -219,19 +175,4 @@
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 @@
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 @@
}
/**
- * 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 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 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 @@
// 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 @@
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 @@
}
}
+ /** 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 @@
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 @@
// 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 @@
/**
* 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 @@
/**
* 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 @@
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 @@
/**
* 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 @@
/**
* 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 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 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 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 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 @@
}
}
+ /** 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 @@
}
/**
- * 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 @@
}
/**
- * 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 @@
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 @@
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.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 @@
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 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.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 @@
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 @@
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.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 @@
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 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.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 @@
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 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 @@
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 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();
}