1、添加相应的权限和gradle引用
android:name="android.hardware.nfc"
android:required="true"/><?xml version="1.0" encoding="utf-8"?>
android.nfc.tech.IsoDep-->
android.nfc.tech.NfcAtech>
android.nfc.tech.NfcB-->
android.nfc.tech.NfcF-->
android.nfc.tech.NfcV-->
android.nfc.tech.Ndeftech>
android.nfc.tech.NdefFormatable-->
android.nfc.tech.MifareClassic-->
android.nfc.tech.MifareUltralight-->
tech-list>
resources>
tech-list>resources>
3、使用NFC的activity添加设置
android:launchMode="singleTop">
intent-filter>
intent-filter>
intent-filter>
android:resource="@xml/nfc_tech_filter" />
activity>
4、NFCActivity代码package com.sam.more.activitys.rfid_nfc;
import android.annotation.SuppressLint;import android.app.PendingIntent;import android.content.Intent;import android.nfc.NdefMessage;import android.nfc.NfcAdapter;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.TextView;import android.widget.Toast;
import com.sam.more.R;
import java.util.Calendar;import java.util.List;
import butterknife.BindView;import butterknife.ButterKnife;import butterknife.OnClick;/**
* Author: Sam
* Date: 2020/11/25 9:41
* Describe:NFC读取数据页面 */
public class NFCActivity extends AppCompatActivity {
private static final String TAG = "NfcActivity";
@BindView(R.id.tv_show_nfc)
TextView tvShowNfc;
@BindView(R.id.btn_clean)
Button btnClean; private PendingIntent mPendingIntent; private NfcAdapter mNfcAdapter;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
setContentView(R.layout.activity_nfc);
ButterKnife.bind(this);
Log.i(TAG, "onCreate: ");
//初始化nfc
mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
mPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0); if (mNfcAdapter == null) {
Toast.makeText(this, "NFC不可用", Toast.LENGTH_SHORT).show();
finish(); return;
}
}
@Override protected void onResume() { super.onResume();
Log.i(TAG, "onResume: "); if (mNfcAdapter != null) { //有nfc功能
if (mNfcAdapter.isEnabled()) { //nfc功能打开了 //隐式启动
mNfcAdapter.enableForegroundDispatch(this, mPendingIntent, null, null);
} else {
Toast.makeText(this, "请打开NFC功能", Toast.LENGTH_SHORT).show();
}
}
}
@Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent);
Log.i(TAG, "onNewIntent: ");
setIntent(intent); if (mNfcAdapter != null) { //有nfc功能
if (mNfcAdapter.isEnabled()) {//nfc功能打开了 resolveIntent(getIntent());
} else {
Toast.makeText(this, "请打开NFC功能", Toast.LENGTH_SHORT).show();
}
}
}
@Override protected void onPause() { super.onPause(); if (mNfcAdapter != null) {
mNfcAdapter.disableForegroundDispatch(this);
}
}
//初次判断是什么类型的NFC卡
private void resolveIntent(Intent intent) {
NdefMessage[] msgs = NfcUtils.getNdefMsg(intent); //重点功能,解析nfc标签中的数据
if (msgs == null) {
Toast.makeText(this, "非NFC启动", Toast.LENGTH_SHORT).show();
} else {
setNFCMsgView(msgs);
}
}
/**
* 显示扫描后的信息
*
* @param ndefMessages ndef数据 */
@SuppressLint("SetTextI18n") private void setNFCMsgView(NdefMessage[] ndefMessages) { if (ndefMessages == null || ndefMessages.length == 0) { return;
}
Calendar calendar = Calendar.getInstance(); int hour = calendar.get(Calendar.HOUR_OF_DAY); int minute = calendar.get(Calendar.MINUTE);
tvShowNfc.append(hour + ":" + minute + "\n");
Listrecords = NdefMessageParser.parse(ndefMessages[0]); final int size = records.size(); for (int i = 0; i
ParsedNdefRecord record = records.get(i);
tvShowNfc.append(record.getViewText() + "\n");
}
}
@OnClick({R.id.btn_clean}) public void onViewClicked(View view) { switch (view.getId()) { case R.id.btn_clean:
tvShowNfc.setText(""); break;
}
}
}
NfcUtils工具类package com.sam.more.activitys.rfid_nfc;
import android.content.Intent;import android.nfc.NdefMessage;import android.nfc.NdefRecord;import android.nfc.NfcAdapter;import android.nfc.Tag;import android.nfc.tech.MifareClassic;import android.nfc.tech.MifareUltralight;import android.os.Parcelable;import android.util.Log;
import java.util.Arrays;
/**
* Auther: Sam
* Time: 2020/11/24 17:26
* Describe: */
public class NfcUtils { private static final String TAG = "NfcUtil";
/**
* 解析 ndefRecord 文本数据
*
* @param ndefRecord
* @return
*/
public static String parse(NdefRecord ndefRecord) { // verify tnf 得到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(); // payload[0]取第一个字节。 0x80:十六进制(最高位是1剩下全是0)
String textEncoding = ((payload[0] & 0x80) == 0) ? "UTF-8" : "UTF-16"; // 获得语言编码长度
int languageCodeLength = payload[0] & 0x3f; // 获得语言编码
String languageCode = new String(payload, 1, languageCodeLength, "US-ASCII"); // String text = new String(payload, languageCodeLength + 1, payload.length - languageCodeLength - 1, textEncoding);
return text;
} catch (Exception e) { throw new IllegalArgumentException();
}
}
//初次判断是什么类型的NFC卡
public static NdefMessage[] getNdefMsg(Intent intent) { if (intent == null) return null;
//nfc卡支持的格式
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
String[] temp = tag.getTechList(); for (String s : temp) {
Log.i(TAG, "resolveIntent tag: " + s);
}
String action = intent.getAction();
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action) ||
NfcAdapter.ACTION_TECH_DISCOVERED.equals(action) ||
NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)) {
Parcelable[] rawMessage = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
NdefMessage[] ndefMessages;
// 判断是哪种类型的数据 默认为NDEF格式
if (rawMessage != null) {
Log.i(TAG, "getNdefMsg: ndef格式 ");
ndefMessages = new NdefMessage[rawMessage.length]; for (int i = 0; i
ndefMessages[i] = (NdefMessage) rawMessage[i];
}
} else { //未知类型
Log.i(TAG, "getNdefMsg: 未知类型"); byte[] empty = new byte[0]; byte[] id = intent.getByteArrayExtra(NfcAdapter.EXTRA_ID);
Parcelable parcelable = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); byte[] payload = dumpTagData(parcelable).getBytes();
NdefRecord record = new NdefRecord(NdefRecord.TNF_UNKNOWN, empty, id, payload);
NdefMessage msg = new NdefMessage(new NdefRecord[]{record});
ndefMessages = new NdefMessage[]{msg};
}
return ndefMessages;
}
return null;
}
//一般公交卡,扫描的信息
private static String dumpTagData(Parcelable p) {
StringBuilder sb = new StringBuilder();
Tag tag = (Tag) p; byte[] id = tag.getId();
sb.append("Tag ID (hex): ").append(getHex(id)).append("\n");
sb.append("Tag ID (dec): ").append(getDec(id)).append("\n");
sb.append("ID (reversed): ").append(getReversed(id)).append("\n");
String prefix = "android.nfc.tech.";
sb.append("Technologies: "); for (String tech : tag.getTechList()) {
sb.append(tech.substring(prefix.length()));
sb.append(", ");
}
sb.delete(sb.length() - 2, sb.length()); for (String tech : tag.getTechList()) { if (tech.equals(MifareClassic.class.getName())) {
sb.append('\n');
MifareClassic mifareTag = MifareClassic.get(tag);
String type = "Unknown"; switch (mifareTag.getType()) { case MifareClassic.TYPE_CLASSIC:
type = "Classic"; break; case MifareClassic.TYPE_PLUS:
type = "Plus"; break; case MifareClassic.TYPE_PRO:
type = "Pro"; break;
}
sb.append("Mifare Classic type: ");
sb.append(type);
sb.append('\n');
sb.append("Mifare size: ");
sb.append(mifareTag.getSize() + " bytes");
sb.append('\n');
sb.append("Mifare sectors: ");
sb.append(mifareTag.getSectorCount());
sb.append('\n');
sb.append("Mifare blocks: ");
sb.append(mifareTag.getBlockCount());
}
if (tech.equals(MifareUltralight.class.getName())) {
sb.append('\n');
MifareUltralight mifareUlTag = MifareUltralight.get(tag);
String type = "Unknown"; switch (mifareUlTag.getType()) { case MifareUltralight.TYPE_ULTRALIGHT:
type = "Ultralight"; break; case MifareUltralight.TYPE_ULTRALIGHT_C:
type = "Ultralight C"; break;
}
sb.append("Mifare Ultralight type: ");
sb.append(type);
}
} return sb.toString();
}
private static String getHex(byte[] bytes) {
StringBuilder sb = new StringBuilder(); for (int i = bytes.length - 1; i >= 0; --i) { int b = bytes[i] & 0xff; if (b
sb.append('0');
sb.append(Integer.toHexString(b)); if (i > 0) {
sb.append(" ");
}
} return sb.toString();
}
private static long getDec(byte[] bytes) { long result = 0; long factor = 1; for (int i = 0; i
result += value * factor;
factor *= 256l;
} return result;
}
private static long getReversed(byte[] bytes) { long result = 0; long factor = 1; for (int i = bytes.length - 1; i >= 0; --i) { long value = bytes[i] & 0xffl;
result += value * factor;
factor *= 256l;
} return result;
}
}
本文详细介绍了如何在Android应用中实现NFC功能,包括添加权限和Gradle引用,配置Activity,处理NDEF消息,以及解析不同类型的NFC标签数据。通过示例代码展示了如何读取和展示NFC标签中的文本信息,并提供了NfcUtils工具类来辅助处理NFC数据。
5408

被折叠的 条评论
为什么被折叠?



