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; } }