要获取NFC标签,首先需要添加NFC权限
<uses-feature
android:name="android.hardware.nfc"
android:required="true"/>
<uses-permission android:name="android.permission.NFC"/>
获取NFC标签及其ID
```
class NfcActivity :BaseActivity() {
private lateinit var imgBack:ImageView
private lateinit var mNfcAdapter:NfcAdapter
private lateinit var mPendingIntent:PendingIntent
//nfc标签信息
private lateinit var tvNfcTag:TextView
//nfc十进制ID
private lateinit var tvNfcD:TextView
//nfc16进制ID
private lateinit var tvNfcH:TextView
/**
* 启动Activity
*/
override fun onStart() {
super.onStart()
mNfcAdapter =NfcAdapter.getDefaultAdapter(this)
//一旦截获NFC消息,就会通过PendingIntent调用窗口
mPendingIntent =PendingIntent.getActivity(this,0,Intent(this,javaClass),0)
}
override fun getLayoutId():Int {
return R.layout.activity_nfc
}
override fun eventBus(event:Any?) {
}
override fun onCreate(savedInstanceState:Bundle?) {
super.onCreate(savedInstanceState)
imgBack =findViewById(R.id.img_nfc_back)
tvNfcD =findViewById(R.id.tv_nfc_d)
tvNfcH =findViewById(R.id.tv_nfc_h)
tvNfcTag =findViewById(R.id.tv_nfc_tag)
imgBack.setOnClickListener {finish() }
}
override fun onResume() {
super.onResume()
//设置处理优于所有其他NFC的处理
mNfcAdapter.enableForegroundDispatch(
this,
mPendingIntent,
null,
null
)
}
override fun onPause() {
super.onPause()
//恢复默认状态
mNfcAdapter.disableForegroundDispatch(this)
}
override fun onNewIntent(intent:Intent?) {
super.onNewIntent(intent)
// readFromTag(intent);
readNfcTag(intent!!)
}
/**
* 读取NFC标签文本数据
*/
private fun readNfcTag(intent:Intent) {
val tag:Tag? =intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)
if (tag !=null) {
val cardNo =flipHexStr(ByteArrayToHexString(tag.id)).toLong(16)
tvNfcD.text = cardNo.toString()
tvNfcH.text =ByteArrayToHexString(tag.id)
}
if (NfcAdapter.ACTION_NDEF_DISCOVERED ==intent.action) {
val rawMessages =intent.getParcelableArrayExtra(
NfcAdapter.EXTRA_NDEF_MESSAGES
)
var msgs:Array? =null
var contentSize =0
if (rawMessages !=null) {
msgs =arrayOfNulls(rawMessages.size)
for (iin rawMessages.indices) {
msgs[i] = rawMessages[i]as NdefMessage
contentSize +=msgs[i]!!.toByteArray().size
}
}
try {
if (null !=msgs) {
val record =msgs[0]!!.records[0]
val textRecord:String? =
NfcUtil.parseTextRecord(record)
Log.e("nfcTag-->","" + textRecord)
tvNfcTag.text = textRecord
}
}catch (e:Exception) {
e.printStackTrace()
Log.e("nfcError-->","" + e)
}
}
}
}
```
获取标签及其ID的工具类
import android.nfc.NdefRecord;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
public class NfcUtil {
/**
* 解析NDEF文本数据,从第三个字节开始,后面的文本数据
* @param ndefRecord
* @return
*/
public static String parseTextRecord(NdefRecord ndefRecord) {
/**
* 判断数据是否为NDEF格式
* 判断TNF
*/
if (ndefRecord.getTnf() !=NdefRecord.TNF_WELL_KNOWN) {
return null;
}
//判断可变的长度的类型
if (!Arrays.equals(ndefRecord.getType(),NdefRecord.RTD_TEXT)) {
return null;
}
try {
//获得字节数组,然后进行分析
byte[] payload =ndefRecord.getPayload();
//下面开始NDEF文本数据第一个字节,状态字节
//判断文本是基于UTF-8还是UTF-16的,取第一个字节"位与"上16进制的80,16进制的80也就是最高位是1,
//其他位都是0,所以进行"位与"运算后就会保留最高位
String textEncoding = ((payload[0] &0x80) ==0) ?"UTF-8" :"UTF-16";
//3f最高两位是0,第六位是1,所以进行"位与"运算后获得第六位
int languageCodeLength = payload[0] &0x3f;
//下面开始NDEF文本数据第二个字节,语言编码
//获得语言编码
String languageCode =new String(payload,1, languageCodeLength,StandardCharsets.US_ASCII);
//下面开始NDEF文本数据后面的字节,解析出文本
String textRecord =new String(payload, languageCodeLength +1,
payload.length - languageCodeLength -1, textEncoding);
return textRecord;
}catch (Exception e) {
throw new IllegalArgumentException();
}
}
// 16转10进制
public static String flipHexStr(String s) {
StringBuilder result =new StringBuilder();
for (int i =0; i <=s.length() -2; i = i +2) {
result.append(new StringBuilder(s.substring(i, i +2)).reverse());
}
return result.reverse().toString();
}
public static String ByteArrayToHexString(byte[]inarray) {
int i, j, in;
String[] hex = {"0","1","2","3","4","5","6","7","8","9","A",
"B","C","D","E","F"};
StringBuilder out =new StringBuilder();
for (j =0; j
in = (int)inarray[j] &0xff;
i = (in >>4) &0x0f;
out.append(hex[i]);
i = in &0x0f;
out.append(hex[i]);
}
return out.toString();
}
}