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.BaseUserCardCard;
|
import com.dayu.baselibrary.tools.HexUtil;
|
import com.tencent.bugly.crashreport.CrashReport;
|
|
import java.io.IOException;
|
|
/**
|
* author: zuo
|
* Date: 2024-09-25
|
* Time: 11:26
|
* 备注:
|
*/
|
public class NativeNfcWriteHelper extends BaseNfcWriteHelper {
|
private Tag tag;
|
|
private static NativeNfcWriteHelper helper;
|
|
|
public void setIntent(Intent intent) {
|
this.tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
|
}
|
|
/**
|
* 单例初始化
|
*
|
* @param intent
|
* @return
|
*/
|
public static NativeNfcWriteHelper getInstence(Intent intent, Activity activity) {
|
if (helper == null) {
|
helper = new NativeNfcWriteHelper();
|
}
|
helper.setIntent(intent);
|
return helper;
|
}
|
|
|
/**
|
* 写卡
|
*
|
* @param userCard 用户卡内容
|
* @param
|
*/
|
@Override
|
public boolean writeUserData(BaseUserCardCard userCard, int sector) {
|
if (userCard != null) {
|
int a = sector;
|
try {
|
MifareClassic mfc = MifareClassic.get(tag);
|
if (null != mfc) {
|
try {
|
//连接NFC
|
mfc.connect();
|
//验证扇区密码
|
boolean isOpen = false;
|
for (int i = 0; i < listKeyA.size(); i++) {
|
if (mfc.authenticateSectorWithKeyA(a, listKeyA.get(i))) {
|
isOpen = true;
|
if (listKeyA.get(i).equals(defauleKey)) {
|
//当前为默认白卡密码时写卡时修改密码
|
changePasword(a, mfc);
|
}
|
break;
|
}
|
}
|
if (isOpen) {
|
for (int b = 0; b < 3; b++) {
|
byte[] data;
|
if (b == 0) {
|
data = userCard.getZeroBytes();
|
} else if (b == 1) {
|
data = userCard.getOneBytes();
|
} else {
|
data = userCard.getTwoBytes();
|
}
|
int bIndex = mfc.sectorToBlock(a);
|
//写卡
|
mfc.writeBlock(bIndex + b, data);
|
}
|
return true;
|
}
|
return false;
|
} catch (Exception e) {
|
e.printStackTrace();
|
return false;
|
} finally {
|
try {
|
mfc.close();
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
}
|
}
|
} catch (Exception e) {
|
e.printStackTrace();
|
return false;
|
}
|
}
|
return false;
|
}
|
|
|
/**
|
* 写卡
|
*
|
* @param str 书写内容,16个字节
|
* @param a 书写的扇区 (从0开始数)
|
* @param b 书写的块(从0开始数)
|
* @param
|
*/
|
@Override
|
public boolean writeData(byte[] str, int a, int b) {
|
return writeData(str, a, b, null);
|
}
|
|
@Override
|
public boolean writeData(byte[] str, int a, int b, NFCCallBack callBack) {
|
return writeData(str, a, b, true, null);
|
}
|
|
@Override
|
public boolean writeData(byte[] str, int a, int b, boolean isConnect, NFCCallBack callBack) {
|
Log.i("NFCWreatActivity", "writeData: a=" + a + " b=" + b);
|
if (str.length == 16) {
|
try {
|
MifareClassic mfc = MifareClassic.get(tag);
|
if (null != mfc) {
|
try {
|
//连接NFC
|
if (isConnect) {
|
mfc.connect();
|
}
|
//获取扇区数量
|
int count = mfc.getSectorCount();
|
//如果传进来的扇区大了或者小了直接退出方法
|
if (a > count - 1 || a < 0) {
|
if (callBack != null) {
|
callBack.isSusses(false, "扇区错误--" + a);
|
}
|
return false;
|
}
|
//获取写的扇区的块的数量
|
int bCount = mfc.getBlockCountInSector(a);
|
//如果输入的块大了或者小了也是直接退出
|
if (b > bCount - 1 || b < 0) {
|
if (callBack != null) {
|
callBack.isSusses(false, "块区错误--" + b);
|
}
|
return false;
|
}
|
//验证扇区密码
|
boolean isOpen = false;
|
if (listKeyA.size() != 0) {
|
for (int i = 0; i < listKeyA.size(); i++) {
|
if (mfc.authenticateSectorWithKeyA(0, listKeyA.get(i))) {
|
isOpen = true;
|
if (listKeyA.get(i).equals(defauleKey)) {
|
//当前为默认白卡密码时写卡时修改密码
|
changePasword(a, mfc);
|
}
|
break;
|
}
|
}
|
} else if (listA_PS.size() != 0 && listA_PS.size() > a) {
|
if (mfc.authenticateSectorWithKeyA(a, defauleKey)) {
|
isOpen = true;
|
|
} else if (mfc.authenticateSectorWithKeyA(a, listA_PS.get(a))) {
|
isOpen = true;
|
}
|
}
|
if (isOpen) {
|
int bIndex = mfc.sectorToBlock(a);
|
//写卡
|
mfc.writeBlock(bIndex + b, str);
|
// 校验写入数据是否正确
|
boolean isVerified = true;
|
// 读取数据验证
|
byte[] readResult = mfc.readBlock(bIndex + b);
|
if (readResult == null) {
|
if (callBack != null) {
|
callBack.isSusses(false, a + "扇区写卡时再次读取验证时失败");
|
}
|
return false;
|
}
|
for (int i = 0; i < str.length; i++) {
|
if (str[i] != readResult[i]) {
|
isVerified = false;
|
break;
|
}
|
}
|
if (isVerified) {
|
if (callBack != null) {
|
callBack.isSusses(true, "写入成功并验证通过");
|
}
|
return true;
|
|
} else {
|
if (callBack != null) {
|
callBack.isSusses(false, "写入验证失败");
|
}
|
return false;
|
}
|
}
|
if (callBack != null) {
|
callBack.isSusses(false, a + "扇区密码错误");
|
}
|
return false;
|
} catch (Exception e) {
|
e.printStackTrace();
|
if (callBack != null) {
|
callBack.isSusses(false, a + "扇区写卡报错" + e.getMessage());
|
|
}
|
return false;
|
} finally {
|
try {
|
mfc.close();
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
}
|
}
|
} catch (Exception e) {
|
e.printStackTrace();
|
if (callBack != null) {
|
callBack.isSusses(false, a + "扇区写卡报错" + e.getMessage());
|
}
|
return false;
|
}
|
} else {
|
if (callBack != null) {
|
callBack.isSusses(false, a + "扇区写卡报错,byte数组大小不为16");
|
}
|
}
|
return false;
|
}
|
|
|
/**
|
* 修改密码
|
*
|
* @param a 书写的扇区
|
* // * @param callback 返回监听
|
*/
|
@Override
|
public boolean changePasword(int a, MifareClassic mfc) {
|
|
byte[] data = new byte[16];
|
if (null != mfc) {
|
try {
|
//将密码转换为keyA
|
byte[] dataA = HexUtil.hexToByteArray(companyKeyA);
|
for (int i = 0; i < dataA.length; i++) {
|
data[i] = dataA[i];
|
}
|
//输入控制位
|
data[6] = (byte) 0xFF;
|
data[7] = (byte) 0x07;
|
data[8] = (byte) 0x80;
|
data[9] = (byte) 0x69;
|
byte[] dataB = HexUtil.hexToByteArray(companyKeyB);
|
//将密码转换为KeyB
|
for (int i = 0; i < dataB.length; i++) {
|
data[i + 10] = dataB[i];
|
}
|
int bIndex = mfc.sectorToBlock(a);
|
int bCount = mfc.getBlockCountInSector(a);
|
//写到扇区的最后一个块
|
mfc.writeBlock(bIndex + bCount - 1, data);
|
return true;
|
} catch (Exception e) {
|
e.printStackTrace();
|
return false;
|
}
|
}
|
return false;
|
}
|
|
|
public boolean changePasword(int a,byte[] passWord, MifareClassic mfc) {
|
try {
|
|
|
} catch (Exception e) {
|
e.printStackTrace();
|
CrashReport.postCatchedException(e);
|
}
|
return false;
|
}
|
|
/**
|
* 初始化卡
|
*
|
* @return
|
*/
|
@Override
|
public boolean initCard() {
|
try {
|
MifareClassic mfc = MifareClassic.get(tag);
|
if (null != mfc) {
|
try {
|
//连接NFC
|
mfc.connect();
|
//获取扇区数量
|
int count = mfc.getSectorCount();
|
byte[] data = new byte[16];
|
String initData = "FFFFFFFFFFFFFF078069FFFFFFFFFFFF";
|
byte[] initDataBytes = HexUtil.hexToByteArray(initData);
|
for (int sector = 0; sector < count; sector++) {
|
//验证扇区密码
|
boolean isOpen = false;
|
for (int i = 0; i < listKeyA.size(); i++) {
|
if (mfc.authenticateSectorWithKeyA(sector, listKeyA.get(i))) {
|
isOpen = true;
|
break;
|
}
|
}
|
if (isOpen) {
|
//获取写的扇区的块的数量
|
int blockCount = mfc.getBlockCountInSector(sector);
|
int blockIndex = mfc.sectorToBlock(sector);
|
for (int block = 0; block < blockCount; block++) {
|
// 跳过第 0 扇区的第 0 块
|
if (sector == 0 && block == 0) {
|
blockIndex++;
|
continue;
|
}
|
|
if (block < 3) {
|
mfc.writeBlock(blockIndex, data);
|
} else {
|
mfc.writeBlock(blockIndex, initDataBytes);
|
}
|
//写卡
|
blockIndex++;
|
}
|
}
|
}
|
return true;
|
} catch (Exception e) {
|
e.printStackTrace();
|
return false;
|
} finally {
|
try {
|
mfc.close();
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
}
|
}
|
} catch (Exception e) {
|
e.printStackTrace();
|
return false;
|
}
|
return false;
|
}
|
|
|
}
|