天天看點

MIFARE CLASSIC 卡 M1卡 android NFC 子線程讀取 寫入

什麼手機支援MIFARE CLASSIC 卡(非接觸卡 )标簽,并不是所有手機都支援的;

具體見(稍等);

Android NFC 讀寫卡 掃盲貼,

見(稍等)

M1 卡讀寫原理,密碼校驗,控制字,控制位等,見文章:點選

讀寫

原來方法,讀取,每次都new 一個線程;這樣讀取64塊,時,就有64個子線程;相當的耗記憶體的;

于是改寫,想到了線程池;

注意比對,下面的2種寫與2種讀;

/**
     * 
     * @param sectorIndex : 扇區編号
     * @param blockInde   : 塊編号
     * @return
     */
    public void readData(int sectorIndex, int blockInde){
        new OnReadThread(sectorIndex, blockInde).start();
    }
    /**
     *
     * @param sectorIndex : 扇區編号
     * @param blockInde   : 塊編号
     * @return
     */
    public void readDataFromPool(int sectorIndex, int blockInde){
        onRead(sectorIndex,blockInde);
    }

    /**
     *
     * @param data 寫入的資料
     * @param sectorIndex 扇區編号
     * @param blockInde 塊編号
     */
    public void writeDataFromPool(byte[] data, int sectorIndex, int blockInde){
        onWrite(data,sectorIndex,blockInde);

    }
    /**
     * 向标簽中寫入資料
     */
    public void writeData(byte[] data, int sectorIndex, int blockInde){
        new OnWriteThread(data, sectorIndex, blockInde).start();

    }
           

讀取卡片,寫卡片,都是開啟的線程池;

發現直接用for循環,主線程來讀,也是很快的;不用加delay;

直接讀;

有的老手機,發現,用線程池,偶爾有些失敗,tag is lost;

特别注意:在寫資料時,必須要先寫資料塊,再寫密碼塊;

單獨寫密碼塊,不能将資料寫進;還報錯;

public class MifareIcCard {
    private ScheduledExecutorService executorService;
    private ScheduledExecutorService executorWriteService;
    private NfcTagHandle mhandle;
    private int sectorIndex;
    private int blockInde;
    private int curretnBlock = ;
    private int numBlock = ;

    public MifareIcCard(NfcTagHandle mhandle) {
        this.mhandle = mhandle;
        this.mhandle.setOnReadListener(onReadListener);
        this.mhandle.setOnWritedListener(onWriteListener);
    }

    /**
     * 讀取新卡的資料
     */
    public void readDataNSector() {
        executorService = Executors.newScheduledThreadPool();
        executorService.scheduleAtFixedRate(readOneBlockRunable, , , TimeUnit.MILLISECONDS);//50毫秒
    }

    /**
     * 初始化新卡
     */
    public void initCardFromNew() {
        executorWriteService = Executors.newScheduledThreadPool();
        executorWriteService.scheduleAtFixedRate(initCardRunable, , , TimeUnit.MILLISECONDS);

    }

 static    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case :
                    //初始化成功
                    ToastUtils.show(AppContext.getInstance().getApplicationContext(),"初始化成功");
                    break;
                case :
                    ToastUtils.show(AppContext.getInstance().getApplicationContext(),"資料全部讀出");

                    break;
                case :
                    ToastUtils.show(AppContext.getInstance().getApplicationContext(),"資料讀取失敗,請重新刷卡");

                    break;
            }
        }
    };
    private Runnable initCardRunable = new Runnable() {
        @Override
        public void run() {

            if (curretnBlock < ) {

                sectorIndex = curretnBlock / ;
                if (curretnBlock %  != ) {
                    blockInde = curretnBlock % ;//
                   //Log.e("sjt", "寫入資料塊 第" + sectorIndex + "扇區第" + blockInde + "塊資料");
                    mhandle.writeDataFromPool(Constant.init_block0_2, sectorIndex, blockInde);//寫資料塊
                } else {
                   // Log.e("sjt", "寫入秘鑰塊 第" + sectorIndex + "扇區第" + 3 + "塊資料");
                    mhandle.writeDataFromPool(Constant.init_block3, sectorIndex, );//寫密碼塊
                }
                curretnBlock++;
            } else {
                curretnBlock = ;
                executorWriteService.shutdown();//關閉寫
                handler.sendEmptyMessage();
            }
        }
    };
    private Runnable readOneBlockRunable = new Runnable() {
        @Override
        public void run() {
            if (curretnBlock < ) {
                sectorIndex = curretnBlock / ;
                if (curretnBlock %  != ) {
                    blockInde = curretnBlock % ;//
                    Log.e("sjt", "讀取第" + sectorIndex + "扇區第" + blockInde + "塊資料");
                    mhandle.readDataFromPool(sectorIndex, blockInde);
                }
                curretnBlock++;
            } else {
                curretnBlock = ;
                executorService.shutdown();//關閉讀
                handler.sendEmptyMessage();
            }
        }
    };


    private NfcTagHandle.OnReadListener onReadListener = new NfcTagHandle.OnReadListener()

    {
        public void onRead(boolean isRead, byte[] data, int sector, int block) {
            //讀取到的資料為
            if (isRead) {
               // final String str = "從扇區" + sector + "中的" + block + "塊資料區,讀取到資料:\n  長度: " + data.length + "位元組\n  HEX資料: ";
                final String str1 = bytesToHexString(data);
                Log.e("sjt", "讀取到的資料:" + str1);
//                    UserIc userIc = new UserIc(data, data, data);
//                    Log.e("sjt", "剩餘水量:" + userIc.getRemindWater() + "資料是否合法" + Util.checkData16IsLegal(data) + "剩餘電量" + userIc.getRemindEle());

             //   dataStr = dataStr + str + str1.substring(2);
//              new Thread() {
//                  public void run() {
//                      handler.post(runnableUi);
//                  }
//              }.start();
            } else {
                Log.e("sjt", "讀取失敗:");
                curretnBlock = ;
                executorService.shutdown();//關閉讀
                handler.sendEmptyMessage();//讀取失敗
            }

        }
    };

    private NfcTagHandle.OnWritedListener onWriteListener = new NfcTagHandle.OnWritedListener() {
        @Override
        public void onWrited(boolean isWrite, byte[] data, int sector, int block) {
            if (isWrite) {
                Log.e("sjt", "寫入成功!");

            } else {
                Log.e("sjt", "寫入失敗!");
            }
        }
    };
}
           

繼續閱讀