package com.dayu.baselibrary.tools.nfc;
|
|
import android.app.Activity;
|
import android.content.Intent;
|
import android.nfc.NfcAdapter;
|
import android.nfc.Tag;
|
import android.nfc.tech.MifareClassic;
|
import android.util.Log;
|
|
import com.dayu.baselibrary.bean.BaseManagerToUserCard;
|
import com.dayu.baselibrary.bean.BaseUserCardCard;
|
import com.dayu.baselibrary.tools.HexUtil;
|
import com.dayu.baselibrary.utils.BaseCommon;
|
|
import java.io.IOException;
|
import java.util.ArrayList;
|
import java.util.Arrays;
|
import java.util.HashMap;
|
import java.util.List;
|
import java.util.Map;
|
|
/**
|
* 原生NFC读卡工具类
|
*
|
* 功能说明:
|
* 1. 使用Android原生NFC API读取Mifare Classic卡片数据
|
* 2. 支持读取用户卡信息、管理卡信息、卡号、卡类型等
|
* 3. 支持扇区级别的数据读取和验证
|
* 4. 提供多种密钥验证方式(KeyA验证)
|
* 5. 支持单例模式,确保资源正确管理
|
*
|
* 使用场景:
|
* - 用户卡信息读取
|
* - 管理卡信息读取
|
* - 卡片类型识别
|
* - 卡号获取
|
* - 扇区数据读取
|
*
|
* 注意事项:
|
* - 需要确保NFC功能已开启
|
* - 读取前需要进行密钥验证
|
* - 使用完毕后需要关闭连接,释放资源
|
* - 异常情况下要正确处理连接关闭
|
*
|
* @author zuo
|
* @date 2024-09-25
|
* @time 10:33
|
*/
|
public class NativeNfcReadHelper extends BaseNfcReadHelper {
|
|
/** NFC标签对象,包含卡片的基本信息 */
|
private Tag tag;
|
|
/** 单例实例 */
|
private static NativeNfcReadHelper helper;
|
|
/**
|
* 设置Intent,从中提取NFC标签信息
|
*
|
* @param intent 包含NFC标签信息的Intent
|
*/
|
@Override
|
public void setIntent(Intent intent) {
|
this.tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
|
}
|
|
/**
|
* 获取单例实例
|
*
|
* @param intent 包含NFC标签信息的Intent
|
* @param activity 当前Activity实例
|
* @return NativeNfcReadHelper实例
|
*/
|
public static NativeNfcReadHelper getInstence(Intent intent, Activity activity) {
|
if (helper == null) {
|
helper = new NativeNfcReadHelper();
|
}
|
helper.setIntent(intent);
|
return helper;
|
}
|
|
/**
|
* 获取用户卡数据(默认从扇区1读取)
|
*
|
* @param userCardCard 用户卡数据模板对象,用于解析读取的字节数据
|
* @return 解析后的用户卡数据对象,失败返回null
|
*/
|
public BaseUserCardCard getUserCardData(BaseUserCardCard userCardCard) {
|
return getUserCardData(1, userCardCard);
|
}
|
|
/**
|
* 从指定扇区获取用户卡信息
|
*
|
* 读取流程:
|
* 1. 建立NFC连接
|
* 2. 使用密钥验证扇区访问权限
|
* 3. 读取扇区内所有块的数据
|
* 4. 将字节数据解析为用户卡对象
|
* 5. 关闭连接并返回结果
|
*
|
* @param sectorIndex 要读取的扇区索引(从0开始)
|
* @param userCardCard 用户卡数据模板对象
|
* @return 解析后的用户卡数据对象,失败返回null
|
*/
|
@Override
|
public BaseUserCardCard getUserCardData(int sectorIndex, BaseUserCardCard userCardCard) {
|
if (userCardCard != null) {
|
BaseUserCardCard userCard = null;
|
Map<String, List<byte[]>> map = new HashMap<>();
|
MifareClassic mfc = MifareClassic.get(tag);
|
if (null != mfc) {
|
try {
|
// 建立NFC连接
|
mfc.connect();
|
|
// 用于判断是否有内容读取出来
|
boolean flag = false;
|
List<byte[]> list = new ArrayList<>();
|
|
// 验证扇区密码,否则会报错(连接失败错误)
|
boolean isOpen = false;
|
if (!listKeyA.isEmpty()) {
|
// 遍历所有可用的KeyA密钥进行验证
|
for (int i = 0; i < listKeyA.size(); i++) {
|
if (mfc.authenticateSectorWithKeyA(sectorIndex, listKeyA.get(i))) {
|
isOpen = true;
|
break;
|
}
|
}
|
} else if (!listA_PS.isEmpty()) {
|
// 使用默认密钥或特定扇区密钥进行验证
|
if (mfc.authenticateSectorWithKeyA(sectorIndex, defauleKey)) {
|
isOpen = true;
|
} else if (mfc.authenticateSectorWithKeyA(sectorIndex, listA_PS.get(sectorIndex))) {
|
isOpen = true;
|
}
|
}
|
|
if (isOpen) {
|
// 获取扇区里面块的数量
|
int bCount = mfc.getBlockCountInSector(sectorIndex);
|
// 获取扇区第一个块对应芯片存储器的位置
|
int bIndex = mfc.sectorToBlock(sectorIndex);
|
|
// 读取扇区内所有块的数据
|
for (int j = 0; j < bCount; j++) {
|
byte[] data = null;
|
try {
|
data = mfc.readBlock(bIndex);
|
bIndex++;
|
list.add(data);
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
}
|
flag = true;
|
}
|
|
if (flag) {
|
// 将读取的字节数据解析为用户卡对象
|
userCard = userCardCard.getBean(list);
|
return userCard;
|
}
|
} catch (IOException e) {
|
e.printStackTrace();
|
} catch (Exception e) {
|
e.printStackTrace();
|
} finally {
|
// 确保连接被正确关闭,释放资源
|
try {
|
mfc.close();
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
}
|
}
|
}
|
return null;
|
}
|
|
/**
|
* 获取卡片类型
|
*
|
* 读取扇区1第一个块的第一个字节作为卡片类型标识
|
*
|
* @return 卡片类型的十六进制字符串,失败返回错误码
|
*/
|
@Override
|
public String getCradType() {
|
MifareClassic mfc = MifareClassic.get(tag);
|
if (null != mfc) {
|
try {
|
mfc.connect();
|
boolean isOpen = false;
|
|
// 使用KeyA密钥验证扇区1的访问权限
|
for (int i = 0; i < listKeyA.size(); i++) {
|
if (mfc.authenticateSectorWithKeyA(1, listKeyA.get(i))) {
|
isOpen = true;
|
break;
|
}
|
}
|
|
if (isOpen) {
|
// 读取扇区1第一个块的数据
|
int bIndex = mfc.sectorToBlock(1);
|
byte[] data = mfc.readBlock(bIndex + 0);
|
if (data != null && data.length > 0) {
|
// 将第一个字节转换为十六进制字符串作为卡片类型
|
String hex = HexUtil.byteToHex(data[0]);
|
Log.i("NFCWreatActivity", "hex===" + hex);
|
return hex;
|
}
|
} else {
|
Log.i("NFCWreatActivity", "isOpen===" + isOpen);
|
return BaseCommon.CARD_TYPE_ERROR2; // 密钥验证失败
|
}
|
} catch (IOException e) {
|
return BaseCommon.CARD_TYPE_ERROR1; // IO异常
|
} finally {
|
try {
|
mfc.close();
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
}
|
}
|
return "";
|
}
|
|
/**
|
* 读取NFC卡的全部信息
|
*
|
* 遍历所有扇区,读取每个扇区的所有块数据
|
*
|
* @param callback 数据读取完成后的回调接口
|
*/
|
@Override
|
public void getAllData(final NFCCallMapback callback) {
|
Map<String, List<byte[]>> map = new HashMap<>();
|
MifareClassic mfc = MifareClassic.get(tag);
|
if (null != mfc) {
|
try {
|
// 建立NFC连接
|
mfc.connect();
|
// 获取扇区数量
|
int count = mfc.getSectorCount();
|
// 存储空间大小
|
int size = mfc.getSize();
|
// 用于判断是否有内容读取出来
|
boolean flag = false;
|
|
// 遍历所有扇区
|
for (int i = 0; i < count; i++) {
|
List<byte[]> list = new ArrayList<>();
|
// 验证扇区密码
|
boolean isOpen = false;
|
for (int j = 0; j < listKeyA.size(); j++) {
|
if (mfc.authenticateSectorWithKeyA(i, listKeyA.get(i))) {
|
isOpen = true;
|
break;
|
}
|
}
|
|
if (isOpen) {
|
// 获取扇区里面块的数量
|
int bCount = mfc.getBlockCountInSector(i);
|
// 获取扇区第一个块对应芯片存储器的位置
|
int bIndex = mfc.sectorToBlock(i);
|
|
// 读取扇区内所有块的数据
|
for (int j = 0; j < bCount; j++) {
|
byte[] data = null;
|
try {
|
data = mfc.readBlock(bIndex);
|
bIndex++;
|
list.add(data);
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
}
|
flag = true;
|
}
|
map.put(i + "", list);
|
}
|
|
if (flag) {
|
callback.callBack(map);
|
} else {
|
callback.error(CardCommonState.ERROR);
|
}
|
} catch (IOException e) {
|
callback.error(CardCommonState.ERROR_MOVE);
|
e.printStackTrace();
|
} catch (Exception e) {
|
callback.error(CardCommonState.ERROR);
|
e.printStackTrace();
|
} finally {
|
try {
|
mfc.close();
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
}
|
}
|
}
|
|
/**
|
* 获取扇区1的信息
|
*
|
* 专门用于读取扇区1的所有块数据,通常用于读取用户卡信息
|
*
|
* @param callback 数据读取完成后的回调接口
|
*/
|
@Override
|
public void getOneSectorData(NFCCallListback callback) {
|
MifareClassic mfc = null;
|
try {
|
mfc = MifareClassic.get(tag);
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
|
if (null != mfc) {
|
try {
|
// 建立NFC连接
|
mfc.connect();
|
// 用于判断是否有内容读取出来
|
boolean flag = false;
|
List<byte[]> list = new ArrayList<>();
|
|
// 验证扇区1的密码
|
boolean isOpen = false;
|
for (int i = 0; i < listKeyA.size(); i++) {
|
if (mfc.authenticateSectorWithKeyA(1, listKeyA.get(i))) {
|
isOpen = true;
|
break;
|
}
|
}
|
|
if (isOpen) {
|
// 获取扇区1里面块的数量
|
int bCount = mfc.getBlockCountInSector(1);
|
// 获取扇区1第一个块对应芯片存储器的位置
|
int bIndex = mfc.sectorToBlock(1);
|
|
// 读取扇区1内所有块的数据
|
for (int j = 0; j < bCount; j++) {
|
byte[] data = null;
|
try {
|
data = mfc.readBlock(bIndex);
|
bIndex++;
|
list.add(data);
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
}
|
flag = true;
|
}
|
|
if (flag) {
|
callback.callBack(list);
|
} else {
|
callback.error(CardCommonState.ERROR);
|
}
|
} catch (IOException e) {
|
callback.error(CardCommonState.ERROR_MOVE);
|
e.printStackTrace();
|
} catch (Exception e) {
|
callback.error(CardCommonState.ERROR);
|
e.printStackTrace();
|
} finally {
|
try {
|
mfc.close();
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
}
|
}
|
}
|
|
/**
|
* 读取NFC卡的特定扇区特定块信息
|
*
|
* @param a 扇区索引(从0开始)
|
* @param b 块索引(从0开始,相对于扇区内的块)
|
* @param callback 数据读取完成后的回调接口
|
*/
|
@Override
|
public void getData(final int a, final int b, final NFCCallByteback callback) {
|
new Thread(new Runnable() {
|
@Override
|
public void run() {
|
Map<String, List<String>> map = new HashMap<>();
|
MifareClassic mfc = MifareClassic.get(tag);
|
if (null != mfc) {
|
try {
|
mfc.connect();
|
int count = mfc.getSectorCount();
|
|
// 验证扇区索引是否有效
|
if (a < 0 || a > count - 1) {
|
callback.error(CardCommonState.ERROR);
|
return;
|
}
|
|
int bCount = mfc.getBlockCountInSector(a);
|
// 验证块索引是否有效
|
if (b < 0 || b > bCount - 1) {
|
callback.error(CardCommonState.ERROR);
|
return;
|
}
|
|
// 获取TAG的类型(用于调试)
|
int type = mfc.getType();
|
String typeS = "";
|
switch (type) {
|
case MifareClassic.TYPE_CLASSIC:
|
typeS = "TYPE_CLASSIC";
|
break;
|
case MifareClassic.TYPE_PLUS:
|
typeS = "TYPE_PLUS";
|
break;
|
case MifareClassic.TYPE_PRO:
|
typeS = "TYPE_PRO";
|
break;
|
case MifareClassic.TYPE_UNKNOWN:
|
typeS = "TYPE_UNKNOWN";
|
break;
|
}
|
|
// 验证扇区密码
|
boolean isOpen = false;
|
for (int i = 0; i < listKeyA.size(); i++) {
|
if (mfc.authenticateSectorWithKeyA(a, listKeyA.get(i))) {
|
isOpen = true;
|
break;
|
}
|
}
|
|
if (isOpen) {
|
// 读取指定扇区指定块的数据
|
int bIndex = mfc.sectorToBlock(a);
|
byte[] data = mfc.readBlock(bIndex + b);
|
callback.callBack(data);
|
} else {
|
callback.error(CardCommonState.ERROR);
|
}
|
} catch (IOException e) {
|
callback.error(CardCommonState.ERROR_MOVE);
|
e.printStackTrace();
|
} catch (Exception e) {
|
callback.error(CardCommonState.ERROR);
|
} finally {
|
try {
|
mfc.close();
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
}
|
}
|
}
|
}).start();
|
}
|
|
/**
|
* 获取卡号(读取后自动关闭连接)
|
*
|
* 从扇区0第一个块读取卡的UID作为卡号
|
*
|
* @return 卡号的十六进制字符串(大写),失败返回错误码或空字符串
|
*/
|
@Override
|
public String getCardNumber() {
|
if (tag == null) {
|
return "";
|
}
|
|
MifareClassic mfc = MifareClassic.get(tag);
|
if (null != mfc) {
|
try {
|
mfc.connect();
|
// 获取当前卡号
|
boolean isOpen = false;
|
if (!listKeyA.isEmpty()) {
|
// 使用KeyA密钥验证扇区0
|
for (int i = 0; i < listKeyA.size(); i++) {
|
if (mfc.authenticateSectorWithKeyA(0, listKeyA.get(i))) {
|
isOpen = true;
|
break;
|
}
|
}
|
} else if (!listA_PS.isEmpty()) {
|
// 使用默认密钥或特定密钥验证扇区0
|
if (mfc.authenticateSectorWithKeyA(0, defauleKey)) {
|
isOpen = true;
|
} else if (mfc.authenticateSectorWithKeyA(0, listA_PS.get(0))) {
|
isOpen = true;
|
}
|
}
|
|
if (isOpen) {
|
// 读取扇区0第一个块的数据
|
int bIndex = mfc.sectorToBlock(0);
|
byte[] data = mfc.readBlock(bIndex + 0);
|
if (data != null && data.length > 0) {
|
// 提取前4个字节作为UID
|
String hex = HexUtil.bytesToHex(Arrays.copyOfRange(data, 0, 4));
|
hex = HexUtil.spaceHex(hex); // 添加空格分隔
|
hex = HexUtil.HighLowHex(hex); // 高低位转换
|
Log.i("NFCWreatActivity", "hex===" + hex);
|
return hex.toUpperCase();
|
}
|
} else {
|
return BaseCommon.CARD_TYPE_ERROR2; // 密钥验证失败
|
}
|
|
} catch (IOException e) {
|
return BaseCommon.CARD_TYPE_ERROR1; // IO异常
|
} finally {
|
try {
|
mfc.close(); // 确保关闭连接
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
}
|
}
|
return "";
|
}
|
|
/**
|
* 获取卡号(不关闭连接)
|
*
|
* 与getCardNumber()功能相同,但不关闭NFC连接
|
* 适用于需要连续进行多次NFC操作的场景
|
*
|
* @return 卡号的十六进制字符串(大写),失败返回错误码或空字符串
|
*/
|
public String getCardNumberNoClose() {
|
if (tag == null) {
|
return "";
|
}
|
|
MifareClassic mfc = MifareClassic.get(tag);
|
if (null != mfc) {
|
try {
|
mfc.connect();
|
// 获取当前卡号
|
boolean isOpen = false;
|
if (!listKeyA.isEmpty()) {
|
// 使用KeyA密钥验证扇区0
|
for (int i = 0; i < listKeyA.size(); i++) {
|
if (mfc.authenticateSectorWithKeyA(0, listKeyA.get(i))) {
|
isOpen = true;
|
break;
|
}
|
}
|
} else if (!listA_PS.isEmpty()) {
|
// 使用默认密钥或特定密钥验证扇区0
|
if (mfc.authenticateSectorWithKeyA(0, defauleKey)) {
|
isOpen = true;
|
} else if (mfc.authenticateSectorWithKeyA(0, listA_PS.get(0))) {
|
isOpen = true;
|
}
|
}
|
|
if (isOpen) {
|
// 读取扇区0第一个块的数据
|
int bIndex = mfc.sectorToBlock(0);
|
byte[] data = mfc.readBlock(bIndex + 0);
|
if (data != null && data.length > 0) {
|
// 提取前4个字节作为UID
|
String hex = HexUtil.bytesToHex(Arrays.copyOfRange(data, 0, 4));
|
hex = HexUtil.spaceHex(hex); // 添加空格分隔
|
hex = HexUtil.HighLowHex(hex); // 高低位转换
|
Log.i("NFCWreatActivity", "hex===" + hex);
|
return hex.toUpperCase();
|
}
|
} else {
|
return BaseCommon.CARD_TYPE_ERROR2; // 密钥验证失败
|
}
|
|
} catch (IOException e) {
|
Log.i("NFCWreatActivity", e.toString());
|
return BaseCommon.CARD_TYPE_ERROR1; // IO异常
|
}
|
// 注意:这里不关闭连接
|
}
|
return "";
|
}
|
|
/**
|
* 获取卡片类型和卡号(默认参数)
|
*
|
* @return "卡号,卡片类型"格式的字符串
|
*/
|
@Override
|
public String getCradTypeAndCardNumber() {
|
return getCradTypeAndCardNumber(1, 0, 0);
|
}
|
|
/**
|
* 获取卡片类型和卡号(自动关闭连接)
|
*
|
* @param sectorIndex 读取卡片类型的扇区索引
|
* @param blockIndex 读取卡片类型的块索引
|
* @param cardTypeIndex 卡片类型字节在块中的位置索引
|
* @return "卡号,卡片类型"格式的字符串
|
*/
|
public String getCradTypeAndCardNumber(int sectorIndex, int blockIndex, int cardTypeIndex) {
|
return getCradTypeAndCardNumber(sectorIndex, blockIndex, cardTypeIndex, true);
|
}
|
|
/**
|
* 获取卡片类型和卡号
|
*
|
* 读取流程:
|
* 1. 从扇区0读取卡号
|
* 2. 从指定扇区读取卡片类型
|
* 3. 返回"卡号,卡片类型"格式的字符串
|
*
|
* @param sectorIndex 读取卡片类型的扇区索引
|
* @param blockIndex 读取卡片类型的块索引
|
* @param cardTypeIndex 卡片类型字节在块中的位置索引
|
* @param isClose 是否在读取完成后关闭连接
|
* @return "卡号,卡片类型"格式的字符串,失败返回错误码
|
*/
|
public String getCradTypeAndCardNumber(int sectorIndex, int blockIndex, int cardTypeIndex, boolean isClose) {
|
MifareClassic mfc = MifareClassic.get(tag);
|
if (null != mfc) {
|
try {
|
mfc.connect();
|
StringBuilder strData = new StringBuilder();
|
|
// 第一步:获取当前卡号(从扇区0读取)
|
boolean isOpen = false;
|
if (!listKeyA.isEmpty()) {
|
for (int i = 0; i < listKeyA.size(); i++) {
|
if (mfc.authenticateSectorWithKeyA(0, listKeyA.get(i))) {
|
isOpen = true;
|
break;
|
}
|
}
|
} else if (!listA_PS.isEmpty()) {
|
if (mfc.authenticateSectorWithKeyA(0, listA_PS.get(0))) {
|
isOpen = true;
|
} else if (mfc.authenticateSectorWithKeyA(0, defauleKey)) {
|
isOpen = true;
|
}
|
}
|
|
if (isOpen) {
|
int bIndex = mfc.sectorToBlock(0);
|
byte[] data = mfc.readBlock(bIndex + 0);
|
if (data != null && data.length > 0) {
|
// 提取卡号并格式化
|
String hex = HexUtil.bytesToHex(Arrays.copyOfRange(data, 0, 4));
|
hex = HexUtil.spaceHex(hex);
|
hex = HexUtil.HighLowHex(hex);
|
strData.append(hex);
|
strData.append(","); // 分隔符
|
Log.i("NFCWreatActivity", "hex===" + hex);
|
}
|
}
|
|
// 第二步:获取卡片类型(从指定扇区读取)
|
if (!listKeyA.isEmpty()) {
|
for (int i = 0; i < listKeyA.size(); i++) {
|
if (mfc.authenticateSectorWithKeyA(sectorIndex, listKeyA.get(i))) {
|
isOpen = true;
|
break;
|
}
|
}
|
} else if (!listA_PS.isEmpty()) {
|
if (mfc.authenticateSectorWithKeyA(sectorIndex, listA_PS.get(sectorIndex))) {
|
isOpen = true;
|
} else if (mfc.authenticateSectorWithKeyA(sectorIndex, defauleKey)) {
|
isOpen = true;
|
}
|
}
|
|
if (isOpen) {
|
int bIndex = mfc.sectorToBlock(sectorIndex);
|
byte[] data = mfc.readBlock(bIndex + 0);
|
if (data != null && data.length > 0) {
|
// 提取指定位置的字节作为卡片类型
|
String hex = HexUtil.byteToHex(data[cardTypeIndex]);
|
strData.append(hex);
|
Log.i("NFCWreatActivity", "hex===" + hex);
|
return strData.toString().toUpperCase();
|
}
|
} else {
|
Log.i("NFCWreatActivity", "isOpen===" + isOpen);
|
return BaseCommon.CARD_TYPE_ERROR2; // 密钥验证失败
|
}
|
} catch (IOException e) {
|
e.printStackTrace();
|
return BaseCommon.CARD_TYPE_ERROR1; // IO异常
|
} finally {
|
try {
|
if (isClose) {
|
mfc.close(); // 根据参数决定是否关闭连接
|
}
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
}
|
}
|
return "";
|
}
|
|
/**
|
* 获取扇区1的数据(返回字节数组列表)
|
*
|
* @return 扇区1所有块的字节数据列表,失败返回null
|
*/
|
@Override
|
public List<byte[]> getOnesectorData() {
|
MifareClassic mfc = null;
|
try {
|
mfc = MifareClassic.get(tag);
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
|
List<byte[]> list = new ArrayList<>();
|
if (null != mfc) {
|
try {
|
// 建立NFC连接
|
mfc.connect();
|
// 用于判断是否有内容读取出来
|
boolean flag = false;
|
|
// 验证扇区1的密码
|
boolean isOpen = false;
|
for (int i = 0; i < listKeyA.size(); i++) {
|
if (mfc.authenticateSectorWithKeyA(1, listKeyA.get(i))) {
|
isOpen = true;
|
break;
|
}
|
}
|
|
if (isOpen) {
|
// 获取扇区1里面块的数量
|
int bCount = mfc.getBlockCountInSector(1);
|
// 获取扇区1第一个块对应芯片存储器的位置
|
int bIndex = mfc.sectorToBlock(1);
|
|
// 读取扇区1内所有块的数据
|
for (int j = 0; j < bCount; j++) {
|
byte[] data = null;
|
try {
|
data = mfc.readBlock(bIndex);
|
bIndex++;
|
list.add(data);
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
}
|
}
|
|
} catch (IOException e) {
|
e.printStackTrace();
|
} catch (Exception e) {
|
e.printStackTrace();
|
} finally {
|
try {
|
mfc.close();
|
return list; // 在finally中返回结果
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
}
|
}
|
return null;
|
}
|
|
/**
|
* 获取管理卡转用户卡的数据
|
*
|
* 用于读取管理卡中存储的用户卡信息,通常用于管理卡向用户卡的数据转换
|
*
|
* @param baseManagerToUserCard 管理卡数据模板对象
|
* @return 解析后的管理卡数据对象,失败返回null
|
*/
|
@Override
|
public BaseManagerToUserCard getManagerToUserCardData(BaseManagerToUserCard baseManagerToUserCard) {
|
BaseManagerToUserCard managerToUserCard = null;
|
Map<String, List<byte[]>> map = new HashMap<>();
|
MifareClassic mfc = MifareClassic.get(tag);
|
if (null != mfc) {
|
try {
|
// 建立NFC连接
|
mfc.connect();
|
// 获取扇区数量
|
int count = mfc.getSectorCount();
|
// 存储空间大小
|
int size = mfc.getSize();
|
// 用于判断是否有内容读取出来
|
boolean flag = false;
|
List<byte[]> list = new ArrayList<>();
|
|
// 验证扇区1的密码(先尝试默认密钥,再尝试公司密钥)
|
boolean isOpen = mfc.authenticateSectorWithKeyA(1, defauleKey);
|
if (!isOpen) {
|
isOpen = mfc.authenticateSectorWithKeyA(1, companyKey);
|
}
|
|
if (isOpen) {
|
// 获取扇区1里面块的数量
|
int bCount = mfc.getBlockCountInSector(1);
|
// 获取扇区1第一个块对应芯片存储器的位置
|
int bIndex = mfc.sectorToBlock(1);
|
|
// 读取扇区1内所有块的数据
|
for (int j = 0; j < bCount; j++) {
|
byte[] data = null;
|
try {
|
data = mfc.readBlock(bIndex);
|
bIndex++;
|
list.add(data);
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
}
|
flag = true;
|
}
|
|
if (flag) {
|
// 将读取的字节数据解析为管理卡对象
|
managerToUserCard = baseManagerToUserCard.getBean(list);
|
return managerToUserCard;
|
}
|
} catch (IOException e) {
|
e.printStackTrace();
|
} catch (Exception e) {
|
e.printStackTrace();
|
} finally {
|
try {
|
mfc.close(); // 确保连接被正确关闭
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
}
|
}
|
return null;
|
}
|
}
|