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 = 0;
    private int numBlock = 64;

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

    /**
     * 读取新卡的数据
     */
    public void readDataNSector() {
        executorService = Executors.newScheduledThreadPool(20);
        executorService.scheduleAtFixedRate(readOneBlockRunable, 20, 50, TimeUnit.MILLISECONDS);//50毫秒
    }

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

    }

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

                    break;
                case 0x87:
                    ToastUtils.show(AppContext.getInstance().getApplicationContext(),"数据读取失败,请重新刷卡");

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

            if (curretnBlock < 64) {

                sectorIndex = curretnBlock / 4;
                if (curretnBlock % 4 != 3) {
                    blockInde = curretnBlock % 4;//
                   //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, 3);//写密码块
                }
                curretnBlock++;
            } else {
                curretnBlock = 0;
                executorWriteService.shutdown();//关闭写
                handler.sendEmptyMessage(0x99);
            }
        }
    };
    private Runnable readOneBlockRunable = new Runnable() {
        @Override
        public void run() {
            if (curretnBlock < 64) {
                sectorIndex = curretnBlock / 4;
                if (curretnBlock % 4 != 3) {
                    blockInde = curretnBlock % 4;//
                    Log.e("sjt", "读取第" + sectorIndex + "扇区第" + blockInde + "块数据");
                    mhandle.readDataFromPool(sectorIndex, blockInde);
                }
                curretnBlock++;
            } else {
                curretnBlock = 0;
                executorService.shutdown();//关闭读
                handler.sendEmptyMessage(0x88);
            }
        }
    };


    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 = 0;
                executorService.shutdown();//关闭读
                handler.sendEmptyMessage(0x87);//读取失败
            }

        }
    };

    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", "写入失败!");
            }
        }
    };
}

猜你喜欢

转载自blog.csdn.net/u014624241/article/details/79679094