什么手机支持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", "写入失败!");
}
}
};
}