Tag.java revision a926540d5455a973dd8ca19c00c108620d9c68c2
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 java.util.HashMap; 20 21import android.os.Parcel; 22import android.os.Parcelable; 23 24/** 25 * Represents a (generic) discovered tag. 26 * <p> 27 * A tag is a passive NFC element, such as NFC Forum Tag's, Mifare class Tags, 28 * Sony Felica Tags. 29 * <p> 30 * Tag's have a type and usually have a UID. 31 * <p> 32 * {@link Tag} objects are passed to applications via the {@link NfcAdapter#EXTRA_TAG} extra 33 * in {@link NfcAdapter#ACTION_TAG_DISCOVERED} intents. A {@link Tag} object is immutable 34 * and represents the state of the tag at the time of discovery. It can be 35 * directly queried for its UID and Type, or used to create a {@link RawTagConnection} 36 * (with {@link NfcAdapter#createRawTagConnection createRawTagConnection()}). 37 * <p> 38 * A {@link Tag} can be used to create a {@link RawTagConnection} only while the tag is in 39 * range. If it is removed and then returned to range, then the most recent 40 * {@link Tag} object (in {@link NfcAdapter#ACTION_TAG_DISCOVERED}) should be used to create a 41 * {@link RawTagConnection}. 42 * <p>This is an immutable data class. 43 */ 44public class Tag implements Parcelable { 45 46 /** 47 * @hide 48 */ 49 public static final int NFC_TAG_ISO14443_A = 1; /* phNfc_eISO14443_A_PICC */ 50 51 /** 52 * @hide 53 */ 54 public static final int NFC_TAG_ISO14443_4A = 2; /* phNfc_eISO14443_4A_PICC */ 55 56 /** 57 * @hide 58 */ 59 public static final int NFC_TAG_ISO14443_3A = 3; /* phNfc_eISO14443_3A_PICC */ 60 61 /** 62 * @hide 63 */ 64 public static final int NFC_TAG_MIFARE = 4; /* phNfc_eMifare_PICC */ 65 66 /** 67 * @hide 68 */ 69 public static final int NFC_TAG_ISO14443_B = 5; /* phNfc_eISO14443_B_PICC */ 70 71 /** 72 * @hide 73 */ 74 public static final int NFC_TAG_ISO14443_4B = 6; /* phNfc_eISO14443_4B_PICC */ 75 76 /** 77 * @hide 78 */ 79 public static final int NFC_TAG_ISO14443_B_PRIME = 7; /* phNfc_eISO14443_BPrime_PICC */ 80 81 /** 82 * @hide 83 */ 84 public static final int NFC_TAG_FELICA = 8; /* phNfc_eFelica_PICC */ 85 86 /** 87 * @hide 88 */ 89 public static final int NFC_TAG_JEWEL = 9; /* phNfc_eJewel_PICC */ 90 91 /** 92 * @hide 93 */ 94 public static final int NFC_TAG_ISO15693 = 10; /* phNfc_eISO15693_PICC */ 95 96 /** 97 * @hide 98 */ 99 public static final int NFC_TAG_OTHER = 11; /* phNfc_ePICC_DevType */ 100 101 102 public static final String TARGET_ISO_14443_3A = "iso14443_3a"; 103 104 public static final String TARGET_ISO_14443_3B = "iso14443_3b"; 105 106 public static final String TARGET_ISO_14443_3B_PRIME = "iso14443_3b"; 107 108 public static final String TARGET_ISO_14443_4 = "iso14443_4"; 109 110 public static final String TARGET_ISO_15693 = "iso15693"; 111 112 public static final String TARGET_JIS_X_6319_4 = "jis_x_6319_4"; 113 114 public static final String TARGET_TOPAZ = "topaz"; 115 116 public static final String TARGET_OTHER = "other"; 117 118 /*package*/ final String mTypeName; 119 /*package*/ final boolean mIsNdef; 120 /*package*/ final byte[] mUid; 121 /*package*/ final int mNativeHandle; 122 123 /*package*/ static final String INTERNAL_TARGET_TYPE_ISO14443_3A = "Iso14443-3A"; 124 /*package*/ static final String INTERNAL_TARGET_TYPE_ISO14443_3B = "Iso14443-3B"; 125 /*package*/ static final String INTERNAL_TARGET_TYPE_ISO14443_4 = "Iso14443-4"; 126 /*package*/ static final String INTERNAL_TARGET_TYPE_MIFARE_UL = "MifareUL"; 127 /*package*/ static final String INTERNAL_TARGET_TYPE_MIFARE_1K = "Mifare1K"; 128 /*package*/ static final String INTERNAL_TARGET_TYPE_MIFARE_4K = "Mifare4K"; 129 /*package*/ static final String INTERNAL_TARGET_TYPE_MIFARE_DESFIRE = "MifareDESFIRE"; 130 /*package*/ static final String INTERNAL_TARGET_TYPE_MIFARE_UNKNOWN = "Unknown Mifare"; 131 /*package*/ static final String INTERNAL_TARGET_TYPE_FELICA = "Felica"; 132 /*package*/ static final String INTERNAL_TARGET_TYPE_JEWEL = "Jewel"; 133 /*package*/ static final String INTERNAL_TARGET_TYPE_UNKNOWN = "Unknown Type"; 134 135 private static final HashMap<String, Integer> INT_TYPES_CONVERTION_TABLE = new HashMap<String, Integer>() { 136 { 137 put(Tag.INTERNAL_TARGET_TYPE_ISO14443_3A, Tag.NFC_TAG_ISO14443_A ); 138 put(Tag.INTERNAL_TARGET_TYPE_ISO14443_3B, Tag.NFC_TAG_ISO14443_B ); 139 put(Tag.INTERNAL_TARGET_TYPE_MIFARE_UL, Tag.NFC_TAG_MIFARE ); 140 put(Tag.INTERNAL_TARGET_TYPE_MIFARE_1K, Tag.NFC_TAG_MIFARE ); 141 put(Tag.INTERNAL_TARGET_TYPE_MIFARE_4K, Tag.NFC_TAG_MIFARE ); 142 put(Tag.INTERNAL_TARGET_TYPE_MIFARE_DESFIRE, Tag.NFC_TAG_MIFARE ); 143 put(Tag.INTERNAL_TARGET_TYPE_FELICA, Tag.NFC_TAG_FELICA ); 144 put(Tag.INTERNAL_TARGET_TYPE_JEWEL, Tag.NFC_TAG_JEWEL ); 145 } 146 }; 147 148 private int convertToInt(String internalTypeName) { 149 Integer result = INT_TYPES_CONVERTION_TABLE.get(internalTypeName); 150 if (result == null) { 151 return Tag.NFC_TAG_OTHER; 152 } 153 return result; 154 } 155 156 private static final HashMap<String, String[]> RAW_TYPES_CONVERTION_TABLE = new HashMap<String, String[]>() { 157 { 158 /* TODO: handle multiprotocol */ 159 put(Tag.INTERNAL_TARGET_TYPE_ISO14443_3A, new String[] { Tag.TARGET_ISO_14443_3A }); 160 put(Tag.INTERNAL_TARGET_TYPE_ISO14443_3B, new String[] { Tag.TARGET_ISO_14443_3B }); 161 put(Tag.INTERNAL_TARGET_TYPE_MIFARE_UL, new String[] { Tag.TARGET_ISO_14443_3A }); 162 put(Tag.INTERNAL_TARGET_TYPE_MIFARE_1K, new String[] { Tag.TARGET_ISO_14443_3A }); 163 put(Tag.INTERNAL_TARGET_TYPE_MIFARE_4K, new String[] { Tag.TARGET_ISO_14443_3A }); 164 put(Tag.INTERNAL_TARGET_TYPE_MIFARE_DESFIRE, new String[] { Tag.TARGET_ISO_14443_3A }); 165 put(Tag.INTERNAL_TARGET_TYPE_MIFARE_UNKNOWN, new String[] { Tag.TARGET_ISO_14443_3A }); 166 put(Tag.INTERNAL_TARGET_TYPE_FELICA, new String[] { Tag.TARGET_JIS_X_6319_4 }); 167 put(Tag.INTERNAL_TARGET_TYPE_JEWEL, new String[] { Tag.TARGET_TOPAZ }); 168 } 169 }; 170 171 private String[] convertToRaw(String internalTypeName) { 172 String[] result = RAW_TYPES_CONVERTION_TABLE.get(internalTypeName); 173 if (result == null) { 174 return new String[] { Tag.TARGET_OTHER }; 175 } 176 return result; 177 } 178 179 /** 180 * Hidden constructor to be used by NFC service only. 181 * @hide 182 */ 183 public Tag(String typeName, boolean isNdef, byte[] uid, int nativeHandle) { 184 mTypeName = typeName; 185 mIsNdef = isNdef; 186 mUid = uid.clone(); 187 mNativeHandle = nativeHandle; 188 } 189 190 /** 191 * For use by NfcService only. 192 * @hide 193 */ 194 public int getHandle() { 195 return mNativeHandle; 196 } 197 198 /** 199 * Return the available targets that this NFC adapter can use to create 200 * a RawTagConnection. 201 * 202 * @return 203 */ 204 public String[] getRawTargets() { 205 return convertToRaw(mTypeName); 206 } 207 208 /** 209 * Get the Tag type. 210 * <p> 211 * The Tag type is one of the NFC_TAG constants. It is read at discovery 212 * time and this method does not cause any further RF activity and does not 213 * block. 214 * 215 * @return a NFC_TAG constant 216 * @hide 217 */ 218 public int getType() { 219 return convertToInt(mTypeName); 220 } 221 222 /** 223 * Get the Tag Identifier (if it has one). 224 * <p> 225 * Tag ID is usually a serial number for the tag. 226 * <p> 227 * The Tag ID is read at discovery time and this method does not cause any 228 * further RF activity and does not block. 229 * 230 * @return ID, or null if it does not exist 231 */ 232 public byte[] getId() { 233 if (mUid.length > 0) { 234 return mUid.clone(); 235 } else { 236 return null; 237 } 238 } 239 240 @Override 241 public int describeContents() { 242 return 0; 243 } 244 245 @Override 246 public void writeToParcel(Parcel dest, int flags) { 247 boolean[] booleans = new boolean[] {mIsNdef}; 248 dest.writeString(mTypeName); 249 dest.writeBooleanArray(booleans); 250 dest.writeInt(mUid.length); 251 dest.writeByteArray(mUid); 252 dest.writeInt(mNativeHandle); 253 } 254 255 public static final Parcelable.Creator<Tag> CREATOR = 256 new Parcelable.Creator<Tag>() { 257 public Tag createFromParcel(Parcel in) { 258 boolean[] booleans = new boolean[1]; 259 String type = in.readString(); 260 in.readBooleanArray(booleans); 261 boolean isNdef = booleans[0]; 262 int uidLength = in.readInt(); 263 byte[] uid = new byte[uidLength]; 264 in.readByteArray(uid); 265 int nativeHandle = in.readInt(); 266 267 return new Tag(type, isNdef, uid, nativeHandle); 268 } 269 public Tag[] newArray(int size) { 270 return new Tag[size]; 271 } 272 }; 273}