Push Tag/NdefTag implementation details into the service.
Tag/NdefTag objects should just be simple data objects. Push the mapping of internal tag type to public rawTarget/ndefTarget into Nfc Service. This gives an oppurtunity to clean up some Tag/NdefTag API methods. Most significantly, adding createMockTag() and createMockNdefTag() to help with application testing. There will probably be some more tweaking of the types/targets in Tag/NdefTag to come, this commit makes that a lot easier. Also: - Introduce getActivationBytes() and getPollBytes(). These are just stubs for NFC service to implement, we have feedback these are really important to help identify NFC tags. - Based on outside advice, remove 3B_PRIME (roll into 3B) and TOPAZ (roll into 3A). Change-Id: I3e6789c047f6ee5c298bf76c65e0885cf3c15d97 Signed-off-by: Nick Pelly <npelly@google.com>
This commit is contained in:
@@ -100172,6 +100172,29 @@
|
|||||||
>
|
>
|
||||||
<implements name="android.os.Parcelable">
|
<implements name="android.os.Parcelable">
|
||||||
</implements>
|
</implements>
|
||||||
|
<method name="createMockNdefTag"
|
||||||
|
return="android.nfc.NdefTag"
|
||||||
|
abstract="false"
|
||||||
|
native="false"
|
||||||
|
synchronized="false"
|
||||||
|
static="true"
|
||||||
|
final="false"
|
||||||
|
deprecated="not deprecated"
|
||||||
|
visibility="public"
|
||||||
|
>
|
||||||
|
<parameter name="id" type="byte[]">
|
||||||
|
</parameter>
|
||||||
|
<parameter name="rawTargets" type="java.lang.String[]">
|
||||||
|
</parameter>
|
||||||
|
<parameter name="pollBytes" type="byte[]">
|
||||||
|
</parameter>
|
||||||
|
<parameter name="activationBytes" type="byte[]">
|
||||||
|
</parameter>
|
||||||
|
<parameter name="ndefTargets" type="java.lang.String[]">
|
||||||
|
</parameter>
|
||||||
|
<parameter name="messages" type="android.nfc.NdefMessage[][]">
|
||||||
|
</parameter>
|
||||||
|
</method>
|
||||||
<method name="getNdefMessages"
|
<method name="getNdefMessages"
|
||||||
return="android.nfc.NdefMessage[]"
|
return="android.nfc.NdefMessage[]"
|
||||||
abstract="false"
|
abstract="false"
|
||||||
@@ -100641,6 +100664,25 @@
|
|||||||
>
|
>
|
||||||
<implements name="android.os.Parcelable">
|
<implements name="android.os.Parcelable">
|
||||||
</implements>
|
</implements>
|
||||||
|
<method name="createMockTag"
|
||||||
|
return="android.nfc.Tag"
|
||||||
|
abstract="false"
|
||||||
|
native="false"
|
||||||
|
synchronized="false"
|
||||||
|
static="true"
|
||||||
|
final="false"
|
||||||
|
deprecated="not deprecated"
|
||||||
|
visibility="public"
|
||||||
|
>
|
||||||
|
<parameter name="id" type="byte[]">
|
||||||
|
</parameter>
|
||||||
|
<parameter name="rawTargets" type="java.lang.String[]">
|
||||||
|
</parameter>
|
||||||
|
<parameter name="pollBytes" type="byte[]">
|
||||||
|
</parameter>
|
||||||
|
<parameter name="activationBytes" type="byte[]">
|
||||||
|
</parameter>
|
||||||
|
</method>
|
||||||
<method name="describeContents"
|
<method name="describeContents"
|
||||||
return="int"
|
return="int"
|
||||||
abstract="false"
|
abstract="false"
|
||||||
@@ -100652,6 +100694,17 @@
|
|||||||
visibility="public"
|
visibility="public"
|
||||||
>
|
>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="getActivationBytes"
|
||||||
|
return="byte[]"
|
||||||
|
abstract="false"
|
||||||
|
native="false"
|
||||||
|
synchronized="false"
|
||||||
|
static="false"
|
||||||
|
final="false"
|
||||||
|
deprecated="not deprecated"
|
||||||
|
visibility="public"
|
||||||
|
>
|
||||||
|
</method>
|
||||||
<method name="getId"
|
<method name="getId"
|
||||||
return="byte[]"
|
return="byte[]"
|
||||||
abstract="false"
|
abstract="false"
|
||||||
@@ -100663,6 +100716,17 @@
|
|||||||
visibility="public"
|
visibility="public"
|
||||||
>
|
>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="getPollBytes"
|
||||||
|
return="byte[]"
|
||||||
|
abstract="false"
|
||||||
|
native="false"
|
||||||
|
synchronized="false"
|
||||||
|
static="false"
|
||||||
|
final="false"
|
||||||
|
deprecated="not deprecated"
|
||||||
|
visibility="public"
|
||||||
|
>
|
||||||
|
</method>
|
||||||
<method name="getRawTargets"
|
<method name="getRawTargets"
|
||||||
return="java.lang.String[]"
|
return="java.lang.String[]"
|
||||||
abstract="false"
|
abstract="false"
|
||||||
@@ -100721,17 +100785,6 @@
|
|||||||
visibility="public"
|
visibility="public"
|
||||||
>
|
>
|
||||||
</field>
|
</field>
|
||||||
<field name="TARGET_ISO_14443_3B_PRIME"
|
|
||||||
type="java.lang.String"
|
|
||||||
transient="false"
|
|
||||||
volatile="false"
|
|
||||||
value=""iso14443_3b""
|
|
||||||
static="true"
|
|
||||||
final="true"
|
|
||||||
deprecated="not deprecated"
|
|
||||||
visibility="public"
|
|
||||||
>
|
|
||||||
</field>
|
|
||||||
<field name="TARGET_ISO_14443_4"
|
<field name="TARGET_ISO_14443_4"
|
||||||
type="java.lang.String"
|
type="java.lang.String"
|
||||||
transient="false"
|
transient="false"
|
||||||
@@ -100776,17 +100829,6 @@
|
|||||||
visibility="public"
|
visibility="public"
|
||||||
>
|
>
|
||||||
</field>
|
</field>
|
||||||
<field name="TARGET_TOPAZ"
|
|
||||||
type="java.lang.String"
|
|
||||||
transient="false"
|
|
||||||
volatile="false"
|
|
||||||
value=""topaz""
|
|
||||||
static="true"
|
|
||||||
final="true"
|
|
||||||
deprecated="not deprecated"
|
|
||||||
visibility="public"
|
|
||||||
>
|
|
||||||
</field>
|
|
||||||
</class>
|
</class>
|
||||||
</package>
|
</package>
|
||||||
<package name="android.opengl"
|
<package name="android.opengl"
|
||||||
|
|||||||
@@ -16,8 +16,6 @@
|
|||||||
|
|
||||||
package android.nfc;
|
package android.nfc;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
|
|
||||||
@@ -33,19 +31,92 @@ import android.os.Parcelable;
|
|||||||
* is possible for {@link NdefTag}s to contain multiple {@link NdefMessage}s.
|
* is possible for {@link NdefTag}s to contain multiple {@link NdefMessage}s.
|
||||||
* <p>{@link NfcAdapter#createNdefTagConnection createNdefTagConnection()} can be used to modify the
|
* <p>{@link NfcAdapter#createNdefTagConnection createNdefTagConnection()} can be used to modify the
|
||||||
* contents of some tags.
|
* contents of some tags.
|
||||||
* <p>This is an immutable data class.
|
* <p>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 class NdefTag extends Tag implements Parcelable {
|
public class NdefTag extends Tag implements Parcelable {
|
||||||
private final NdefMessage[] mMessages;
|
/**
|
||||||
|
* Target for NFC Forum Type 1 compliant tag.
|
||||||
|
* <p>This is based on Jewel/Topaz technology
|
||||||
|
*/
|
||||||
|
public static final String TARGET_TYPE_1 = "type_1";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hidden constructor to be used by NFC service when a
|
* Target for NFC Forum Type 2 compliant tag.
|
||||||
* tag is discovered and by Parcelable methods.
|
* <p>This is based on Mifare Ultralight technology.
|
||||||
|
*/
|
||||||
|
public static final String TARGET_TYPE_2 = "type_2";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Target for NFC Forum Type 3 compliant tag.
|
||||||
|
* <p>This is based on Felica technology.
|
||||||
|
*/
|
||||||
|
public static final String TARGET_TYPE_3 = "type_3";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Target for NFC Forum Type 4 compliant tag.
|
||||||
|
* <p>This is based on Mifare Desfire technology.
|
||||||
|
*/
|
||||||
|
public static final String TARGET_TYPE_4 = "type_4";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Target for NFC Forum Enabled: Mifare Classic tag.
|
||||||
|
* <p>This is not strictly a NFC Forum tag type, but is a common
|
||||||
|
* NDEF message container.
|
||||||
|
*/
|
||||||
|
public static final String TARGET_MIFARE_CLASSIC = "type_mifare_classic";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Any other target.
|
||||||
|
*/
|
||||||
|
public static final String TARGET_OTHER = "other";
|
||||||
|
|
||||||
|
private final String[] mNdefTargets;
|
||||||
|
private final NdefMessage[][] mMessages; // one NdefMessage[] per NDEF target
|
||||||
|
private NdefMessage[] mFlatMessages; // collapsed mMessages, built lazily, protected by (this)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hidden constructor to be used by NFC service only.
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public NdefTag(String typeName, byte[] uid, int nativeHandle, NdefMessage[] messages) {
|
public NdefTag(byte[] id, String[] rawTargets, byte[] pollBytes, byte[] activationBytes,
|
||||||
super(typeName, true, uid, nativeHandle);
|
int serviceHandle, String[] ndefTargets, NdefMessage[][] messages) {
|
||||||
mMessages = messages.clone();
|
super(id, true, rawTargets, pollBytes, activationBytes, serviceHandle);
|
||||||
|
if (ndefTargets == null || messages == null) {
|
||||||
|
throw new IllegalArgumentException("ndefTargets or messages cannot be null");
|
||||||
|
}
|
||||||
|
if (ndefTargets.length != messages.length){
|
||||||
|
throw new IllegalArgumentException("ndefTargets and messages arrays must match");
|
||||||
|
}
|
||||||
|
for (NdefMessage[] ms : messages) {
|
||||||
|
if (ms == null) {
|
||||||
|
throw new IllegalArgumentException("messages elements cannot be null");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mNdefTargets = ndefTargets;
|
||||||
|
mMessages = messages;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a mock NdefTag.
|
||||||
|
* <p>This is an application constructed tag, so NfcAdapter methods on this
|
||||||
|
* Tag such as {@link NfcAdapter#createRawTagConnection} will fail with
|
||||||
|
* {@link IllegalArgumentException} since it does not represent a physical Tag.
|
||||||
|
* <p>This constructor might be useful for mock testing.
|
||||||
|
* @param id The tag identifier, can be null
|
||||||
|
* @param rawTargets must not be null
|
||||||
|
* @param pollBytes can be null
|
||||||
|
* @param activationBytes can be null
|
||||||
|
* @param ndefTargets NDEF target array, such as {TARGET_TYPE_2}, cannot be null
|
||||||
|
* @param messages messages, one array per NDEF target, cannot be null
|
||||||
|
* @return freshly constructed NdefTag
|
||||||
|
*/
|
||||||
|
public static NdefTag createMockNdefTag(byte[] id, String[] rawTargets, byte[] pollBytes,
|
||||||
|
byte[] activationBytes, String[] ndefTargets, NdefMessage[][] messages) {
|
||||||
|
// set serviceHandle to 0 to indicate mock tag
|
||||||
|
return new NdefTag(id, rawTargets, pollBytes, activationBytes, 0, ndefTargets, messages);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -59,7 +130,29 @@ public class NdefTag extends Tag implements Parcelable {
|
|||||||
* @return NDEF Messages found at Tag discovery
|
* @return NDEF Messages found at Tag discovery
|
||||||
*/
|
*/
|
||||||
public NdefMessage[] getNdefMessages() {
|
public NdefMessage[] getNdefMessages() {
|
||||||
return mMessages.clone();
|
// common-case optimization
|
||||||
|
if (mMessages.length == 1) {
|
||||||
|
return mMessages[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// return cached flat array
|
||||||
|
synchronized(this) {
|
||||||
|
if (mFlatMessages != null) {
|
||||||
|
return mFlatMessages;
|
||||||
|
}
|
||||||
|
// not cached - build a flat array
|
||||||
|
int sz = 0;
|
||||||
|
for (NdefMessage[] ms : mMessages) {
|
||||||
|
sz += ms.length;
|
||||||
|
}
|
||||||
|
mFlatMessages = new NdefMessage[sz];
|
||||||
|
int i = 0;
|
||||||
|
for (NdefMessage[] ms : mMessages) {
|
||||||
|
System.arraycopy(ms, 0, mFlatMessages, i, ms.length);
|
||||||
|
i += ms.length;
|
||||||
|
}
|
||||||
|
return mFlatMessages;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -70,58 +163,25 @@ public class NdefTag extends Tag implements Parcelable {
|
|||||||
* <p>
|
* <p>
|
||||||
* Most tags only contain a single NDEF message.
|
* Most tags only contain a single NDEF message.
|
||||||
*
|
*
|
||||||
* @param target One of targets strings provided by getNdefTargets()
|
* @param target one of targets strings provided by getNdefTargets()
|
||||||
* @return NDEF Messages found at Tag discovery
|
* @return NDEF Messages found at Tag discovery
|
||||||
*/
|
*/
|
||||||
public NdefMessage[] getNdefMessages(String target) {
|
public NdefMessage[] getNdefMessages(String target) {
|
||||||
// TODO: handle multiprotocol
|
for (int i=0; i<mNdefTargets.length; i++) {
|
||||||
String[] localTypes = convertToNdefType(mTypeName);
|
if (target.equals(mNdefTargets[i])) {
|
||||||
if (!target.equals(localTypes[0])) {
|
return mMessages[i];
|
||||||
throw new IllegalArgumentException();
|
}
|
||||||
}
|
}
|
||||||
return getNdefMessages();
|
throw new IllegalArgumentException("target (" + target + ") not found");
|
||||||
}
|
|
||||||
|
|
||||||
/** TODO(npelly):
|
|
||||||
* - check that any single tag can only have one of each NDEF type
|
|
||||||
* - ok to include mifare_classic?
|
|
||||||
*/
|
|
||||||
public static final String TARGET_TYPE_1 = "type_1";
|
|
||||||
public static final String TARGET_TYPE_2 = "type_2";
|
|
||||||
public static final String TARGET_TYPE_3 = "type_3";
|
|
||||||
public static final String TARGET_TYPE_4 = "type_4";
|
|
||||||
public static final String TARGET_MIFARE_CLASSIC = "type_mifare_classic";
|
|
||||||
public static final String TARGET_OTHER = "other";
|
|
||||||
|
|
||||||
private static final HashMap<String, String[]> NDEF_TYPES_CONVERTION_TABLE = new HashMap<String, String[]>() {
|
|
||||||
{
|
|
||||||
// TODO: handle multiprotocol
|
|
||||||
// TODO: move INTERNAL_TARGET_Type to TARGET_TYPE mapping to NFC service
|
|
||||||
put(Tag.INTERNAL_TARGET_TYPE_JEWEL, new String[] { NdefTag.TARGET_TYPE_1 });
|
|
||||||
put(Tag.INTERNAL_TARGET_TYPE_MIFARE_UL, new String[] { NdefTag.TARGET_TYPE_2 });
|
|
||||||
put(Tag.INTERNAL_TARGET_TYPE_MIFARE_1K, new String[] { NdefTag.TARGET_MIFARE_CLASSIC });
|
|
||||||
put(Tag.INTERNAL_TARGET_TYPE_MIFARE_4K, new String[] { NdefTag.TARGET_MIFARE_CLASSIC });
|
|
||||||
put(Tag.INTERNAL_TARGET_TYPE_FELICA, new String[] { NdefTag.TARGET_TYPE_3 });
|
|
||||||
put(Tag.INTERNAL_TARGET_TYPE_ISO14443_4, new String[] { NdefTag.TARGET_TYPE_4 });
|
|
||||||
put(Tag.INTERNAL_TARGET_TYPE_MIFARE_DESFIRE, new String[] { NdefTag.TARGET_TYPE_4 });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private String[] convertToNdefType(String internalTypeName) {
|
|
||||||
String[] result = NDEF_TYPES_CONVERTION_TABLE.get(internalTypeName);
|
|
||||||
if (result == null) {
|
|
||||||
return new String[] { NdefTag.TARGET_OTHER };
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the
|
* Return the NDEF targets on this Tag that support NDEF messages.
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public String[] getNdefTargets() {
|
public String[] getNdefTargets() {
|
||||||
return convertToNdefType(mTypeName);
|
return mNdefTargets;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -131,19 +191,50 @@ public class NdefTag extends Tag implements Parcelable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeToParcel(Parcel dest, int flags) {
|
public void writeToParcel(Parcel dest, int flags) {
|
||||||
super.writeToParcel(dest, flags);
|
// Tag fields
|
||||||
|
dest.writeInt(mIsNdef ? 1 : 0);
|
||||||
|
writeBytesWithNull(dest, mId);
|
||||||
|
dest.writeInt(mRawTargets.length);
|
||||||
|
dest.writeStringArray(mRawTargets);
|
||||||
|
writeBytesWithNull(dest, mPollBytes);
|
||||||
|
writeBytesWithNull(dest, mActivationBytes);
|
||||||
|
dest.writeInt(mServiceHandle);
|
||||||
|
|
||||||
|
// NdefTag fields
|
||||||
|
dest.writeInt(mNdefTargets.length);
|
||||||
|
dest.writeStringArray(mNdefTargets);
|
||||||
dest.writeInt(mMessages.length);
|
dest.writeInt(mMessages.length);
|
||||||
dest.writeTypedArray(mMessages, flags);
|
for (NdefMessage[] ms : mMessages) {
|
||||||
|
dest.writeTypedArray(ms, flags);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Parcelable.Creator<NdefTag> CREATOR =
|
public static final Parcelable.Creator<NdefTag> CREATOR =
|
||||||
new Parcelable.Creator<NdefTag>() {
|
new Parcelable.Creator<NdefTag>() {
|
||||||
public NdefTag createFromParcel(Parcel in) {
|
public NdefTag createFromParcel(Parcel in) {
|
||||||
Tag tag = Tag.CREATOR.createFromParcel(in);
|
boolean isNdef = (in.readInt() == 1);
|
||||||
int messagesLength = in.readInt();
|
if (!isNdef) {
|
||||||
NdefMessage[] messages = new NdefMessage[messagesLength];
|
throw new IllegalArgumentException("Creating NdefTag from Tag parcel");
|
||||||
in.readTypedArray(messages, NdefMessage.CREATOR);
|
}
|
||||||
return new NdefTag(tag.mTypeName, tag.mUid, tag.mNativeHandle, messages);
|
|
||||||
|
// Tag fields
|
||||||
|
byte[] id = readBytesWithNull(in);
|
||||||
|
String[] rawTargets = new String[in.readInt()];
|
||||||
|
in.readStringArray(rawTargets);
|
||||||
|
byte[] pollBytes = readBytesWithNull(in);
|
||||||
|
byte[] activationBytes = readBytesWithNull(in);
|
||||||
|
int serviceHandle = in.readInt();
|
||||||
|
|
||||||
|
// NdefTag fields
|
||||||
|
String[] ndefTargets = new String[in.readInt()];
|
||||||
|
in.readStringArray(ndefTargets);
|
||||||
|
NdefMessage[][] messages = new NdefMessage[in.readInt()][];
|
||||||
|
for (int i=0; i<messages.length; i++) {
|
||||||
|
messages[i] = new NdefMessage[in.readInt()];
|
||||||
|
in.readTypedArray(messages[i], NdefMessage.CREATOR);
|
||||||
|
}
|
||||||
|
return new NdefTag(id, rawTargets, pollBytes, activationBytes, serviceHandle,
|
||||||
|
ndefTargets, messages);
|
||||||
}
|
}
|
||||||
public NdefTag[] newArray(int size) {
|
public NdefTag[] newArray(int size) {
|
||||||
return new NdefTag[size];
|
return new NdefTag[size];
|
||||||
|
|||||||
@@ -81,9 +81,9 @@ public class NdefTagConnection extends RawTagConnection {
|
|||||||
//TODO(nxp): do not use getLastError(), it is racy
|
//TODO(nxp): do not use getLastError(), it is racy
|
||||||
try {
|
try {
|
||||||
NdefMessage[] msgArray = new NdefMessage[1];
|
NdefMessage[] msgArray = new NdefMessage[1];
|
||||||
NdefMessage msg = mTagService.read(mTag.mNativeHandle);
|
NdefMessage msg = mTagService.read(mTag.mServiceHandle);
|
||||||
if (msg == null) {
|
if (msg == null) {
|
||||||
int errorCode = mTagService.getLastError(mTag.mNativeHandle);
|
int errorCode = mTagService.getLastError(mTag.mServiceHandle);
|
||||||
switch (errorCode) {
|
switch (errorCode) {
|
||||||
case ErrorCodes.ERROR_IO:
|
case ErrorCodes.ERROR_IO:
|
||||||
throw new IOException();
|
throw new IOException();
|
||||||
@@ -121,7 +121,7 @@ public class NdefTagConnection extends RawTagConnection {
|
|||||||
*/
|
*/
|
||||||
public void writeNdefMessage(NdefMessage message) throws IOException, FormatException {
|
public void writeNdefMessage(NdefMessage message) throws IOException, FormatException {
|
||||||
try {
|
try {
|
||||||
int errorCode = mTagService.write(mTag.mNativeHandle, message);
|
int errorCode = mTagService.write(mTag.mServiceHandle, message);
|
||||||
switch (errorCode) {
|
switch (errorCode) {
|
||||||
case ErrorCodes.SUCCESS:
|
case ErrorCodes.SUCCESS:
|
||||||
break;
|
break;
|
||||||
@@ -148,7 +148,7 @@ public class NdefTagConnection extends RawTagConnection {
|
|||||||
*/
|
*/
|
||||||
public boolean makeReadOnly() throws IOException {
|
public boolean makeReadOnly() throws IOException {
|
||||||
try {
|
try {
|
||||||
int errorCode = mTagService.makeReadOnly(mTag.mNativeHandle);
|
int errorCode = mTagService.makeReadOnly(mTag.mServiceHandle);
|
||||||
switch (errorCode) {
|
switch (errorCode) {
|
||||||
case ErrorCodes.SUCCESS:
|
case ErrorCodes.SUCCESS:
|
||||||
return true;
|
return true;
|
||||||
@@ -175,7 +175,7 @@ public class NdefTagConnection extends RawTagConnection {
|
|||||||
*/
|
*/
|
||||||
public int getModeHint() throws IOException {
|
public int getModeHint() throws IOException {
|
||||||
try {
|
try {
|
||||||
int result = mTagService.getModeHint(mTag.mNativeHandle);
|
int result = mTagService.getModeHint(mTag.mServiceHandle);
|
||||||
if (ErrorCodes.isError(result)) {
|
if (ErrorCodes.isError(result)) {
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case ErrorCodes.ERROR_IO:
|
case ErrorCodes.ERROR_IO:
|
||||||
|
|||||||
@@ -327,6 +327,9 @@ public final class NfcAdapter {
|
|||||||
* <p>Requires {@link android.Manifest.permission#NFC} permission.
|
* <p>Requires {@link android.Manifest.permission#NFC} permission.
|
||||||
*/
|
*/
|
||||||
public RawTagConnection createRawTagConnection(Tag tag) {
|
public RawTagConnection createRawTagConnection(Tag tag) {
|
||||||
|
if (tag.mServiceHandle == 0) {
|
||||||
|
throw new IllegalArgumentException("mock tag cannot be used for connections");
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
return new RawTagConnection(mService, tag);
|
return new RawTagConnection(mService, tag);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
@@ -340,6 +343,9 @@ public final class NfcAdapter {
|
|||||||
* <p>Requires {@link android.Manifest.permission#NFC} permission.
|
* <p>Requires {@link android.Manifest.permission#NFC} permission.
|
||||||
*/
|
*/
|
||||||
public RawTagConnection createRawTagConnection(Tag tag, String target) {
|
public RawTagConnection createRawTagConnection(Tag tag, String target) {
|
||||||
|
if (tag.mServiceHandle == 0) {
|
||||||
|
throw new IllegalArgumentException("mock tag cannot be used for connections");
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
return new RawTagConnection(mService, tag, target);
|
return new RawTagConnection(mService, tag, target);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
@@ -353,6 +359,9 @@ public final class NfcAdapter {
|
|||||||
* <p>Requires {@link android.Manifest.permission#NFC} permission.
|
* <p>Requires {@link android.Manifest.permission#NFC} permission.
|
||||||
*/
|
*/
|
||||||
public NdefTagConnection createNdefTagConnection(NdefTag tag) {
|
public NdefTagConnection createNdefTagConnection(NdefTag tag) {
|
||||||
|
if (tag.mServiceHandle == 0) {
|
||||||
|
throw new IllegalArgumentException("mock tag cannot be used for connections");
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
return new NdefTagConnection(mService, tag);
|
return new NdefTagConnection(mService, tag);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
@@ -366,6 +375,9 @@ public final class NfcAdapter {
|
|||||||
* <p>Requires {@link android.Manifest.permission#NFC} permission.
|
* <p>Requires {@link android.Manifest.permission#NFC} permission.
|
||||||
*/
|
*/
|
||||||
public NdefTagConnection createNdefTagConnection(NdefTag tag, String target) {
|
public NdefTagConnection createNdefTagConnection(NdefTag tag, String target) {
|
||||||
|
if (tag.mServiceHandle == 0) {
|
||||||
|
throw new IllegalArgumentException("mock tag cannot be used for connections");
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
return new NdefTagConnection(mService, tag, target);
|
return new NdefTagConnection(mService, tag, target);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ public class RawTagConnection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return mTagService.isPresent(mTag.mNativeHandle);
|
return mTagService.isPresent(mTag.mServiceHandle);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.e(TAG, "NFC service died", e);
|
Log.e(TAG, "NFC service died", e);
|
||||||
return false;
|
return false;
|
||||||
@@ -135,7 +135,7 @@ public class RawTagConnection {
|
|||||||
public void close() {
|
public void close() {
|
||||||
mIsConnected = false;
|
mIsConnected = false;
|
||||||
try {
|
try {
|
||||||
mTagService.close(mTag.mNativeHandle);
|
mTagService.close(mTag.mServiceHandle);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.e(TAG, "NFC service died", e);
|
Log.e(TAG, "NFC service died", e);
|
||||||
}
|
}
|
||||||
@@ -154,7 +154,7 @@ public class RawTagConnection {
|
|||||||
*/
|
*/
|
||||||
public byte[] transceive(byte[] data) throws IOException {
|
public byte[] transceive(byte[] data) throws IOException {
|
||||||
try {
|
try {
|
||||||
byte[] response = mTagService.transceive(mTag.mNativeHandle, data);
|
byte[] response = mTagService.transceive(mTag.mServiceHandle, data);
|
||||||
if (response == null) {
|
if (response == null) {
|
||||||
throw new IOException("transcieve failed");
|
throw new IOException("transcieve failed");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,8 +16,6 @@
|
|||||||
|
|
||||||
package android.nfc;
|
package android.nfc;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
|
|
||||||
@@ -39,202 +37,168 @@ import android.os.Parcelable;
|
|||||||
* range. If it is removed and then returned to range, then the most recent
|
* 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 Tag} object (in {@link NfcAdapter#ACTION_TAG_DISCOVERED}) should be used to create a
|
||||||
* {@link RawTagConnection}.
|
* {@link RawTagConnection}.
|
||||||
* <p>This is an immutable data class.
|
* <p>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 class Tag implements Parcelable {
|
public class Tag implements Parcelable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @hide
|
* ISO 14443-3A technology.
|
||||||
|
* <p>
|
||||||
|
* Includes Topaz (which is -3A compatible)
|
||||||
*/
|
*/
|
||||||
public static final int NFC_TAG_ISO14443_A = 1; /* phNfc_eISO14443_A_PICC */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
public static final int NFC_TAG_ISO14443_4A = 2; /* phNfc_eISO14443_4A_PICC */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
public static final int NFC_TAG_ISO14443_3A = 3; /* phNfc_eISO14443_3A_PICC */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
public static final int NFC_TAG_MIFARE = 4; /* phNfc_eMifare_PICC */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
public static final int NFC_TAG_ISO14443_B = 5; /* phNfc_eISO14443_B_PICC */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
public static final int NFC_TAG_ISO14443_4B = 6; /* phNfc_eISO14443_4B_PICC */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
public static final int NFC_TAG_ISO14443_B_PRIME = 7; /* phNfc_eISO14443_BPrime_PICC */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
public static final int NFC_TAG_FELICA = 8; /* phNfc_eFelica_PICC */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
public static final int NFC_TAG_JEWEL = 9; /* phNfc_eJewel_PICC */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
public static final int NFC_TAG_ISO15693 = 10; /* phNfc_eISO15693_PICC */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
public static final int NFC_TAG_OTHER = 11; /* phNfc_ePICC_DevType */
|
|
||||||
|
|
||||||
|
|
||||||
public static final String TARGET_ISO_14443_3A = "iso14443_3a";
|
public static final String TARGET_ISO_14443_3A = "iso14443_3a";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ISO 14443-3B technology.
|
||||||
|
*/
|
||||||
public static final String TARGET_ISO_14443_3B = "iso14443_3b";
|
public static final String TARGET_ISO_14443_3B = "iso14443_3b";
|
||||||
|
|
||||||
public static final String TARGET_ISO_14443_3B_PRIME = "iso14443_3b";
|
/**
|
||||||
|
* ISO 14443-4 technology.
|
||||||
|
*/
|
||||||
public static final String TARGET_ISO_14443_4 = "iso14443_4";
|
public static final String TARGET_ISO_14443_4 = "iso14443_4";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ISO 15693 technology, commonly known as RFID.
|
||||||
|
*/
|
||||||
public static final String TARGET_ISO_15693 = "iso15693";
|
public static final String TARGET_ISO_15693 = "iso15693";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JIS X-6319-4 technology, commonly known as Felica.
|
||||||
|
*/
|
||||||
public static final String TARGET_JIS_X_6319_4 = "jis_x_6319_4";
|
public static final String TARGET_JIS_X_6319_4 = "jis_x_6319_4";
|
||||||
|
|
||||||
public static final String TARGET_TOPAZ = "topaz";
|
/**
|
||||||
|
* Any other technology.
|
||||||
|
*/
|
||||||
public static final String TARGET_OTHER = "other";
|
public static final String TARGET_OTHER = "other";
|
||||||
|
|
||||||
/*package*/ final String mTypeName;
|
|
||||||
/*package*/ final boolean mIsNdef;
|
/*package*/ final boolean mIsNdef;
|
||||||
/*package*/ final byte[] mUid;
|
/*package*/ final byte[] mId;
|
||||||
/*package*/ final int mNativeHandle;
|
/*package*/ final String[] mRawTargets;
|
||||||
|
/*package*/ final byte[] mPollBytes;
|
||||||
/*package*/ static final String INTERNAL_TARGET_TYPE_ISO14443_3A = "Iso14443-3A";
|
/*package*/ final byte[] mActivationBytes;
|
||||||
/*package*/ static final String INTERNAL_TARGET_TYPE_ISO14443_3B = "Iso14443-3B";
|
/*package*/ final int mServiceHandle; // for use by NFC service, 0 indicates a mock
|
||||||
/*package*/ static final String INTERNAL_TARGET_TYPE_ISO14443_4 = "Iso14443-4";
|
|
||||||
/*package*/ static final String INTERNAL_TARGET_TYPE_MIFARE_UL = "MifareUL";
|
|
||||||
/*package*/ static final String INTERNAL_TARGET_TYPE_MIFARE_1K = "Mifare1K";
|
|
||||||
/*package*/ static final String INTERNAL_TARGET_TYPE_MIFARE_4K = "Mifare4K";
|
|
||||||
/*package*/ static final String INTERNAL_TARGET_TYPE_MIFARE_DESFIRE = "MifareDESFIRE";
|
|
||||||
/*package*/ static final String INTERNAL_TARGET_TYPE_MIFARE_UNKNOWN = "Unknown Mifare";
|
|
||||||
/*package*/ static final String INTERNAL_TARGET_TYPE_FELICA = "Felica";
|
|
||||||
/*package*/ static final String INTERNAL_TARGET_TYPE_JEWEL = "Jewel";
|
|
||||||
/*package*/ static final String INTERNAL_TARGET_TYPE_UNKNOWN = "Unknown Type";
|
|
||||||
|
|
||||||
private static final HashMap<String, Integer> INT_TYPES_CONVERTION_TABLE = new HashMap<String, Integer>() {
|
|
||||||
{
|
|
||||||
put(Tag.INTERNAL_TARGET_TYPE_ISO14443_3A, Tag.NFC_TAG_ISO14443_A );
|
|
||||||
put(Tag.INTERNAL_TARGET_TYPE_ISO14443_3B, Tag.NFC_TAG_ISO14443_B );
|
|
||||||
put(Tag.INTERNAL_TARGET_TYPE_MIFARE_UL, Tag.NFC_TAG_MIFARE );
|
|
||||||
put(Tag.INTERNAL_TARGET_TYPE_MIFARE_1K, Tag.NFC_TAG_MIFARE );
|
|
||||||
put(Tag.INTERNAL_TARGET_TYPE_MIFARE_4K, Tag.NFC_TAG_MIFARE );
|
|
||||||
put(Tag.INTERNAL_TARGET_TYPE_MIFARE_DESFIRE, Tag.NFC_TAG_MIFARE );
|
|
||||||
put(Tag.INTERNAL_TARGET_TYPE_FELICA, Tag.NFC_TAG_FELICA );
|
|
||||||
put(Tag.INTERNAL_TARGET_TYPE_JEWEL, Tag.NFC_TAG_JEWEL );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private int convertToInt(String internalTypeName) {
|
|
||||||
Integer result = INT_TYPES_CONVERTION_TABLE.get(internalTypeName);
|
|
||||||
if (result == null) {
|
|
||||||
return Tag.NFC_TAG_OTHER;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final HashMap<String, String[]> RAW_TYPES_CONVERTION_TABLE = new HashMap<String, String[]>() {
|
|
||||||
{
|
|
||||||
/* TODO: handle multiprotocol */
|
|
||||||
put(Tag.INTERNAL_TARGET_TYPE_ISO14443_3A, new String[] { Tag.TARGET_ISO_14443_3A });
|
|
||||||
put(Tag.INTERNAL_TARGET_TYPE_ISO14443_3B, new String[] { Tag.TARGET_ISO_14443_3B });
|
|
||||||
put(Tag.INTERNAL_TARGET_TYPE_MIFARE_UL, new String[] { Tag.TARGET_ISO_14443_3A });
|
|
||||||
put(Tag.INTERNAL_TARGET_TYPE_MIFARE_1K, new String[] { Tag.TARGET_ISO_14443_3A });
|
|
||||||
put(Tag.INTERNAL_TARGET_TYPE_MIFARE_4K, new String[] { Tag.TARGET_ISO_14443_3A });
|
|
||||||
put(Tag.INTERNAL_TARGET_TYPE_MIFARE_DESFIRE, new String[] { Tag.TARGET_ISO_14443_3A });
|
|
||||||
put(Tag.INTERNAL_TARGET_TYPE_MIFARE_UNKNOWN, new String[] { Tag.TARGET_ISO_14443_3A });
|
|
||||||
put(Tag.INTERNAL_TARGET_TYPE_FELICA, new String[] { Tag.TARGET_JIS_X_6319_4 });
|
|
||||||
put(Tag.INTERNAL_TARGET_TYPE_JEWEL, new String[] { Tag.TARGET_TOPAZ });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private String[] convertToRaw(String internalTypeName) {
|
|
||||||
String[] result = RAW_TYPES_CONVERTION_TABLE.get(internalTypeName);
|
|
||||||
if (result == null) {
|
|
||||||
return new String[] { Tag.TARGET_OTHER };
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hidden constructor to be used by NFC service only.
|
* Hidden constructor to be used by NFC service and internal classes.
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public Tag(String typeName, boolean isNdef, byte[] uid, int nativeHandle) {
|
public Tag(byte[] id, boolean isNdef, String[] rawTargets, byte[] pollBytes,
|
||||||
mTypeName = typeName;
|
byte[] activationBytes, int serviceHandle) {
|
||||||
|
if (rawTargets == null) {
|
||||||
|
throw new IllegalArgumentException("rawTargets cannot be null");
|
||||||
|
}
|
||||||
mIsNdef = isNdef;
|
mIsNdef = isNdef;
|
||||||
mUid = uid.clone();
|
mId = id;
|
||||||
mNativeHandle = nativeHandle;
|
mRawTargets = rawTargets;
|
||||||
|
mPollBytes = pollBytes;
|
||||||
|
mActivationBytes = activationBytes;
|
||||||
|
mServiceHandle = serviceHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a mock Tag.
|
||||||
|
* <p>This is an application constructed tag, so NfcAdapter methods on this
|
||||||
|
* Tag such as {@link NfcAdapter#createRawTagConnection} will fail with
|
||||||
|
* {@link IllegalArgumentException} since it does not represent a physical Tag.
|
||||||
|
* <p>This constructor might be useful for mock testing.
|
||||||
|
* @param id The tag identifier, can be null
|
||||||
|
* @param rawTargets must not be null
|
||||||
|
* @param pollBytes can be null
|
||||||
|
* @param activationBytes can be null
|
||||||
|
* @return freshly constructed tag
|
||||||
|
*/
|
||||||
|
public static Tag createMockTag(byte[] id, String[] rawTargets, byte[] pollBytes,
|
||||||
|
byte[] activationBytes) {
|
||||||
|
// set serviceHandle to 0 to indicate mock tag
|
||||||
|
return new Tag(id, false, rawTargets, pollBytes, activationBytes, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For use by NfcService only.
|
* For use by NfcService only.
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public int getHandle() {
|
public int getServiceHandle() {
|
||||||
return mNativeHandle;
|
return mServiceHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the available targets that this NFC adapter can use to create
|
* Return the available targets that this NFC adapter can use to create
|
||||||
* a RawTagConnection.
|
* a RawTagConnection.
|
||||||
*
|
*
|
||||||
* @return
|
* @return raw targets, will not be null
|
||||||
*/
|
*/
|
||||||
public String[] getRawTargets() {
|
public String[] getRawTargets() {
|
||||||
return convertToRaw(mTypeName);
|
return mRawTargets;
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the Tag type.
|
|
||||||
* <p>
|
|
||||||
* The Tag type is one of the NFC_TAG constants. It is read at discovery
|
|
||||||
* time and this method does not cause any further RF activity and does not
|
|
||||||
* block.
|
|
||||||
*
|
|
||||||
* @return a NFC_TAG constant
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
public int getType() {
|
|
||||||
return convertToInt(mTypeName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the Tag Identifier (if it has one).
|
* Get the Tag Identifier (if it has one).
|
||||||
* <p>
|
* <p>Tag ID is usually a serial number for the tag.
|
||||||
* Tag ID is usually a serial number for the tag.
|
|
||||||
* <p>
|
|
||||||
* The Tag ID is read at discovery time and this method does not cause any
|
|
||||||
* further RF activity and does not block.
|
|
||||||
*
|
*
|
||||||
* @return ID, or null if it does not exist
|
* @return ID, or null if it does not exist
|
||||||
*/
|
*/
|
||||||
public byte[] getId() {
|
public byte[] getId() {
|
||||||
if (mUid.length > 0) {
|
return mId;
|
||||||
return mUid.clone();
|
}
|
||||||
} else {
|
|
||||||
return null;
|
/**
|
||||||
|
* Get the low-level bytes returned by this Tag at poll-time.
|
||||||
|
* <p>These can be used to help with advanced identification of a Tag.
|
||||||
|
* <p>The meaning of these bytes depends on the Tag technology.
|
||||||
|
* @return poll bytes, or null if they do not exist for this Tag technology
|
||||||
|
*/
|
||||||
|
public byte[] getPollBytes() {
|
||||||
|
return mPollBytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the low-level bytes returned by this Tag at activation-time.
|
||||||
|
* <p>These can be used to help with advanced identification of a Tag.
|
||||||
|
* <p>The meaning of these bytes depends on the Tag technology.
|
||||||
|
* @return activation bytes, or null if they do not exist for this Tag technology
|
||||||
|
*/
|
||||||
|
public byte[] getActivationBytes() {
|
||||||
|
return mActivationBytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder sb = new StringBuilder("TAG ")
|
||||||
|
.append("uid = ")
|
||||||
|
.append(mId)
|
||||||
|
.append(" poll ")
|
||||||
|
.append(mPollBytes)
|
||||||
|
.append(" activation ")
|
||||||
|
.append(mActivationBytes)
|
||||||
|
.append(" Raw [");
|
||||||
|
for (String s : mRawTargets) {
|
||||||
|
sb.append(s)
|
||||||
|
.append(", ");
|
||||||
}
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*package*/ static byte[] readBytesWithNull(Parcel in) {
|
||||||
|
int len = in.readInt();
|
||||||
|
byte[] result = null;
|
||||||
|
if (len > 0) {
|
||||||
|
result = new byte[len];
|
||||||
|
in.readByteArray(result);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*package*/ static void writeBytesWithNull(Parcel out, byte[] b) {
|
||||||
|
if (b == null) {
|
||||||
|
out.writeInt(-1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
out.writeInt(b.length);
|
||||||
|
out.writeByteArray(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -242,29 +206,34 @@ public class Tag implements Parcelable {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeToParcel(Parcel dest, int flags) {
|
public void writeToParcel(Parcel dest, int flags) {
|
||||||
boolean[] booleans = new boolean[] {mIsNdef};
|
dest.writeInt(mIsNdef ? 1 : 0);
|
||||||
dest.writeString(mTypeName);
|
writeBytesWithNull(dest, mId);
|
||||||
dest.writeBooleanArray(booleans);
|
dest.writeInt(mRawTargets.length);
|
||||||
dest.writeInt(mUid.length);
|
dest.writeStringArray(mRawTargets);
|
||||||
dest.writeByteArray(mUid);
|
writeBytesWithNull(dest, mPollBytes);
|
||||||
dest.writeInt(mNativeHandle);
|
writeBytesWithNull(dest, mActivationBytes);
|
||||||
|
dest.writeInt(mServiceHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Parcelable.Creator<Tag> CREATOR =
|
public static final Parcelable.Creator<Tag> CREATOR =
|
||||||
new Parcelable.Creator<Tag>() {
|
new Parcelable.Creator<Tag>() {
|
||||||
public Tag createFromParcel(Parcel in) {
|
public Tag createFromParcel(Parcel in) {
|
||||||
boolean[] booleans = new boolean[1];
|
boolean isNdef = (in.readInt() == 1);
|
||||||
String type = in.readString();
|
if (isNdef) {
|
||||||
in.readBooleanArray(booleans);
|
throw new IllegalArgumentException("Creating Tag from NdefTag parcel");
|
||||||
boolean isNdef = booleans[0];
|
}
|
||||||
int uidLength = in.readInt();
|
// Tag fields
|
||||||
byte[] uid = new byte[uidLength];
|
byte[] id = Tag.readBytesWithNull(in);
|
||||||
in.readByteArray(uid);
|
String[] rawTargets = new String[in.readInt()];
|
||||||
int nativeHandle = in.readInt();
|
in.readStringArray(rawTargets);
|
||||||
|
byte[] pollBytes = Tag.readBytesWithNull(in);
|
||||||
|
byte[] activationBytes = Tag.readBytesWithNull(in);
|
||||||
|
int serviceHandle = in.readInt();
|
||||||
|
|
||||||
return new Tag(type, isNdef, uid, nativeHandle);
|
return new Tag(id, isNdef, rawTargets, pollBytes, activationBytes, serviceHandle);
|
||||||
}
|
}
|
||||||
public Tag[] newArray(int size) {
|
public Tag[] newArray(int size) {
|
||||||
return new Tag[size];
|
return new Tag[size];
|
||||||
|
|||||||
Reference in New Issue
Block a user