1 package skyseraph.android.util.nfc; 2 3 import com.google.common.collect.BiMap; 4 import com.google.common.collect.ImmutableBiMap; 5 6 import skyseraph.android.util.LogUtil; 7 import skyseraph.android.util.MyConstant; 8 9 import android.annotation.SuppressLint; 10 import android.net.Uri; 11 import android.nfc.NdefMessage; 12 import android.nfc.NdefRecord; 13 14 import java.nio.charset.Charset; 15 import java.util.Locale; 16 17 /** 18 * @Title :BobNdefMessage.java 19 * @Package :skyseraph.android.util.nfc 20 * @ClassName : BobNdefMessage 21 * @Description :Custom Class For NdefMessage 22 * @author : skyseraph00@163.com 23 * @date : 2013-5-13 上午11:14:51 24 * @version : V1.0 《Android NFC 开发实战详解》 25 */ 26 public class BobNdefMessage { 27 private static final String TAG_ASSIST = "[BobNdefMessage]-"; 28 29 /** 30 * @About:create a TNF_WELL_KNOW NDEF record as RTD_URI 31 * @param uriFiledStr , The rest of the URI, or the entire URI (if 32 * identifier code is 0x00). 33 * @param identifierCode = prefixes(URI identifier code), 0x01=http://www. 34 * ,0x02=https://www. , 0x03=http:// 35 * @param flagAddAAR, true means add AAR 36 * @return NdefMessage 37 * @Ref: NFCForum-TS-RTD_URI_1.0 38 * @By SkySeraph-2013 39 */ 40 public static NdefMessage getNdefMsg_from_RTD_URI(String uriFiledStr, byte identifierCode, 41 boolean flagAddAAR) { 42 LogUtil.i(MyConstant.TAG, TAG_ASSIST + "into getNdefMsg_from_RTD_URI"); 43 byte[] uriField = uriFiledStr.getBytes(Charset.forName("US-ASCII")); 44 byte[] payLoad = new byte[uriField.length + 1]; // add 1 for the URI 45 // Prefix 46 payLoad[0] = identifierCode; // 0x01 = prefixes http://www. to the URI 47 // appends URI to payload 48 System.arraycopy(uriField, 0, payLoad, 1, uriField.length); 49 50 // Method1: 51 NdefRecord rtdUriRecord1 = new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_URI, 52 new byte[0], payLoad); 53 54 // Method2:only in API 14 55 String prefix = URI_PREFIX_MAP.get(identifierCode); 56 NdefRecord rtdUriRecord2 = NdefRecord.createUri(prefix + uriFiledStr); 57 58 // Method3:only in API 14 59 NdefRecord rtdUriRecord3 = NdefRecord.createUri(Uri.parse(prefix + uriFiledStr)); 60 61 if (flagAddAAR) { 62 // note: returns AAR for different app (nfcreadtag) 63 return new NdefMessage(new NdefRecord[] { 64 rtdUriRecord1, NdefRecord.createApplicationRecord("skyseraph.nfc_demo") 65 }); // packageName 66 } else { 67 return new NdefMessage(new NdefRecord[] { 68 rtdUriRecord1 69 }); 70 } 71 } 72 73 /** 74 * @About:create a TNF_WELL_KNOW NDEF record as RTD_TEXT 75 * @param text , the really text data 76 * @param encodeInUtf8 , false means TEXT encoded by UTF-8 77 * @param flagAddAAR , true means add AAR 78 * @return NdefMessage 79 * @Ref: NFCForum-TS-RTD_Text_1.0 80 * @By SkySeraph-2013 81 */ 82 public static NdefMessage getNdefMsg_from_RTD_TEXT(String text, boolean encodeInUtf8, 83 boolean flagAddAAR) { 84 LogUtil.i(MyConstant.TAG, TAG_ASSIST + "into getNdefMsg_from_RTD_TEXT"); 85 86 Locale locale = new Locale("en", "US"); // a new Locale is created with 87 // US English. 88 byte[] langBytes = locale.getLanguage().getBytes(Charset.forName("US-ASCII")); 89 // boolean encodeInUtf8 = false; 90 Charset utfEncoding = encodeInUtf8 ? Charset.forName("UTF-8") : Charset.forName("UTF-16"); 91 int utfBit = encodeInUtf8 ? 0 : (1 << 7); 92 char status = (char)(utfBit + langBytes.length); 93 // String text = "This is an RTD_TEXT exp"; 94 byte[] textBytes = text.getBytes(utfEncoding); 95 byte[] data = new byte[1 + langBytes.length + textBytes.length]; 96 data[0] = (byte)status; 97 System.arraycopy(langBytes, 0, data, 1, langBytes.length); 98 System.arraycopy(textBytes, 0, data, 1 + langBytes.length, textBytes.length); 99 NdefRecord textRecord = new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, 100 new byte[0], data); 101 102 if (flagAddAAR) { 103 // note: returns AAR for different app (nfcreadtag) 104 return new NdefMessage(new NdefRecord[] { 105 textRecord, NdefRecord.createApplicationRecord("skyseraph.nfc_demo") 106 }); 107 } else { 108 return new NdefMessage(new NdefRecord[] { 109 textRecord 110 }); 111 } 112 } 113 114 /** 115 * @About: create a TNF_ABSOLUTE_URI NDEF record 116 * @param absoluteUri ,the absolute Uri 117 * @param flagAddAAR , true means add AAR 118 * @return NdefMessage 119 * @Note: TNF_ABSOLUTE_URI indicates the absolute form of a URI that follows 120 * the absolute-URI rule defined by RFC 3986 121 * @Note: Recommend that you use the RTD_URI type instead of 122 * TNF_ABSOLUTE_URI, because it is more efficient 123 * @By SkySeraph-2013 124 */ 125 public static NdefMessage getNdefMsg_from_ABSOLUTE_URI(String absoluteUri, boolean flagAddAAR) { 126 LogUtil.i(MyConstant.TAG, TAG_ASSIST + "into getNdefMsg_from_ABSOLUTE_URI"); 127 // String absoluteUri = "http://developer.android.com/index.html"; 128 byte[] absoluteUriBytes = absoluteUri.getBytes(Charset.forName("US-ASCII")); 129 NdefRecord uriRecord = new NdefRecord(NdefRecord.TNF_ABSOLUTE_URI, absoluteUriBytes, 130 new byte[0], new byte[0]); 131 if (flagAddAAR) { 132 // note: returns AAR for different app (nfcreadtag) 133 return new NdefMessage(new NdefRecord[] { 134 uriRecord, NdefRecord.createApplicationRecord("skyseraph.nfc_demo") 135 }); 136 } else { 137 return new NdefMessage(new NdefRecord[] { 138 uriRecord 139 }); 140 } 141 } 142 143 /** 144 * @About:create a TNF_MIME_MEDIA NDEF record 145 * @param payLoad,the MIME data 146 * @param mimeType,the MIME Type 147 * @param flagAddAAR, true means add AAR 148 * @return NdefMessage 149 * @By SkySeraph-2013 150 */ 151 @SuppressLint("NewApi") 152 public static NdefMessage getNdefMsg_from_MIME_MEDIA(String payLoad, String mimeType, 153 boolean flagAddAAR) { 154 LogUtil.i(MyConstant.TAG, TAG_ASSIST + "into getNdefMsg_from_MIME_MEDIA"); 155 byte[] payLoadBytes = payLoad.getBytes(Charset.forName("US-ASCII")); 156 // String mimeType = "application/skyseraph.nfc_demo"; 157 158 // method1:Creating the NdefRecord manually 159 NdefRecord mimeRecord1 = new NdefRecord(NdefRecord.TNF_MIME_MEDIA, 160 mimeType.getBytes(Charset.forName("US-ASCII")), new byte[0], payLoadBytes); 161 // the identfier of the record is given as 0, since it will be the first 162 // record in the NdefMessage 163 164 // method2:Using the createMime() method, in API-16 165 NdefRecord mimeRecord2 = NdefRecord.createMime(mimeType, payLoadBytes); 166 167 if (flagAddAAR) { 168 // note: returns AAR for different app (nfcreadtag) 169 return new NdefMessage(new NdefRecord[] { 170 mimeRecord1, NdefRecord.createApplicationRecord("skyseraph.nfc_demo") 171 }); 172 } else { 173 return new NdefMessage(new NdefRecord[] { 174 mimeRecord1 175 }); 176 } 177 } 178 179 /** 180 * @About:create a TNF_EXTERNAL_TYPE NDEF record 181 * @param payLoad,the EXTERNAL data 182 * @param flagAddAAR, true means add AAR 183 * @return NdefMessage 184 * @By SkySeraph-2013 185 */ 186 @SuppressLint("NewApi") 187 public static NdefMessage getNdefMsg_from_EXTERNAL_TYPE(String payLoad, boolean flagAddAAR) { 188 LogUtil.i(MyConstant.TAG, TAG_ASSIST + "into getNdefMsg_from_EXTERNAL_TYPE"); 189 byte[] payLoadBytes = payLoad.getBytes(); 190 String domain = "skyseraph.nfc_demo"; // usually your app's package name 191 String type = "externalType"; 192 String externalType = domain + ":" + type; 193 194 // method1:Creating the NdefRecord manually 195 NdefRecord exteralRecord1 = new NdefRecord(NdefRecord.TNF_EXTERNAL_TYPE, 196 externalType.getBytes(), new byte[0], payLoadBytes); 197 198 // method2:Using the createExternal() method, in API-16 199 NdefRecord exteralRecord2 = NdefRecord.createExternal(domain, type, payLoadBytes); 200 201 if (flagAddAAR) { 202 // note: returns AAR for different app (nfcreadtag) 203 return new NdefMessage(new NdefRecord[] { 204 exteralRecord1, NdefRecord.createApplicationRecord("skyseraph.nfc_demo") 205 }); 206 } else { 207 return new NdefMessage(new NdefRecord[] { 208 exteralRecord1 209 }); 210 } 211 } 212 213 /** 214 * checkSystemVersion() 215 */ 216 private boolean flagVersion = false; 217 218 private void checkSystemVersion() { 219 // TODO Auto-generated method stub 220 // if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) 221 222 LogUtil.i(MyConstant.TAG, TAG_ASSIST + "Product Model=" + android.os.Build.MODEL + ", " 223 + android.os.Build.VERSION.SDK + ", " + android.os.Build.VERSION.RELEASE); 224 String systemModel; 225 String releaseVersion; 226 String sdkVersion; 227 systemModel = android.os.Build.MODEL; 228 sdkVersion = android.os.Build.VERSION.SDK; 229 releaseVersion = android.os.Build.VERSION.RELEASE; 230 if (Integer.parseInt(sdkVersion) > 15) { 231 flagVersion = true; 232 } else { 233 flagVersion = false; 234 LogUtil.e(MyConstant.TAG, TAG_ASSIST + "Your android system version is low to API-16"); 235 } 236 } 237 238 /** 239 * NFC Forum "URI Record Type Definition" This is a mapping of 240 * "URI Identifier Codes" to URI string prefixes, per section 3.2.2 of the 241 * NFC Forum URI Record Type Definition document. 242 */ 243 private static final BiMap<Byte, String> URI_PREFIX_MAP = ImmutableBiMap 244 .<Byte, String> builder().put((byte)0x00, "").put((byte)0x01, "http://www.") 245 .put((byte)0x02, "https://www.").put((byte)0x03, "http://").put((byte)0x04, "https://") 246 .put((byte)0x05, "tel:").put((byte)0x06, "mailto:") 247 .put((byte)0x07, "ftp://anonymous:anonymous@").put((byte)0x08, "ftp://ftp.") 248 .put((byte)0x09, "ftps://").put((byte)0x0A, "sftp://").put((byte)0x0B, "smb://") 249 .put((byte)0x0C, "nfs://").put((byte)0x0D, "ftp://").put((byte)0x0E, "dav://") 250 .put((byte)0x0F, "news:").put((byte)0x10, "telnet://").put((byte)0x11, "imap:") 251 .put((byte)0x12, "rtsp://").put((byte)0x13, "urn:").put((byte)0x14, "pop:") 252 .put((byte)0x15, "sip:").put((byte)0x16, "sips:").put((byte)0x17, "tftp:") 253 .put((byte)0x18, "btspp://").put((byte)0x19, "btl2cap://").put((byte)0x1A, "btgoep://") 254 .put((byte)0x1B, "tcpobex://").put((byte)0x1C, "irdaobex://") 255 .put((byte)0x1D, "file://").put((byte)0x1E, "urn:epc:id:") 256 .put((byte)0x1F, "urn:epc:tag:").put((byte)0x20, "urn:epc:pat:") 257 .put((byte)0x21, "urn:epc:raw:").put((byte)0x22, "urn:epc:") 258 .put((byte)0x23, "urn:nfc:").build(); 259 }