概述
现在市面上所售的Android手机几乎都支持NFC功能,作为开发者有必要对其进行一番了解,NFC技术是一种短距高频的无线电技术,主要用于IOT领域。NFC在Android上,是从API9才开始支持的,但是到了API14 Google才对NFC大力开发,所以等到了API15的时候,NFC的传输速度就得到了很大的加强,所以最小api最好设置为14。它有三种模式数据交互形式:
- 读卡器模式(Reader/Witer Mode)
- 仿真卡模式(Card Emulation Mode)公交刷卡所用的方式
- 点对点模式(P2P Mode)共享数据所用的方式
今天主要实现读卡器模式。具体实现:
权限的配置
1
2
3
4<uses-permission android:name="android.permission.NFC" />
<!-- 要求当前设备必须要有NFC芯片 -->
<uses-feature android:name="android.hardware.nfc"
android:required="true" />当我们在注册activity的时候还需要加上过滤NFC的intent,目的是一旦NFC标签靠近手机,手机发起响应不能让它调起系统自带的NFC应用,而是我们的应用
1
2
3<intent-filter>
<action android:name="android.nfc.action.TAG_DISCOVERED"/>
</intent-filter>定义NFC标签的规则标准,目的是哪些符合标准的NFC标签可以让自己的应用响应。该标准由xml文件编写,例如创建一个nfc_model.xml的文件。该文件放在rew资源中的xml文件夹中
nfc_model.xml里面的内容有:
1
2
3
4
5<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<tech-list>
<tech>android.nfc.tech.MifareClassic</tech>
</tech-list>
</resources>在注册activity时将nfc_model.xml文件添加进去:
1
2<meta-data android:name="android.nfc.action.TECH_DISCOVERED"
android:resource="@xml/nfc_model" />
- 在Activity中重写onNewIntent,这里的android:launchMode为”singleTop”,要注意。对NFC标签无论是读还是写都会调用这个重写的方法,数据格式是ndef
1
2
3
4
5
6
7
8
9
10
11
12
13
protected void onNewIntent(Intent intent) {//通过intent来作为数据的载体
if(iswrite){//是写入
Tag detectedTag =intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
NdefMessage ndefMessage = new NdefMessage(new NdefRecord[]{createTextRecord(mTagText)});//写入ndef格式的字符串
boolean result = writeTag(ndefMessage, detectedTag);
if (result) {//写入成功
}
}else{//是读
readNfcTag(intent);
}
}
/*
读
*/
`
java
private void readNfcTag(Intent intent) {
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())) {//标签靠近手机时,手机响应NFC标签
Parcelable[] rawMsgs = intent.getParcelableArrayExtra(
NfcAdapter.EXTRA_NDEF_MESSAGES);//获取序列数组
NdefMessage msgs[] = null;
if (rawMsgs != null) {//将数组放进NdefMessage中
msgs = new NdefMessage[rawMsgs.length];
for (int i = 0; i < rawMsgs.length; i++) {
msgs[i] = (NdefMessage) rawMsgs[i];
}
}
NdefRecord record = msgs[0].getRecords()[0];
String textRecord = parseTextRecord(record);
//textRecord 就是读到的nfc标签里的字符串了
}
}
/**
* 将文本信息转成ndef格式的NdefRecord
*
* @param text
* @return
*/
protected NdefRecord createTextRecord(String text) {
byte[] langBytes = Locale.CHINA.getLanguage().getBytes(Charset.forName("US-ASCII"));
Charset utfEncoding = Charset.forName("UTF-8");
//将文本转换为UTF-8格式
byte[] textBytes = text.getBytes(utfEncoding);
//设置状态字节编码最高位数为0
int utfBit = 0;
//定义状态字节
char status = (char) (utfBit + langBytes.length);
byte[] data = new byte[1 + langBytes.length + textBytes.length];
//设置第一个状态字节,先将状态码转换成字节
data[0] = (byte) status;
//设置语言编码,使用数组拷贝方法,从0开始拷贝到data中,拷贝到data的1到langBytes.length的位置
System.arraycopy(langBytes, 0, data, 1, langBytes.length);
//设置文本字节,使用数组拷贝方法,从0开始拷贝到data中,拷贝到data的1 + langBytes.length
//到textBytes.length的位置
System.arraycopy(textBytes, 0, data, 1 + langBytes.length, textBytes.length);
//通过字节传入NdefRecord对象
//NdefRecord.RTD_TEXT:传入类型 读写
NdefRecord ndefRecord = new NdefRecord(NdefRecord.TNF_WELL_KNOWN,
NdefRecord.RTD_TEXT, new byte[0], data);
return ndefRecord;
}
- 这里以Ndef开头的两个类,都是核心类:NdefMessage:主要是描述NDEF格式的信息。NdefRecord:这个是秒速NDEF信息的一个信息段。有了读和写,我们就能进行基本的数据交互。十分的简单。NFC标签属于IOT的范畴,有很多种的用途。更多的逻辑处理是在于读写的操作上。标签里如果需要存在大量的数据的话,需要把写入的文本数据写成json格式的字符串,再通过手机获取信息发送的服务器。