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;
|
|
/**
|
* author: zuo
|
* Date: 2024-09-25
|
* Time: 10:33
|
* 备注:原生读写卡方式
|
*/
|
public class NativeNfcReadHelper extends BaseNfcReadHelper {
|
private Tag tag;
|
// private NFCCallback callback;
|
private static NativeNfcReadHelper helper;
|
|
|
|
|
@Override
|
public void setIntent(Intent intent) {
|
this.tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
|
}
|
|
|
/**
|
* 单例初始化
|
*
|
* @param intent
|
* @return
|
*/
|
public static NativeNfcReadHelper getInstence(Intent intent, Activity activity) {
|
if (helper == null) {
|
helper = new NativeNfcReadHelper();
|
}
|
helper.setIntent(intent);
|
return helper;
|
}
|
|
/**
|
* 获取用户卡信息
|
*
|
* @return
|
*/
|
@Override
|
public BaseUserCardCard getUserCardData(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();
|
//获取扇区数量
|
int count = mfc.getSectorCount();
|
//存储空间
|
int size = mfc.getSize();
|
//用于判断时候有内容读取出来
|
boolean flag = false;
|
List<byte[]> list = new ArrayList<>();
|
//验证扇区密码,否则会报错(链接失败错误)
|
boolean isOpen = false;
|
for (int i = 0; i < listKeyA.size(); i++) {
|
if (mfc.authenticateSectorWithKeyA(1, listKeyA.get(i))) {
|
isOpen = true;
|
break;
|
}
|
}
|
if (isOpen) {
|
//获取扇区里面块的数量
|
int bCount = mfc.getBlockCountInSector(1);
|
//获取扇区第一个块对应芯片存储器的位置(我是这样理解的,因为第0扇区的这个值是4而不是0)
|
int bIndex = mfc.sectorToBlock(1);
|
//String data1 = "";
|
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;
|
}
|
|
|
@Override
|
public String getCradType() {
|
MifareClassic mfc = MifareClassic.get(tag);
|
if (null != mfc) {
|
try {
|
mfc.connect();
|
boolean isOpen = false;
|
for (int i = 0; i < listKeyA.size(); i++) {
|
if (mfc.authenticateSectorWithKeyA(1, listKeyA.get(i))) {
|
isOpen = true;
|
break;
|
}
|
}
|
if (isOpen) {
|
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;
|
} 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);
|
//获取扇区第一个块对应芯片存储器的位置(我是这样理解的,因为第0扇区的这个值是4而不是0)
|
int bIndex = mfc.sectorToBlock(i);
|
//String data1 = "";
|
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扇区信息
|
*
|
* @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<>();
|
//验证扇区密码,否则会报错(链接失败错误)
|
boolean isOpen = false;
|
for (int i = 0; i < listKeyA.size(); i++) {
|
if (mfc.authenticateSectorWithKeyA(1, listKeyA.get(i))) {
|
isOpen = true;
|
break;
|
}
|
}
|
if (isOpen) {
|
//获取扇区里面块的数量
|
int bCount = mfc.getBlockCountInSector(1);
|
//获取扇区第一个块对应芯片存储器的位置(我是这样理解的,因为第0扇区的这个值是4而不是0)
|
int bIndex = mfc.sectorToBlock(1);
|
//String data1 = "";
|
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 扇区
|
* @param b 块
|
* @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;
|
}
|
|
int type = mfc.getType();//获取TAG的类型
|
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();
|
}
|
|
|
@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()) {
|
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, defauleKey)) {
|
isOpen = true;
|
} else if (mfc.authenticateSectorWithKeyA(0, listA_PS.get(0))) {
|
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);
|
Log.i("NFCWreatActivity", "hex===" + hex);
|
return hex.toUpperCase();
|
}
|
}
|
|
} catch (IOException e) {
|
return BaseCommon.CARD_TYPE_ERROR1;
|
} finally {
|
try {
|
mfc.close();
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
}
|
}
|
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()) {
|
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, defauleKey)) {
|
isOpen = true;
|
} else if (mfc.authenticateSectorWithKeyA(0, listA_PS.get(0))) {
|
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);
|
Log.i("NFCWreatActivity", "hex===" + hex);
|
return hex.toUpperCase();
|
}
|
}
|
|
} catch (IOException e) {
|
Log.i("NFCWreatActivity", e.toString());
|
return BaseCommon.CARD_TYPE_ERROR1;
|
}
|
}
|
return "";
|
}
|
|
/**
|
* 获取卡片类型和卡号
|
*
|
* @return
|
*/
|
@Override
|
public String getCradTypeAndCardNumber() {
|
|
MifareClassic mfc = MifareClassic.get(tag);
|
if (null != mfc) {
|
try {
|
mfc.connect();
|
StringBuilder strData = new StringBuilder();
|
//获取当前卡号
|
boolean isOpen = false;
|
for (int i = 0; i < listKeyA.size(); i++) {
|
if (mfc.authenticateSectorWithKeyA(0, listKeyA.get(i))) {
|
isOpen = true;
|
break;
|
}
|
}
|
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);
|
}
|
}
|
//获取卡片类型
|
for (int i = 0; i < listKeyA.size(); i++) {
|
if (mfc.authenticateSectorWithKeyA(1, listKeyA.get(i))) {
|
isOpen = true;
|
break;
|
}
|
}
|
if (isOpen) {
|
int bIndex = mfc.sectorToBlock(1);
|
byte[] data = mfc.readBlock(bIndex + 0);
|
if (data != null && data.length > 0) {
|
String hex = HexUtil.byteToHex(data[0]);
|
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) {
|
return BaseCommon.CARD_TYPE_ERROR1;
|
} finally {
|
try {
|
mfc.close();
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
}
|
}
|
return "";
|
}
|
|
|
@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;
|
|
//验证扇区密码,否则会报错(链接失败错误)
|
boolean isOpen = false;
|
for (int i = 0; i < listKeyA.size(); i++) {
|
if (mfc.authenticateSectorWithKeyA(1, listKeyA.get(i))) {
|
isOpen = true;
|
break;
|
}
|
}
|
if (isOpen) {
|
//获取扇区里面块的数量
|
int bCount = mfc.getBlockCountInSector(1);
|
//获取扇区第一个块对应芯片存储器的位置(我是这样理解的,因为第0扇区的这个值是4而不是0)
|
int bIndex = mfc.sectorToBlock(1);
|
//String data1 = "";
|
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;
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
}
|
}
|
return null;
|
}
|
|
/**
|
* 获取用户卡信息
|
*
|
* @return
|
*/
|
@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<>();
|
//验证扇区密码,否则会报错(链接失败错误)
|
boolean isOpen = mfc.authenticateSectorWithKeyA(1, defauleKey);
|
if (!isOpen) {
|
isOpen = mfc.authenticateSectorWithKeyA(1, companyKey);
|
}
|
if (isOpen) {
|
//获取扇区里面块的数量
|
int bCount = mfc.getBlockCountInSector(1);
|
//获取扇区第一个块对应芯片存储器的位置(我是这样理解的,因为第0扇区的这个值是4而不是0)
|
int bIndex = mfc.sectorToBlock(1);
|
//String data1 = "";
|
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;
|
}
|
|
public boolean changePasword(int a, MifareClassic mfc) {
|
|
}
|
}
|