Tag.java revision 07f3bee2db8b6e93ebbf7222676bd9f468e85569
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.nfc; 18 19import android.os.Parcel; 20import android.os.Parcelable; 21 22/** 23 * Represents a (generic) discovered tag. 24 * <p> 25 * A tag is a passive NFC element, such as NFC Forum Tag's, Mifare class Tags, 26 * Sony Felica Tags. 27 * <p> 28 * Tag's have a type and usually have a UID. 29 * <p> 30 * {@link Tag} objects are passed to applications via the {@link NfcAdapter#EXTRA_TAG} extra 31 * in {@link NfcAdapter#ACTION_TAG_DISCOVERED} intents. A {@link Tag} object is immutable 32 * and represents the state of the tag at the time of discovery. It can be 33 * directly queried for its UID and Type, or used to create a {@link RawTagConnection} 34 * (with {@link NfcAdapter#createRawTagConnection createRawTagConnection()}). 35 * <p> 36 * A {@link Tag} can be used to create a {@link RawTagConnection} only while the tag is in 37 * range. If it is removed and then returned to range, then the most recent 38 * {@link Tag} object (in {@link NfcAdapter#ACTION_TAG_DISCOVERED}) should be used to create a 39 * {@link RawTagConnection}. 40 * <p>This is an immutable data class. All properties are set at Tag discovery 41 * time and calls on this class will retrieve those read-only properties, and 42 * not cause any further RF activity or block. Note however that arrays passed to and 43 * returned by this class are *not* cloned, so be careful not to modify them. 44 */ 45public class Tag implements Parcelable { 46 /** 47 * ISO 14443-3A technology. 48 * <p> 49 * Includes Topaz (which is -3A compatible) 50 */ 51 public static final String TARGET_ISO_14443_3A = "iso14443_3a"; 52 53 /** 54 * ISO 14443-3B technology. 55 */ 56 public static final String TARGET_ISO_14443_3B = "iso14443_3b"; 57 58 /** 59 * ISO 14443-4 technology. 60 */ 61 public static final String TARGET_ISO_14443_4 = "iso14443_4"; 62 63 /** 64 * ISO 15693 technology, commonly known as RFID. 65 */ 66 public static final String TARGET_ISO_15693 = "iso15693"; 67 68 /** 69 * JIS X-6319-4 technology, commonly known as Felica. 70 */ 71 public static final String TARGET_JIS_X_6319_4 = "jis_x_6319_4"; 72 73 /** 74 * Any other technology. 75 */ 76 public static final String TARGET_OTHER = "other"; 77 78 /*package*/ final boolean mIsNdef; 79 /*package*/ final byte[] mId; 80 /*package*/ final String[] mRawTargets; 81 /*package*/ final byte[] mPollBytes; 82 /*package*/ final byte[] mActivationBytes; 83 /*package*/ final int mServiceHandle; // for use by NFC service, 0 indicates a mock 84 85 /** 86 * Hidden constructor to be used by NFC service and internal classes. 87 * @hide 88 */ 89 public Tag(byte[] id, boolean isNdef, String[] rawTargets, byte[] pollBytes, 90 byte[] activationBytes, int serviceHandle) { 91 if (rawTargets == null) { 92 throw new IllegalArgumentException("rawTargets cannot be null"); 93 } 94 mIsNdef = isNdef; 95 mId = id; 96 mRawTargets = rawTargets; 97 mPollBytes = pollBytes; 98 mActivationBytes = activationBytes; 99 mServiceHandle = serviceHandle; 100 } 101 102 /** 103 * Construct a mock Tag. 104 * <p>This is an application constructed tag, so NfcAdapter methods on this 105 * Tag such as {@link NfcAdapter#createRawTagConnection} will fail with 106 * {@link IllegalArgumentException} since it does not represent a physical Tag. 107 * <p>This constructor might be useful for mock testing. 108 * @param id The tag identifier, can be null 109 * @param rawTargets must not be null 110 * @param pollBytes can be null 111 * @param activationBytes can be null 112 * @return freshly constructed tag 113 */ 114 public static Tag createMockTag(byte[] id, String[] rawTargets, byte[] pollBytes, 115 byte[] activationBytes) { 116 // set serviceHandle to 0 to indicate mock tag 117 return new Tag(id, false, rawTargets, pollBytes, activationBytes, 0); 118 } 119 120 /** 121 * For use by NfcService only. 122 * @hide 123 */ 124 public int getServiceHandle() { 125 return mServiceHandle; 126 } 127 128 /** 129 * Return the available targets that this NFC adapter can use to create 130 * a RawTagConnection. 131 * 132 * @return raw targets, will not be null 133 */ 134 public String[] getRawTargets() { 135 return mRawTargets; 136 } 137 138 /** 139 * Get the Tag Identifier (if it has one). 140 * <p>Tag ID is usually a serial number for the tag. 141 * 142 * @return ID, or null if it does not exist 143 */ 144 public byte[] getId() { 145 return mId; 146 } 147 148 /** 149 * Get the low-level bytes returned by this Tag at poll-time. 150 * <p>These can be used to help with advanced identification of a Tag. 151 * <p>The meaning of these bytes depends on the Tag technology. 152 * @return poll bytes, or null if they do not exist for this Tag technology 153 */ 154 public byte[] getPollBytes() { 155 return mPollBytes; 156 } 157 158 /** 159 * Get the low-level bytes returned by this Tag at activation-time. 160 * <p>These can be used to help with advanced identification of a Tag. 161 * <p>The meaning of these bytes depends on the Tag technology. 162 * @return activation bytes, or null if they do not exist for this Tag technology 163 */ 164 public byte[] getActivationBytes() { 165 return mActivationBytes; 166 } 167 168 @Override 169 public String toString() { 170 StringBuilder sb = new StringBuilder("TAG ") 171 .append("uid = ") 172 .append(mId) 173 .append(" poll ") 174 .append(mPollBytes) 175 .append(" activation ") 176 .append(mActivationBytes) 177 .append(" Raw ["); 178 for (String s : mRawTargets) { 179 sb.append(s) 180 .append(", "); 181 } 182 return sb.toString(); 183 } 184 185 /*package*/ static byte[] readBytesWithNull(Parcel in) { 186 int len = in.readInt(); 187 byte[] result = null; 188 if (len > 0) { 189 result = new byte[len]; 190 in.readByteArray(result); 191 } 192 return result; 193 } 194 195 /*package*/ static void writeBytesWithNull(Parcel out, byte[] b) { 196 if (b == null) { 197 out.writeInt(-1); 198 return; 199 } 200 out.writeInt(b.length); 201 out.writeByteArray(b); 202 } 203 204 @Override 205 public int describeContents() { 206 return 0; 207 } 208 209 210 @Override 211 public void writeToParcel(Parcel dest, int flags) { 212 dest.writeInt(mIsNdef ? 1 : 0); 213 writeBytesWithNull(dest, mId); 214 dest.writeInt(mRawTargets.length); 215 dest.writeStringArray(mRawTargets); 216 writeBytesWithNull(dest, mPollBytes); 217 writeBytesWithNull(dest, mActivationBytes); 218 dest.writeInt(mServiceHandle); 219 } 220 221 public static final Parcelable.Creator<Tag> CREATOR = 222 new Parcelable.Creator<Tag>() { 223 public Tag createFromParcel(Parcel in) { 224 boolean isNdef = (in.readInt() == 1); 225 if (isNdef) { 226 throw new IllegalArgumentException("Creating Tag from NdefTag parcel"); 227 } 228 // Tag fields 229 byte[] id = Tag.readBytesWithNull(in); 230 String[] rawTargets = new String[in.readInt()]; 231 in.readStringArray(rawTargets); 232 byte[] pollBytes = Tag.readBytesWithNull(in); 233 byte[] activationBytes = Tag.readBytesWithNull(in); 234 int serviceHandle = in.readInt(); 235 236 return new Tag(id, isNdef, rawTargets, pollBytes, activationBytes, serviceHandle); 237 } 238 public Tag[] newArray(int size) { 239 return new Tag[size]; 240 } 241 }; 242}