|  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | 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.tools.HexUtil; | 
|---|
|  |  |  | import com.dayu.baselibrary.tools.nfc.NfcWriteAdapter; | 
|---|
|  |  |  | import com.dayu.qiheonlinelibrary.card.UserCard; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | import java.io.IOException; | 
|---|
|  |  |  | import java.util.ArrayList; | 
|---|
|  |  |  | import java.util.List; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * @author zx | 
|---|
|  |  |  | 
|---|
|  |  |  | * email 1058083107@qq.com | 
|---|
|  |  |  | * description | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | public class NFCWriteHelper extends BaseNFCHelper { | 
|---|
|  |  |  | public class NFCWriteHelper extends QHBaseNFCHelper { | 
|---|
|  |  |  |  | 
|---|
|  |  |  | private Tag tag; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | private static NFCWriteHelper helper; | 
|---|
|  |  |  | private static int PASSWORD_LENTH = 12; | 
|---|
|  |  |  | private NfcWriteAdapter adapter; | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public NFCWriteHelper(Intent intent, Activity activity) { | 
|---|
|  |  |  | super(activity); | 
|---|
|  |  |  | this.tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); | 
|---|
|  |  |  | adapter = new NfcWriteAdapter(intent, activity); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | 
|---|
|  |  |  | if (helper == null) { | 
|---|
|  |  |  | helper = new NFCWriteHelper(intent, activity); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return helper; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 设置NFC卡的读取密码 | 
|---|
|  |  |  | * | 
|---|
|  |  |  | * @param str | 
|---|
|  |  |  | * @return | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | public NFCWriteHelper setReadPassword(String str) { | 
|---|
|  |  |  | if (null != str && (str.length() <= PASSWORD_LENTH)) { | 
|---|
|  |  |  | for (int i = 0; i < str.length(); i++) { | 
|---|
|  |  |  | defauleKey[i] = (byte) str.charAt(i); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | helper.adapter.setIntent(intent); | 
|---|
|  |  |  | return helper; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | 
|---|
|  |  |  | * @param | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | public boolean writeUserData(UserCard userCard) { | 
|---|
|  |  |  | if (userCard != null) { | 
|---|
|  |  |  | int a = 1; | 
|---|
|  |  |  | try { | 
|---|
|  |  |  | MifareClassic mfc = MifareClassic.get(tag); | 
|---|
|  |  |  | List<byte[]> list = new ArrayList<>(); | 
|---|
|  |  |  | if (null != mfc) { | 
|---|
|  |  |  | try { | 
|---|
|  |  |  | //连接NFC | 
|---|
|  |  |  | mfc.connect(); | 
|---|
|  |  |  | //验证扇区密码 | 
|---|
|  |  |  | boolean isOpen = mfc.authenticateSectorWithKeyA(a, defauleKey); | 
|---|
|  |  |  | if (!isOpen) { | 
|---|
|  |  |  | isOpen = mfc.authenticateSectorWithKeyA(a, companyKey); | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | //写卡时修改所有密码 | 
|---|
|  |  |  | changePasword(a, mfc); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | 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); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | int bIndex = mfc.sectorToBlock(1); | 
|---|
|  |  |  | for (int j = 0; j < 3; j++) { | 
|---|
|  |  |  | //读取数据 | 
|---|
|  |  |  | byte[] data = null; | 
|---|
|  |  |  | try { | 
|---|
|  |  |  | data = mfc.readBlock(bIndex); | 
|---|
|  |  |  | bIndex++; | 
|---|
|  |  |  | list.add(data); | 
|---|
|  |  |  | } catch (Exception e) { | 
|---|
|  |  |  | e.printStackTrace(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if (userCard.equlsUserCard(list)) { | 
|---|
|  |  |  | return true; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | 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; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | try { | 
|---|
|  |  |  | return adapter.writeUserData(userCard,1); | 
|---|
|  |  |  | } catch (Exception e) { | 
|---|
|  |  |  | e.printStackTrace(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | 
|---|
|  |  |  | * @param | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | public boolean writeData(byte[] str, int a, int b) { | 
|---|
|  |  |  | Log.i("NFCWreatActivity", "writeData: a=" + a + " b=" + b); | 
|---|
|  |  |  | if (str.length <= 16) { | 
|---|
|  |  |  | try { | 
|---|
|  |  |  | MifareClassic mfc = MifareClassic.get(tag); | 
|---|
|  |  |  | if (null != mfc) { | 
|---|
|  |  |  | try { | 
|---|
|  |  |  | //连接NFC | 
|---|
|  |  |  | mfc.connect(); | 
|---|
|  |  |  | //获取扇区数量 | 
|---|
|  |  |  | int count = mfc.getSectorCount(); | 
|---|
|  |  |  | //如果传进来的扇区大了或者小了直接退出方法 | 
|---|
|  |  |  | if (a > count - 1 || a < 0) { | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | //获取写的扇区的块的数量 | 
|---|
|  |  |  | int bCount = mfc.getBlockCountInSector(a); | 
|---|
|  |  |  | //如果输入的块大了或者小了也是直接退出 | 
|---|
|  |  |  | if (b > bCount - 1 || b < 0) { | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | //验证扇区密码 | 
|---|
|  |  |  | boolean isOpen = mfc.authenticateSectorWithKeyA(a, defauleKey); | 
|---|
|  |  |  | if (!isOpen) { | 
|---|
|  |  |  | isOpen = mfc.authenticateSectorWithKeyA(a, companyKey); | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | //写卡时修改所有密码 | 
|---|
|  |  |  | changePasword(a, mfc); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if (isOpen) { | 
|---|
|  |  |  | int bIndex = mfc.sectorToBlock(a); | 
|---|
|  |  |  | //写卡 | 
|---|
|  |  |  | mfc.writeBlock(bIndex + b, str); | 
|---|
|  |  |  | 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; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | try { | 
|---|
|  |  |  | return adapter.writeData(str, a, b); | 
|---|
|  |  |  | } catch (Exception e) { | 
|---|
|  |  |  | e.printStackTrace(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | 
|---|
|  |  |  | *          //     * @param callback 返回监听 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | public boolean changePasword(int a, MifareClassic mfc) { | 
|---|
|  |  |  | //        MifareClassic mfc = MifareClassic.get(tag); | 
|---|
|  |  |  | byte[] data = new byte[16]; | 
|---|
|  |  |  | if (null != mfc) { | 
|---|
|  |  |  | try { | 
|---|
|  |  |  | //                mfc.connect(); | 
|---|
|  |  |  | //                int count = mfc.getSectorCount(); | 
|---|
|  |  |  | //                boolean isOpen = mfc.authenticateSectorWithKeyA(a, defauleKey); | 
|---|
|  |  |  | //                //验证是否是默认密码,当默认密码时修改密码 | 
|---|
|  |  |  | //                if (isOpen) { | 
|---|
|  |  |  | //将密码转换为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); | 
|---|
|  |  |  | //                    byte[] dataa = mfc.readBlock(bIndex + bCount - 1); | 
|---|
|  |  |  | //                    // 修改密码 A | 
|---|
|  |  |  | //                    mfc.writeBlock(mfc.sectorToBlock(a) + 3, dataA); | 
|---|
|  |  |  | //                    // 修改密码 B | 
|---|
|  |  |  | //                    mfc.writeBlock(mfc.sectorToBlock(a) + 7, dataB); | 
|---|
|  |  |  | //                } | 
|---|
|  |  |  | return true; | 
|---|
|  |  |  | } catch (Exception e) { | 
|---|
|  |  |  | e.printStackTrace(); | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | //                callback.isSusses(false); | 
|---|
|  |  |  | } finally { | 
|---|
|  |  |  | //                try { | 
|---|
|  |  |  | //                    mfc.close(); | 
|---|
|  |  |  | //                } catch (IOException e) { | 
|---|
|  |  |  | //                    e.printStackTrace(); | 
|---|
|  |  |  | //                } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | try { | 
|---|
|  |  |  | return adapter.changePasword(a, mfc); | 
|---|
|  |  |  | } catch (Exception e) { | 
|---|
|  |  |  | e.printStackTrace(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | 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 = mfc.authenticateSectorWithKeyA(sector, defauleKey); | 
|---|
|  |  |  | if (!isOpen) { | 
|---|
|  |  |  | isOpen = mfc.authenticateSectorWithKeyA(sector, companyKey2); | 
|---|
|  |  |  | if (isOpen) { | 
|---|
|  |  |  | mfc.authenticateSectorWithKeyB(sector, companyKey2); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if (!isOpen) { | 
|---|
|  |  |  | isOpen = mfc.authenticateSectorWithKeyA(sector, companyKey); | 
|---|
|  |  |  | if (isOpen) { | 
|---|
|  |  |  | mfc.authenticateSectorWithKeyB(sector, companyKey); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | 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(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return adapter.initCard(); | 
|---|
|  |  |  | } catch (Exception e) { | 
|---|
|  |  |  | e.printStackTrace(); | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 返回监听类 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | public interface NFCCallback { | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 返回是否成功 | 
|---|
|  |  |  | * | 
|---|
|  |  |  | * @param flag | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | void isSusses(boolean flag); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | } | 
|---|