android nfc 原始读取,Android NFC读取数据

本文详细介绍了如何在Android应用中实现NFC功能,包括添加权限和Gradle引用,配置Activity,处理NDEF消息,以及解析不同类型的NFC标签数据。通过示例代码展示了如何读取和展示NFC标签中的文本信息,并提供了NfcUtils工具类来辅助处理NFC数据。

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;

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值