什麼手機支援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", "寫入失敗!");
}
}
};
}