NFC(11)MifareUltralight格式规范及读写示例
注意
MifareUltralight 不支三种过滤方式之一,只支持第四种(用代码,activity singleTop )
见 NFC(4)响应NFC设备时启动activity的四重过滤机制
MifareUltralight数据格式规范
将NFC标签的存储区域分为16个页,每一个页可以存储4个字节,一个可存储64个字节(512位)。页码从0开始(0至15)。前4页(0至3)存储了NFC标签相关的信息(如NFC标签的序列号、控制位等)。从第5页开始存储实际的数据(4至15页)。
示例代码:
1 import java.nio.charset.Charset; 2 3 import android.app.Activity; 4 import android.app.PendingIntent; 5 import android.content.Intent; 6 import android.nfc.NfcAdapter; 7 import android.nfc.Tag; 8 import android.nfc.tech.MifareUltralight; 9 import android.os.Bundle; 10 import android.widget.CheckBox; 11 import android.widget.Toast; 12 13 14 /* 15 * 本类为处理MifareUltralighto格式nfc标签的aty 16 */ 17 public class MifareultralightMainActivity extends Activity { 18 19 private CheckBox mWriteData; 20 private NfcAdapter mNfcAdapter; 21 private PendingIntent mPendingIntent; 22 23 @Override 24 public void onCreate(Bundle savedInstanceState) { 25 super.onCreate(savedInstanceState); 26 27 setContentView(R.layout.activity_mifareultralight); 28 mWriteData = (CheckBox) findViewById(R.id.checkbox_write); 29 30 //1,设置当前窗口为处理nfc标签的窗口. 31 mNfcAdapter = NfcAdapter.getDefaultAdapter(this); 32 mPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this,getClass()), 0); 33 } 34 35 /* 36 * 2,注册为处理nfc标签的前台窗口 37 */ 38 @Override 39 public void onResume() { 40 super.onResume(); 41 if (mNfcAdapter != null) { 42 mNfcAdapter.enableForegroundDispatch(this, mPendingIntent, null,null); 43 } 44 } 45 @Override 46 public void onNewIntent(Intent intent) { 47 //得到nfc标签. 48 Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); 49 50 //得到nfc标签内支持的数据格式,如ndef,MifareUltralight 51 String[] techList = tag.getTechList(); 52 53 //判断是否支持MifareUltralight数据格式 54 boolean haveMifareUltralight = false; 55 for (String tech : techList) { 56 if (tech.indexOf("MifareUltralight") >= 0) { 57 haveMifareUltralight = true; 58 break; 59 } 60 } 61 if (!haveMifareUltralight) {//标签不支持MifareUltralight数据格式 62 Toast.makeText(this, "本标签不支持MifareUltralight数据格式",Toast.LENGTH_LONG).show(); 63 return; 64 } 65 if (mWriteData.isChecked()) { 66 //3,写数据 67 writeTag(tag); 68 } else { 69 //4,读数据 70 String data = readTag(tag); 71 if (data != null) 72 Toast.makeText(this, data, Toast.LENGTH_LONG).show(); 73 } 74 75 } 76 /* 77 *5,注销处理nfc标签的窗口 78 */ 79 @Override 80 public void onPause() { 81 super.onPause(); 82 if (mNfcAdapter != null) { 83 mNfcAdapter.disableForegroundDispatch(this); 84 } 85 } 86 /* 87 * 向nfc标签写入数据 88 * 将NFC标签的存储区域分为16个页,每一个页可以存储4个字节,一个可存储64个字节(512位)。 89 * 页码从0开始(0至15)。前4页(0至3)存储了NFC标签相关的信息(如NFC标签的序列号、控制位等)。 90 * 从第5页开始存储实际的数据(4至15页)。 91 */ 92 public void writeTag(Tag tag) { 93 //向nfc标签写数据第1步,从标签中得到MifareUltralight 94 MifareUltralight ultralight = MifareUltralight.get(tag); 95 try { 96 //向nfc标签写数据第2步, connect 97 ultralight.connect(); 98 99 /* 100 * 向nfc标签写数据第3步, 正式写数据.前4页(0至3)存储了NFC标签相关的信息 101 * 102 * 注意 Charset.forName("GB2312")), 103 * 不用utf-8因为一个汉字有可能用3个字节编码汉字,那么2个汉字有可能是6个字节. 104 * 而GB2312始终用2个字节.而每页最多4个字节, 105 */ 106 ultralight.writePage(4, "中国".getBytes(Charset.forName("GB2312")));//第4页,页从0开始. 107 ultralight.writePage(5, "美国".getBytes(Charset.forName("GB2312"))); 108 ultralight.writePage(6, "英国".getBytes(Charset.forName("GB2312"))); 109 ultralight.writePage(7, "德国".getBytes(Charset.forName("GB2312"))); 110 111 Toast.makeText(this, "成功写入MifareUltralight格式数据",Toast.LENGTH_LONG).show(); 112 } catch (Exception e) { 113 e.printStackTrace(); 114 } finally { 115 try { 116 ultralight.close(); 117 } catch (Exception e) { 118 e.printStackTrace(); 119 } 120 } 121 } 122 /* 123 * 读取MifareUltralight格式数据 124 */ 125 public String readTag(Tag tag) { 126 //读数据 第1步,从nfc标签中得到MifareUltralight 127 MifareUltralight ultralight = MifareUltralight.get(tag); 128 129 try { 130 //读数据 第2步,接连 131 ultralight.connect(); 132 //读数据 第3步,从ultralight数据中的下标为4的位开始读数据. 133 byte[] data = ultralight.readPages(4); 134 //读数据 第4步,把读出的数据存到一个string中.注意语言编码 135 return new String(data, Charset.forName("GB2312")); 136 } catch (Exception e) { 137 e.printStackTrace(); 138 } finally { 139 try { 140 ultralight.close(); 141 } catch (Exception e) { 142 e.printStackTrace(); 143 } 144 } 145 return null; 146 } 147 }