实例介绍
【实例简介】
手机NFC读卡器。
支持M1卡和CPU卡。
【核心代码】
package com.xdym;
import android.app.PendingIntent;
import android.content.IntentFilter;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
import android.app.AlertDialog;
import android.content.DialogInterface;
import java.io.IOException;
import java.util.ArrayList;
import android.widget.ArrayAdapter;
import android.content.Intent;
import com.xdym.constant.Command;
import com.xdym.mifare.MifareBlock;
import com.xdym.mifare.MifareClassCard;
import com.xdym.mifare.MifareSector;
import com.xdym.util.Converter;
import com.xdym.R;
import android.content.IntentFilter.MalformedMimeTypeException;
// NFC 需要的包
import android.nfc.NfcAdapter;
import android.nfc.Tag;
// ISO标准
import android.nfc.tech.IsoDep;
// Mifare 卡
import android.nfc.tech.MifareClassic;
// Type A 卡
import android.nfc.tech.NfcA;
public class MainActivity extends AppCompatActivity {
private static final String LOG_TAG = MainActivity.class.getSimpleName();
//---------控件定义------------
Button btnSelectMF;
Button btnGetRand;
ListView listView;
Button btnReadCardSN;
Button btnCardSAK;
Button btnTechList;
Button btnReadMifareCard;
// NFC parts
private static NfcAdapter nfcAdapter;
private static PendingIntent mPendingIntent;
private static IntentFilter[] mFilters;
private static String[][] mTechLists;
private Intent mIntent = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//----------------控件---------------------
btnSelectMF = (Button) findViewById(R.id.btnSelectMF);
btnReadCardSN = (Button) findViewById(R.id.btnReadCardSN);
btnCardSAK = (Button) findViewById(R.id.btnCardSAK);
btnTechList = (Button) findViewById(R.id.btnTechList);
btnGetRand = (Button) findViewById(R.id.btnGetRand);
btnReadMifareCard = (Button) findViewById(R.id.btnReadMifareCard);
listView = (ListView) findViewById(R.id.listview_msg);
/*Button sendSms = (Button) findViewById(R.id.btnSendSms);
sendSms.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
Uri uri = Uri.parse("smsto:" "10086");
intent.setAction(Intent.ACTION_SENDTO);
intent.setData(uri);
intent.putExtra(Intent.EXTRA_TEXT,"充话费100");
startActivity(intent);
}
});*/
//-------------事件绑定---------------
btnSelectMF.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
SelectMF();
}
});
btnGetRand.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
GetRand();
}
});
btnReadCardSN.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
ReadCardSN();
}
});
btnCardSAK.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
CardSAK();
}
});
btnTechList.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
TechList();
}
});
btnReadMifareCard.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
ReadMifareCard();
}
});
nfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (nfcAdapter == null) {
Log.d("h_bl", "设备不支持NFC!");
Toast.makeText(getApplicationContext(), "设备不支持NFC!", Toast.LENGTH_SHORT).show();
return;
}
if (!nfcAdapter.isEnabled()) {
Toast.makeText(getApplicationContext(), "请在系统设置中先启用NFC功能!", Toast.LENGTH_SHORT).show();
Log.d("h_bl", "请在系统设置中先启用NFC功能!");
}
mPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this,
getClass()), 0);
IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED);
try {
ndef.addDataType("*/*");
} catch (MalformedMimeTypeException e) {
throw new RuntimeException("fail", e);
}
mFilters = new IntentFilter[]{ndef};
//设置
mTechLists = new String[][]{new String[]{IsoDep.class
.getName()}, new String[]{MifareClassic.class.getName()}};//MifareClassic
mIntent = this.getIntent();
}
@Override
protected void onStart() {
super.onStart();
String [] a = {"调用了onStart"};
listView.setAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, a));
}
/**
* 读M1卡
*/
private void ReadMifareCard() {
String action = mIntent.getAction();
if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)) {//当前的action
Tag tag = mIntent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
MifareClassic mifareClassic = MifareClassic.get(tag);
if(mifareClassic == null){
showAlert("不是Mifare卡");
return;
}
MifareClassCard mifareClassCard=null;
try {
mifareClassic.connect();
boolean auth = false;
// 5.2) and get the number of sectors this card has..and loop
// thru these sectors
// 取扇区个数,循环读取
int secCount = mifareClassic.getSectorCount();
mifareClassCard= new MifareClassCard(secCount);
int bCount = 0;
int bIndex = 0;
for (int j = 0; j < secCount; j ) {
MifareSector mifareSector = new MifareSector();
mifareSector.sectorIndex = j;
// 6.1) authenticate the sector
// 认证扇区
auth = mifareClassic.authenticateSectorWithKeyA(j,
MifareClassic.KEY_DEFAULT);
mifareSector.authorized = auth;
if (auth) {
// 6.2) In each sector - get the block count
// 取块个数
bCount = mifareClassic.getBlockCountInSector(j);
bCount =Math.min(bCount, MifareSector.BLOCKCOUNT);
// 扇区转块
bIndex = mifareClassic.sectorToBlock(j);
for (int i = 0; i < bCount; i ) {
// 6.3) Read the block
// 读取块
byte []data = mifareClassic.readBlock(bIndex);
MifareBlock mifareBlock = new MifareBlock(data);
mifareBlock.blockIndex = bIndex;
// 7) Convert the data into a string from Hex
// format.
bIndex ;
mifareSector.blocks[i] = mifareBlock;
}
mifareClassCard.setSector(mifareSector.sectorIndex,
mifareSector);
} else { // Authentication failed - Handle it
}
}
ArrayList<String> blockData = new ArrayList<String>();
int blockIndex=0;
for(int i=0;i<secCount;i ){
MifareSector mifareSector=mifareClassCard.getSector(i);
for(int j=0;j<MifareSector.BLOCKCOUNT;j ){
MifareBlock mifareBlock=mifareSector.blocks[j];
byte []data=mifareBlock.getData();
blockData.add("Block " blockIndex " : " Converter.getHexString(data, data.length));
}
}
//---------------------显示输出---------------------
String[] contents = new String[blockData.size()];
blockData.toArray(contents);
listView.setAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, contents));
mifareClassic.close();
} catch (IOException e) {
// Log.e(TAG, e.getLocalizedMessage());
//showAlert(3);
}
} else {
showAlert("没有找到卡片 00");
}
}
/**
* 选择MF
*/
private void SelectMF() {
String action = mIntent.getAction();
if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)) {
Tag tagFromIntent = mIntent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
IsoDep isoDep = IsoDep.get(tagFromIntent);
if(isoDep == null){
showAlert("不是CPU卡");
return;
}
try {
//连接卡片
isoDep.connect();
ArrayList<String> blockData = new ArrayList<String>();
byte[] sendData = null;
byte[] recvB = null;
String send = "";
String recv = "";
send = Command.SELECT_MF.getCommand();
sendData = Converter.hexStringToByte(send);
recvB = isoDep.transceive(sendData);
recv = Converter.getHexString(recvB, recvB.length);
blockData.add(send);
blockData.add(">" recv);
//断开卡片
isoDep.close();
//---------------------显示输出---------------------
String[] contents = new String[blockData.size()];
blockData.toArray(contents);
listView.setAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, contents));
} catch (IOException e) {
// Log.e(TAG, e.getLocalizedMessage());
//showAlert(3);
}
} else {
showAlert("没有找到卡片 00");
}
}
/**
* 取随机数
*/
private void GetRand() {
String action = mIntent.getAction();
if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)) {//当前的action
Tag tag = mIntent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
IsoDep isoDep = IsoDep.get(tag);
if(isoDep == null){
showAlert("不是CPU卡");
return;
}
try {
isoDep.connect();
if (isoDep.isConnected() == false) {
Log.i(LOG_TAG,"连接卡片失败");
showAlert("连接卡片失败");
return;
}
byte[] sendData = null;
byte[] recvB = null;
String send = "";
String recv = "";
//随机数指令
send = Command.RANDOM.getCommand();
sendData = Converter.hexStringToByte(send);
Log.i(LOG_TAG,"发送随机数指令:" send);
recvB = isoDep.transceive(sendData);
if (recvB == null){
Log.i(LOG_TAG,"指令错误:" send);
showAlert("指令错误");
}
recv = Converter.getHexString(recvB, recvB.length);
Log.i(LOG_TAG,"返回数据(16进制):" recv);
ArrayList<String> blockData = new ArrayList<String>();
blockData.add(send);
blockData.add(">" recv);
//---------------------显示输出---------------------
String[] contents = new String[blockData.size()];
blockData.toArray(contents);
listView.setAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, contents));
isoDep.close();
} catch (IOException e) {
// Log.e(TAG, e.getLocalizedMessage());
//showAlert(3);
}
} else {
showAlert("没有找到卡片 00");
}
}
/**
* 读卡唯一号
*/
private void ReadCardSN() {
String action = mIntent.getAction();
Tag tag = mIntent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)) {//当前的action
IsoDep isoDep = IsoDep.get(tag);
if(isoDep == null){
showAlert("不是CPU卡");
return;
}
String send = null;
String recv = null;
try {
isoDep.connect();
if (isoDep.isConnected() == false) {
Log.i(LOG_TAG,"连接卡片失败");
showAlert("连接卡片失败");
return;
}
byte[] sendData = null;
byte[] recvB = null;
send = "";
recv = "";
//卡号指令
send = Command.CARD_ID.getCommand();
sendData = Converter.hexStringToByte(send);
Log.i(LOG_TAG,"发送读卡唯一号指令:" send);
recvB = isoDep.transceive(sendData);
if (recvB == null){
Log.i(LOG_TAG,"指令错误:" send);
showAlert("指令错误");
}
recv = Converter.getHexString(recvB, recvB.length);
Log.i(LOG_TAG,"返回数据(16进制):" recv);
ArrayList<String> blockData = new ArrayList<String>();
blockData.add("读卡唯一号指令:" send);
blockData.add(">" recv);
/*byte[] bytCardSN = tag.getId();
String strCardSN = Converter.getHexString(bytCardSN, bytCardSN.length);
ArrayList<String> blockData = new ArrayList<String>();
blockData.add("读卡唯一号");
blockData.add(">" strCardSN);*/
//---------------------显示输出---------------------
String[] contents = new String[blockData.size()];
blockData.toArray(contents);
listView.setAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, contents));
isoDep.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
} else {
showAlert("没有找到卡片 00");
}
}
/**
* 支持的协议
*/
private void TechList() {
String action = mIntent.getAction();
ArrayList<String> blockData = new ArrayList<String>();
if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)) {//当前的action
Tag tag = mIntent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
String[] arTeachList = tag.getTechList();
blockData.add("支持的协议");
for (int i = 0; i < arTeachList.length; i ) {
String strTeach = arTeachList[i];
blockData.add(">" strTeach);
}
//---------------------显示输出---------------------
String[] contents = new String[blockData.size()];
blockData.toArray(contents);
listView.setAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, contents));
} else {
showAlert("没有找到卡片 00");
}
}
/**
* 读卡SAK
*/
private void CardSAK() {
String action = mIntent.getAction();
if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)) {//当前的action
Tag tag = mIntent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
NfcA nfcA = NfcA.get(tag);
byte[] bytAtqa = nfcA.getAtqa();
short Sak = nfcA.getSak();
int maxTranLen = nfcA.getMaxTransceiveLength();
String strAtqa = Converter.getHexString(bytAtqa, bytAtqa.length);
String strSAK = String.format("%02X", Sak);
String strCardType;
if (Sak == 0x08){
strCardType = "M1卡";
}else if(Sak == 0x20){
strCardType = "CPU卡";
}else if(Sak == 0x28 || Sak == 0x38){
strCardType = "复合卡";
}else{
strCardType = "未知类型";
}
ArrayList<String> blockData = new ArrayList<String>();
blockData.add("ATQA");
blockData.add(">" strAtqa);
blockData.add("SAK");
blockData.add(">" strSAK " " strCardType);
blockData.add("最大传输长度");
blockData.add(">" maxTranLen);
//---------------------显示输出---------------------
String[] contents = new String[blockData.size()];
blockData.toArray(contents);
listView.setAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, contents));
} else {
showAlert("没有找到卡片 00");
}
}
/**
* 显示对话框
*
* @param alertCase
*/
private void showAlert(String alertCase) {
// prepare the alert box
AlertDialog.Builder alertbox = new AlertDialog.Builder(this);
alertbox.setMessage(alertCase);
// set a positive/yes button and create a listener
alertbox.setPositiveButton("关闭", new DialogInterface.OnClickListener() {
// Save the data from the UI to the database - already done
public void onClick(DialogInterface arg0, int arg1) {
//clearFields();
}
});
// display box
alertbox.show();
}
@Override
public void onResume() {
super.onResume();
//-----------------非常关键,必要的哦,不能删除----------------
nfcAdapter.enableForegroundDispatch(this, mPendingIntent, mFilters,
mTechLists);
}
@Override
public void onNewIntent(Intent intent) {
Log.i("Foreground dispatch", "Discovered tag with intent: " intent);
//resolveIntent(intent);
// mText.setText("Discovered tag " mCount " with intent: "
// intent);
mIntent = intent;
}
}
好例子网口号:伸出你的我的手 — 分享!
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明


网友评论
我要评论