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 }