只有遵守NDEF文本格式规范的数据才能写到nfc标签上.
NDEF文本格式规范
不管什么格式的数据本质上都是由一些字节组成的。对于NDEF文本格式来说。
1,这些数据的第1个字节描述了数据的状态,
2,然后若干个字节描述文本的语言编码,
3,最后剩余字节表示文本数据。
其中第1个字节是 状态字节编码格式
这些数据格式由NFC Forum的相关规范定义,可以从下面的地址下载相关的规范。
http://www.nfc-forum.org/specs/spec_dashboard
重要
获取NFC标签中的数据要通过NdefRecord.getPayload方法完成。
在处理这些数据之前,最好判断一下NdefRecord对象中存储的是不是NDEF文本格式数据。
判断的标准有如下两个
TNF(类型名格式,Type Name Format)必须是NdefRecord.TNF_WELL_KNOWN。
可变的长度类型必须是NdefRecord.RTD_TEXT
解析示例
1 public class TextRecord { 2 private final String mText; 3 4 private TextRecord(String text) { 5 mText = text; 6 } 7 8 public String getText() { 9 return mText; 10 } 11 12 public static TextRecord parse(NdefRecord ndefRecord) { 13 /* 14 * 1,判断数据是否为NDEF格式 15 */ 16 // verify tnf 17 //第一个判断,TNF(类型名格式,Type Name Format)必须是NdefRecord.TNF_WELL_KNOWN 18 if (ndefRecord.getTnf() != NdefRecord.TNF_WELL_KNOWN) { 19 return null; 20 } 21 //第二个判断,可变的长度类型必须是NdefRecord.RTD_TEXT。 22 if (!Arrays.equals(ndefRecord.getType(), NdefRecord.RTD_TEXT)) { 23 return null; 24 } 25 26 try { 27 /* 28 * 2,取得读到的ndef字节流, 29 * 第1个字节描述了数据的状态,然后若干个字节描述文本的语言编码,最后剩余字节表示文本数据 30 */ 31 byte[] payload = ndefRecord.getPayload(); 32 33 /* 34 * 3,解析第1个字节最高位,第7位:本流的字符编码值, 若值是0是UTF8,1是UTF16 35 * 注意 字符编码与语言编码不同. 36 */ 37 String textEncoding = ((payload[0] & 0x80) == 0) ? "UTF-8" : "UTF-16"; 38 //第1个字节第6位总为0 39 /* 40 * 4,解析第1个字节0-5位,它存放语言编码的长度值 41 * 注意 字符编码与语言编码不同. 42 */ 43 int languageCodeLength = payload[0] & 0x3f; 44 45 /* 46 * 5,解析语言编码 47 */ 48 String languageCode = new String(payload, 1, languageCodeLength,"US-ASCII"); 49 50 /* 51 * 6,解析出文本内容 52 */ 53 String text = new String(payload, languageCodeLength + 1, 54 payload.length - languageCodeLength - 1, textEncoding); 55 56 /* 57 * 7,返回解析结果 58 */ 59 return new TextRecord(text); 60 61 } catch (Exception e) { 62 throw new IllegalArgumentException(); 63 } 64 } 65 }
封装示例
1 /* 2 * 重要函数 3 * 将txt数据按ndef格式封装一个record 4 * 第1个字节描述了数据的状态,然后若干个字节描述文本的语言编码,最后剩余字节表示文本数据 5 */ 6 public NdefRecord createTextRecord(String text) { 7 /* 8 * 按ndef格式封装1,准备语言编码,注意不是字符编码 9 */ 10 byte[] langBytes = Locale.CHINA.getLanguage().getBytes( 11 Charset.forName("US-ASCII")); 12 /* 13 * 按ndef格式封装2,设置text的字符编码为utf8 14 */ 15 Charset utfEncoding = Charset.forName("UTF-8"); 16 byte[] textBytes = text.getBytes(utfEncoding); 17 int utfBit = 0; 18 /* 19 * 按ndef格式封装3,第1个字节描述了数据的状态 20 */ 21 char status = (char) (utfBit + langBytes.length); 22 23 /* 24 * 按ndef格式封装3,分配数据空间, 25 * 状态字节长度为1+语言编码长度+字符长度 26 */ 27 byte[] data = new byte[1 + langBytes.length + textBytes.length]; 28 /* 29 * 按ndef格式封装4,将各部分数据拷贝到数据中 30 */ 31 data[0] = (byte) status; 32 System.arraycopy(langBytes, 0, data, 1, langBytes.length); 33 System.arraycopy(textBytes, 0, data, 1 + langBytes.length,textBytes.length); 34 35 /* 36 * 按ndef格式封装5,用数据构造NdefRecord 37 */ 38 NdefRecord ndefRecord = new NdefRecord(NdefRecord.TNF_WELL_KNOWN, 39 NdefRecord.RTD_TEXT, new byte[0], data); 40 return ndefRecord; 41 }