NFC简介
NFC,即Near Field Communication,近距离无线通讯技术,是一种短距离的(通常<=4cm或更短)高频(13.56M Hz)无线通信技术,它提供了一种简单、触控式的解决方案,可以让消费者简单直观地交换信息、访问内容与服务。
NFC技术由非接触式射频识别(RFID)演变而来,由飞利浦半导体(现恩智浦半导体公司)、诺基亚和索尼共同研制开发,其基础是RFID及互连技术。近场通信(Near Field Communication,NFC)是一种短距高频的无线电技术,在单一芯片上结合感应式读卡器、感应式卡片和点对点的功能,能在13.56MHz频率运行于4厘米距离内,与兼容设备进行识别和数据交换。其传输速度有106 Kbit/秒、212 Kbit/秒或者424 Kbit/秒三种。目前近场通信已通过成为ISO/IEC IS 18092国际标准、ECMA-340标准与ETSI TS 102 190标准。现今这项技术在日韩被广泛应用。手机用户凭着配置了支付功能的手机就可以行遍全国:他们的手机可以用作机场登机验证、大厦的门禁钥匙、交通一卡通、信用卡、支付卡等等。
NFC标签的复杂度不一。简单的标签仅能够提供读写语义,有时编程域是一次性的,写完卡片就变成只读。更复杂一点的tag能够提供数学运算,拥有加密硬件保护区块的访问。最最复杂的tag包含操作环境,允许tag上执行的代码进行交互。我们还能够以各种格式来向tag中写入存储数据,但很多Android的API框架都是基于NFC论坛制定的NDEF标准。
AndroidManifest.xml
为了能够使用Android手机的NFC功能,需要在Manifest文件中添加相应的权限:
使用
使用
下面这项不一定需要,如果你希望你的软件可以在android market中显示有NFC硬件,可以使用
NFC数据过滤
NFC有三种过滤器分别是ACTION_NDEF_DISCOVERED,ACTION_TECH_DISCOVERED,ACTION_TAG_DISCOVERED。
1. ACTION_NDEF_DISCOVERED
当扫描到的tag中包含有NDEF载荷且为已知类型,该intent将用来启动Activity。该intent的优先级最高,tag分发系统总是先于其他intent用该intent来启动Activity。
2. ACTION_TECH_DISCOVERED
如果manifest中没有注册处理ACTION_NDEF_DISCOVERED类型的intent,该intent将被用以启动Activity。如果tag中没有包含可以映射到MIME或者URI类型的数据,或者虽然没有包含NDEF数据,但是已知的tag技术,则该intent也会被直接启用。
3. ACTION_TAG_DISCOVERED
如果以上两个intent都没人疼,那么该intent就会启动。
过滤器的作用是过滤掉杂质,剩下的就是我们需要的了。这三种过滤方式可同时配置,可以比方成从上到下三层,只要是符合某一层过滤器要求的,过滤完就停止往下一层。
NFC TAG的发布系统:
当android设备扫描到一个NFC标签时,会自动寻找最适合的Activity来处理这个TAG,如果有多个Activity满足条件的话,会让用户来选择到底使用哪一个Activity来处理,可以理解为就是简单的事件响应与事件处理。
那么如何让一个Activity监听 ”当扫描到NFC标签时” 的这一个事件呢?使用intent-filter。
可以理解为当检测到一个NFC标签时系统自动创建一个相关Intent对象,含有响应intent-filter的Activity将处理这个Intent。
1.ACTION_NDEF_DISCOVERED过滤器定义如下:
下面是能够筛选URI为http://developer.android.com/index.html的ACTION_NDEF_DISCOVERED过滤器。
2.ACTION_TECH_DISCOVERED过滤器定义如下:
在res下新建xml文件夹然后新建一个nfc_tech_filter.xml文件,添加进你需要支持的标签类型。
android.nfc.tech.IsoDep
android.nfc.tech.NfcA
android.nfc.tech.NfcB
android.nfc.tech.NfcF
android.nfc.tech.NfcV
android.nfc.tech.Ndef
android.nfc.tech.NdefFormatable
android.nfc.tech.MifareUltralight
android.nfc.tech.MifareClassic
不同数据标签类型什么意思:
MIFARE Classic数据格式就是NfcA,MIFARE DESFire数据格式是IsoDep就是各种交通卡像武汉通,羊城通,深圳通,北京市政交通卡,长安通,我们使用的二代身份证用的就是NfcB,Felica用的就是NfcF,德州仪器的VicinityCard卡用的是NfcV,而Android分享文件就是实用的Ndef格式传输数据。
3.ACTION_TAG_DISCOVERED过滤器定义如下:
各类NFC数据读取
1.NDEF格式数据读取
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_write);
nfcTView=(TextView)findViewById(R.id.info_tv);
nfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (nfcAdapter == null) {
nfcTView.setText("设备不支持NFC!");
inish();
return;
}
if (nfcAdapter!=null&&!nfcAdapter.isEnabled()) {
nfcTView.setText("请在系统设置中先启用NFC功能!");
finish();
return;
}
}
@Override
protected void onResume() {
super.onResume();
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
readFromTag(getIntent());
}
}
//读取内容:
private boolean readFromTag(Intent intent){
Parcelable[] rawArray = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
NdefMessage mNdefMsg = (NdefMessage)rawArray[0];
NdefRecord mNdefRecord = mNdefMsg.getRecords()[0];
try {
if(mNdefRecord != null){
readResult = new String(mNdefRecord.getPayload(),"UTF-8");
return true;
}
}
catch (UnsupportedEncodingException e) {
e.printStackTrace();
};
return false;
}
//写入内容
@Override
protected void onResume() {
super.onResume();
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
Tag tag=getIntent().getParcelableExtra(NfcAdapter.EXTRA_TAG);
Ndef ndef=Ndef.get(tag);
try {
ndef.connect();
NdefRecord ndefRecord=createTextRecord(data,Locale.US,true);
NdefRecord[] records={ndefRecord};
NdefMessage ndefMessage=new NdefMessage(records);
ndef.writeNdefMessage(ndefMessage);
} catch (IOException e1) {
e1.printStackTrace();
} catch (FormatException e) {
e.printStackTrace();
}
}
2.非NDEF数据MifareUltralight读取:
public String readTagUltralight(Tag tag) {
MifareUltralight mifare = MifareUltralight.get(tag);
try {
mifare.connect();
int size=mifare.PAGE_SIZE;
byte[] payload = mifare.readPages(0);
String result="page1:"+ByteArrayToHexString(payload)+"\n"+"总容量:"+String.valueOf(size)+"\n";
//这里只读取了其中几个page
byte[] payload1 = mifare.readPages(4);
byte[] payload2 = mifare.readPages(8);
byte[] payload3 = mifare.readPages(12);
result+="page4:"+ByteArrayToHexString(payload1)+"\npage8:"+ByteArrayToHexString(payload2)+"\npage12:"+ByteArrayToHexString(payload3)+"\n";
//byte[] payload4 = mifare.readPages(16);
//byte[] payload5 = mifare.readPages(20);
return result;
//+ new String(payload4, Charset.forName("US-ASCII"));
//+ new String(payload5, Charset.forName("US-ASCII"));
} catch (IOException e) {
Log.e(TAG, "IOException while writing MifareUltralight message...",
e);
return "读取失败!";
} catch (Exception ee) {
Log.e(TAG, "IOException while writing MifareUltralight message...",
ee);
return "读取失败!";
} finally {
if (mifare != null) {
try {
mifare.close();
} catch (IOException e) {
Log.e(TAG, "Error closing tag...", e);
}
}
}
}
3.非NDEF数据MifareClassic读取:
public class NFCActivity extends Activity {
NfcAdapter nfcAdapter;
TextView promt;
private PendingIntent pi;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.nfc_info);
promt = (TextView) findViewById(R.id.promt);
// 获取默认的NFC控制器
nfcAdapter = NfcAdapter.getDefaultAdapter(this);
pi = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
if (nfcAdapter == null) {
Toast.makeText(this, "对不起,您的设备不支持nfc功能!", Toast.LENGTH_SHORT).show();
//promt.setText("设备不支持NFC!");
finish();
return;
}
if (!nfcAdapter.isEnabled()) {
Toast.makeText(this, "请在系统设置中开启NFC功能!", Toast.LENGTH_SHORT).show();
//promt.setText("请在系统设置中先启用NFC功能!");
finish();
return;
}
}
public void btn_back(View view){
this.finish();
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
// 当前app正在前端界面运行,这个时候有intent发送过来,那么系统就会调用onNewIntent回调方法,将intent传送过来
// 我们只需要在这里检验这个intent是否是NFC相关的intent,如果是,就调用处理方法
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())) {
processIntent(intent);
}
}
@Override
protected void onResume() {
super.onResume();
nfcAdapter.enableForegroundDispatch(this, pi, null, null);
}
/*@Override
protected void onResume() {
super.onResume();
//得到是否检测到ACTION_TECH_DISCOVERED触发
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(getIntent().getAction())) {
//处理该intent
processIntent(getIntent());
}
}*/
//字符序列转换为16进制字符串
private String bytesToHexString(byte[] src) {
StringBuilder stringBuilder = new StringBuilder("0x");
if (src == null || src.length <= 0) {
return null;
}
char[] buffer = new char[2];
for (int i = 0; i < src.length; i++) {
buffer[0] = Character.forDigit((src[i] >>> 4) & 0x0F, 16);
buffer[1] = Character.forDigit(src[i] & 0x0F, 16);
System.out.println(buffer);
stringBuilder.append(buffer);
}
return stringBuilder.toString();
}
private String ByteArrayToHexString(byte[] inarray) {
int i, j, in;
String[] hex = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A",
"B", "C", "D", "E", "F" };
String out = "";
for (j = 0; j < inarray.length; ++j) {
in = (int) inarray[j] & 0xff;
i = (in >> 4) & 0x0f;
out += hex[i];
i = in & 0x0f;
out += hex[i];
}
return out;
}
/**
* Parses the NDEF Message from the intent and prints to the TextView
*/
private void processIntent(Intent intent) {
//取出封装在intent中的TAG
Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
String CardId =ByteArrayToHexString(tagFromIntent.getId());
String metaInfo = "";
metaInfo+="卡片ID:"+CardId;
for (String tech : tagFromIntent.getTechList()) {
System.out.println(tech);
}
boolean auth = false;
//读取TAG
MifareClassic mfc = MifareClassic.get(tagFromIntent);
try {
//Enable I/O operations to the tag from this TagTechnology object.
mfc.connect();
int type = mfc.getType();//获取TAG的类型
int sectorCount = mfc.getSectorCount();//获取TAG中包含的扇区数
String typeS = "";
switch (type) {
case MifareClassic.TYPE_CLASSIC:
typeS = "TYPE_CLASSIC";
break;
case MifareClassic.TYPE_PLUS:
typeS = "TYPE_PLUS";
break;
case MifareClassic.TYPE_PRO:
typeS = "TYPE_PRO";
break;
case MifareClassic.TYPE_UNKNOWN:
typeS = "TYPE_UNKNOWN";
break;
}
metaInfo += "\n卡片类型:" + typeS + "\n共" + sectorCount + "个扇区\n共"
+ mfc.getBlockCount() + "个块\n存储空间: " + mfc.getSize() + "B\n";
for (int j = 0; j < sectorCount; j++) {
//Authenticate a sector with key A.
auth = mfc.authenticateSectorWithKeyA(j,
MifareClassic.KEY_DEFAULT);
int bCount;
int bIndex;
if (auth) {
metaInfo += "Sector " + j + ":验证成功\n";
// 读取扇区中的块
bCount = mfc.getBlockCountInSector(j);
bIndex = mfc.sectorToBlock(j);
for (int i = 0; i < bCount; i++) {
byte[] data = mfc.readBlock(bIndex);
metaInfo += "Block " + bIndex + " : "
+ bytesToHexString(data) + "\n";
bIndex++;
}
} else {
metaInfo += "Sector " + j + ":验证失败\n";
}
}
promt.setText(metaInfo);
//Toast.makeText(this, metaInfo, Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
}
}
}
4.非NDEF数据IsoDep读取:
IsoDep isodep = IsoDep.get(tagFromIntent);
isodep.connect();
//select the card manager applet
byte[] mf = { (byte) '1', (byte) 'P',
(byte) 'A', (byte) 'Y', (byte) '.', (byte) 'S', (byte) 'Y',
(byte) 'S', (byte) '.', (byte) 'D', (byte) 'D', (byte) 'F',
(byte) '0', (byte) '1', };
String result="";
byte[] mfRsp = isodep.transceive(getSelectCommand(mf));
Log.d(TAG, "mfRsp:" + HexToString(mfRsp));
//select Main Application
byte[] wht = { (byte) 0x41, (byte) 0x50,
//此处以武汉通为例,其它的卡片参考对应的命令,网上可以查到
(byte) 0x31, (byte) 0x2E, (byte) 0x57, (byte) 0x48, (byte) 0x43,
(byte) 0x54, (byte) 0x43, };
byte[] sztRsp = isodep.transceive(getSelectCommand(wht));
byte[] balance = { (byte) 0x80, (byte) 0x5C, 0x00, 0x02, 0x04};
byte[] balanceRsp = isodep.transceive(balance);
Log.d(TAG, "balanceRsp:" + HexToString(balanceRsp));
if(balanceRsp!=null && balanceRsp.length>4)
{
int cash = byteToInt(balanceRsp, 4);
float ba = cash / 100.0f;
result+=" 余额:"+String.valueOf(ba);
}
setNoteBody(result);
isodep.close();
完整代码以厦门公交卡为例
package com.example.nfcdemo;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import android.support.v7.app.ActionBarActivity;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentFilter.MalformedMimeTypeException;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.IsoDep;
import android.nfc.tech.NfcF;
import android.nfc.tech.NfcV;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;
import com.example.nfcdemo2.R;
public class MainActivity extends ActionBarActivity {
private NfcAdapter nfcAdapter; // NFC适配器
// NFC前台调度系统
private PendingIntent pendingIntent = null;
private TextView show_msg; // 显示数据
protected final static byte TRANS_CSU = 6; // 如果等于0x06或者0x09,表示刷卡;否则是充值
protected final static byte TRANS_CSU_CPX = 9; // 如果等于0x06或者0x09,表示刷卡;否则是充值
public String[][] tenchlists;
public IntentFilter[] filters;
@SuppressWarnings("unchecked")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
show_msg = (TextView) findViewById(R.id.show_msg);
tenchlists = new String[][] { { IsoDep.class.getName() }, { NfcV.class.getName() }, { NfcF.class.getName() }, };
try {
filters = new IntentFilter[] { new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED, "*/*") };
} catch (MalformedMimeTypeException e1) {
e1.printStackTrace();
}
// 初始化PendingIntent,当有NFC设备连接上的时候,就交给当前Activity处理
pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
// 获取默认的NFC控制器,并进行判断
nfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (nfcAdapter == null) {
Log.d("h_bl", "设备不支持NFC!");
finish();
return;
}
if (!nfcAdapter.isEnabled()) {
Toast.makeText(getApplicationContext(), "请在系统设置中先启用NFC功能!", Toast.LENGTH_SHORT).show();
Log.d("h_bl", "请在系统设置中先启用NFC功能!");
return;
}
Intent intent = this.getIntent(); // 捕获NFC Intent
praseIntent(intent);
}
private void praseIntent(Intent intent) {
String nfcAction = intent.getAction(); // 解析该Intent的Action
if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(nfcAction)) {
Log.d("h_bl", "ACTION_TECH_DISCOVERED");
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); // 获取Tag标签,既可以处理相关信息
for (String tech : tag.getTechList()) {
Log.d("h_bl", "tech=" + tech);
}
IsoDep isoDep = IsoDep.get(tag);
String str = "";
try {
isoDep.connect(); // 连接
if (isoDep.isConnected()) {
Log.d("h_bl", "isoDep.isConnected"); // 判断是否连接上
// 1.select PSF (1PAY.SYS.DDF01)
// 选择支付系统文件,它的名字是1PAY.SYS.DDF01。
byte[] DFN_PSE = { (byte) '1', (byte) 'P', (byte) 'A', (byte) 'Y', (byte) '.', (byte) 'S', (byte) 'Y', (byte) 'S', (byte) '.', (byte) 'D', (byte) 'D', (byte) 'F', (byte) '0', (byte) '1', };
isoDep.transceive(getSelectCommand(DFN_PSE));
// 2.选择公交卡应用的名称
byte[] DFN_SRV = { (byte) 0xA0, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x86, (byte) 0x98, (byte) 0x07, (byte) 0x01, };
isoDep.transceive(getSelectCommand(DFN_SRV));
// 3.读取余额
byte[] ReadMoney = { (byte) 0x80, // CLA Class
(byte) 0x5C, // INS Instruction
(byte) 0x00, // P1 Parameter 1
(byte) 0x02, // P2 Parameter 2
(byte) 0x04, // Le
};
byte[] Money = isoDep.transceive(ReadMoney);
if (Money != null && Money.length > 4) {
int cash = byteToInt(Money, 4);
float ba = cash / 100.0f;
show_msg.setText("余额:" + ba);
}
// 4.读取所有交易记录
byte[] ReadRecord = { (byte) 0x00, // CLA Class
(byte) 0xB2, // INS Instruction
(byte) 0x01, // P1 Parameter 1
(byte) 0xC5, // P2 Parameter 2
(byte) 0x00, // Le
};
byte[] Records = isoDep.transceive(ReadRecord);
// 处理Record
Log.d("h_bl", "总消费记录" + Records);
ArrayList ret = parseRecords(Records);
List retList = parseRecordsToStrings(ret);
show_msg.append("\n" + "消费记录如下:");
for (String string : retList) {
Log.d("h_bl", "消费记录" + string);
show_msg.append("\n" + string);
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (isoDep != null) {
try {
isoDep.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
@Override
protected void onPause() {
if (nfcAdapter != null)
nfcAdapter.disableForegroundDispatch(this);
super.onPause();
}
@Override
protected void onResume() {
super.onResume();
nfcAdapter.enableForegroundDispatch(this, pendingIntent, filters, tenchlists);
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
// 当前app正在前端界面运行,这个时候有intent发送过来,那么系统就会调用onNewIntent回调方法,将intent传送过来
// 我们只需要在这里检验这个intent是否是NFC相关的intent,如果是,就调用处理方法
if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.getAction())) {
Log.d("h_bl", "onNewIntent");
praseIntent(intent);
}
}
public static byte byteToHex(byte arg) {
byte hex = 0;
if (arg >= 48 && arg <= 57) {
hex = (byte) (arg - 48);
} else if (arg >= 65 && arg <= 70) {
hex = (byte) (arg - 55);
} else if (arg >= 97 && arg <= 102) {
hex = (byte) (arg - 87);
}
return hex;
}
private byte[] getSelectCommand(byte[] aid) {
final ByteBuffer cmd_pse = ByteBuffer.allocate(aid.length + 6);
cmd_pse.put((byte) 0x00) // CLA Class
.put((byte) 0xA4) // INS Instruction
.put((byte) 0x04) // P1 Parameter 1
.put((byte) 0x00) // P2 Parameter 2
.put((byte) aid.length) // Lc
.put(aid).put((byte) 0x00); // Le
return cmd_pse.array();
}
/**
* 整条Records解析成ArrayList
*
* @param Records
* @return
*/
private ArrayList parseRecords(byte[] Records) {
int max = Records.length / 23;
Log.d("h_bl", "消费记录有" + max + "条");
ArrayList ret = new ArrayList();
for (int i = 0; i < max; i++) {
byte[] aRecord = new byte[23];
for (int j = 23 * i, k = 0; j < 23 * (i + 1); j++, k++) {
aRecord[k] = Records[j];
}
ret.add(aRecord);
}
for (byte[] bs : ret) {
Log.d("h_bl", "消费记录有byte[]" + bs); // 有数据。解析正确。
}
return ret;
}
/**
* ArrayList记录分析List 一条记录是23个字节byte[] data,对其解码如下
* data[0]-data[1]:index data[2]-data[4]:over,金额溢出??? data[5]-data[8]:交易金额
* ??代码应该是(5,4) data[9]:如果等于0x06或者0x09,表示刷卡;否则是充值
* data[10]-data[15]:刷卡机或充值机编号
* data[16]-data[22]:日期String.format("%02X%02X.%02X.%02X %02X:%02X:%02X"
* ,data[16], data[17], data[18], data[19], data[20], data[21], data[22]);
*
* @param logs
* @return
*/
private List parseRecordsToStrings(ArrayList... Records) {
List recordsList = new ArrayList();
for (ArrayList record : Records) {
if (record == null)
continue;
for (byte[] v : record) {
StringBuilder r = new StringBuilder();
int cash = Util.toInt(v, 5, 4);
char t = (v[9] == TRANS_CSU || v[9] == TRANS_CSU_CPX) ? '-' : '+';
r.append(String.format("%02X%02X.%02X.%02X %02X:%02X ", v[16], v[17], v[18], v[19], v[20], v[21], v[22]));
r.append(" " + t).append(Util.toAmountString(cash / 100.0f));
String aLog = r.toString();
recordsList.add(aLog);
}
}
return recordsList;
}
// byteArray转化为int
private int byteToInt(byte[] b, int n) {
int ret = 0;
for (int i = 0; i < n; i++) {
ret = ret << 8;
ret |= b[i] & 0x00FF;
}
if (ret > 100000 || ret < -100000)
ret -= 0x80000000;
return ret;
}
}
IsoDep主要用于读取各城市公交卡信息如:武汉通,羊城通,深圳通,北京市政交通卡,长安通。
深圳通:
byte[] DFN_SRV = { (byte) 'P', (byte) 'A', (byte) 'Y',
(byte) '.', (byte) 'S', (byte) 'Z', (byte) 'T' };
武汉通:
byte[] DFN_SRV = { (byte) 0x41, (byte) 0x50,
(byte) 0x31, (byte) 0x2E, (byte) 0x57, (byte) 0x48, (byte) 0x43,
(byte) 0x54, (byte) 0x43, };
羊城通:
byte[] DFN_SRV = { (byte) 'P', (byte) 'A', (byte) 'Y',
(byte) '.', (byte) 'A', (byte) 'P', (byte) 'P', (byte) 'Y', };
长安通:
byte[] DFN_SRV = { (byte) 0xA0, (byte) 0x00,
(byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x86, (byte) 0x98,
(byte) 0x07, (byte) 0x01, };
北京市政交通卡:
byte[] DFI_EP = { (byte) 0x10, (byte) 0x01 };
5.非NDEF数据NfcA读取:
NfcA nfca = NfcA.get(tagFromIntent);
try{
nfca.connect();
if (nfca.isConnected()) {//NTAG216的芯片
byte[] SELECT = {
(byte) 0x30,
(byte) 5 & 0x0ff,//0x05
};
byte[] response = nfca.transceive(SELECT);
nfca.close();
if(response!=null){
setNoteBody(new String(response, Charset.forName("utf-8")));
}
}
}
catch(Exception e){
}
6.非NDEF数据NfcB读取:
nfcbTag = NfcB.get(tag);
try {
nfcbTag.connect();
if (nfcbTag.isConnected()) {
System.out.println("已连接");
Toast.makeText(MainActivity.this, "身份证已连接",Toast.LENGTH_SHORT).show();
new CommandAsyncTask().execute();
}
// nfcbTag.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
7.非NDEF数据NfcF读取:
NfcF nfc = NfcF.get(tag);
try {
nfc.connect();
byte[] felicaIDm = new byte[]{0};
byte[] req = readWithoutEncryption(felicaIDm, 10);
byte[] res = nfc.transceive(req);
nfc.close();
setNoteBody(ByteArrayToHexString(res));
} catch (Exception e) {
Log.e(TAG, e.getMessage() , e);
}
8.非NDEF数据NfcV读取:
NfcV tech = NfcV.get(tag);
if (tech != null) {
try {
tech.connect();
if (tech.isConnected()) {
byte[] tagUid = tag.getId();
int blockAddress = 0;
int blocknum = 4;
byte[] cmd = new byte[] {
(byte)0x22, // FLAGS
(byte)0x23, // 20-READ_SINGLE_BLOCK,23-所有块
0, 0, 0, 0, 0, 0, 0,0,
(byte)(blockAddress & 0x0ff),(byte)(blocknum-1 & 0x0ff)
};
System.arraycopy(tagUid, 0, cmd, 2, tagUid.length);
byte[] response = tech.transceive(cmd);
tech.close();
if(response!=null){
setNoteBody(new String(response, Charset.forName("utf-8")));
}
}
} catch (IOException e) {
}
}