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文件中添加相应的权限:

使用<uses-permission>元素允许设备访问NFC硬件:

<uses-permission android:name="android.permission.NFC" />

使用<uses-sdk>元素设置最小SDK版本,下面是基于android 4.0环境,因此声明如下:

<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" />

下面这项不一定需要,如果你希望你的软件可以在android market中显示有NFC硬件,可以使用<uses-feature>元素声明:

<uses-feature android:name="android.hardware.nfc" android:required="true" />

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过滤器定义如下:

<intent-filter><action android:name="android.nfc.action.NDEF_DISCOVERED" /><category android:name="android.intent.category.DEFAULT" /><data android:mimeType="text/plain" />
</intent-filter>

下面是能够筛选URI为http://developer.android.com/index.html的ACTION_NDEF_DISCOVERED过滤器。

<intent-filter><action android:name="android.nfc.action.NDEF_DISCOVERED" /><category android:name="android.intent.category.DEFAULT" /><data android:mimeType="text/plain" />
</intent-filter>
<intent-filter><action android:name="android.nfc.action.NDEF_DISCOVERED" /><category android:name="android.intent.category.DEFAULT" /><data android:scheme="http" android:host="developer.android.com"android:pathPrefix="/index.html" />
</intent-filter>

2.ACTION_TECH_DISCOVERED过滤器定义如下:

<intent-filter><action android:name="android.nfc.action.TECH_DISCOVERED" />
</intent-filter><meta-dataandroid:name="android.nfc.action.TECH_DISCOVERED"android:resource="@xml/nfc_tech_filter" />

在res下新建xml文件夹然后新建一个nfc_tech_filter.xml文件,添加进你需要支持的标签类型。

<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"><!-- 可以处理所有Android支持的NFC类型 --><tech-list><tech>android.nfc.tech.IsoDep</tech></tech-list><tech-list><tech>android.nfc.tech.NfcA</tech></tech-list><tech-list><tech>android.nfc.tech.NfcB</tech></tech-list><tech-list><tech>android.nfc.tech.NfcF</tech></tech-list><tech-list><tech>android.nfc.tech.NfcV</tech></tech-list><tech-list><tech>android.nfc.tech.Ndef</tech></tech-list><tech-list><tech>android.nfc.tech.NdefFormatable</tech></tech-list><tech-list><tech>android.nfc.tech.MifareUltralight</tech></tech-list><tech-list><tech>android.nfc.tech.MifareClassic</tech></tech-list>
</resources>

不同数据标签类型什么意思:

MIFARE Classic数据格式就是NfcA,MIFARE DESFire数据格式是IsoDep就是各种交通卡像武汉通,羊城通,深圳通,北京市政交通卡,长安通,我们使用的二代身份证用的就是NfcB,Felica用的就是NfcF,德州仪器的VicinityCard卡用的是NfcV,而Android分享文件就是实用的Ndef格式传输数据。

3.ACTION_TAG_DISCOVERED过滤器定义如下:

<intent-filter><action android:name="android.nfc.action.TAG_DISCOVERED"/>
</intent-filter>

各类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) { <span style="white-space:pre">   </span><span style="white-space:pre">   </span>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";//这里只读取了其中几个pagebyte[] 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;@Overridepublic 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();}@Overrideprotected void onNewIntent(Intent intent) {super.onNewIntent(intent);// 当前app正在前端界面运行,这个时候有intent发送过来,那么系统就会调用onNewIntent回调方法,将intent传送过来// 我们只需要在这里检验这个intent是否是NFC相关的intent,如果是,就调用处理方法if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())) {processIntent(intent);}}@Overrideprotected void onResume() {super.onResume();nfcAdapter.enableForegroundDispatch(this, pi, null, null);}/*@Overrideprotected void onResume() {super.onResume();//得到是否检测到ACTION_TECH_DISCOVERED触发if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(getIntent().getAction())) {//处理该intentprocessIntent(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中的TAGTag 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;//读取TAGMifareClassic 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 appletbyte[] 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 Applicationbyte[] 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")@Overrideprotected 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 IntentpraseIntent(intent);}private void praseIntent(Intent intent) {String nfcAction = intent.getAction(); // 解析该Intent的Actionif (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);// 处理RecordLog.d("h_bl", "总消费记录" + Records);ArrayList<byte[]> ret = parseRecords(Records);List<String> 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();}}}}}@Overrideprotected void onPause() {if (nfcAdapter != null)nfcAdapter.disableForegroundDispatch(this);super.onPause();}@Overrideprotected void onResume() {super.onResume();nfcAdapter.enableForegroundDispatch(this, pendingIntent, filters, tenchlists);}@Overrideprotected 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); // Lereturn cmd_pse.array();}/*** 整条Records解析成ArrayList<byte[]>* * @param Records* @return*/private ArrayList<byte[]> parseRecords(byte[] Records) {int max = Records.length / 23;Log.d("h_bl", "消费记录有" + max + "条");ArrayList<byte[]> ret = new ArrayList<byte[]>();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<byte[]>记录分析List<String> 一条记录是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<String> parseRecordsToStrings(ArrayList<byte[]>... Records) {List<String> recordsList = new ArrayList<String>();for (ArrayList<byte[]> 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转化为intprivate 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 blocke.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) {}}

Android NFC标签读写 配置 过滤器总结 各类NFC数据类型NfcA NfcB IsoDep MifareClassic读取相关推荐

  1. Android开发——NFC标签读写

    Android开发----NFC标签读写 前言 最近因为项目需要,特意学习了NFC的Android开发.加上之前并没有系统地学习过Android开发知识,起手比较困难,搞了半天才算一知半解.怎么办呢? ...

  2. Android NFC 标签读写Demo与历史漏洞概述

    文章目录 前言 NFC基础 1.1 RFID区别 1.2 工作模式 1.3 日常应用 NFC标签 2.1 标签应用 2.2 应用实践 2.3 标签预览 2.4 前台调度 NFC开发 3.1 NDEF数 ...

  3. Android应用实例之----MifareUltralight格式的nfc标签读写

    随着支持nfc通信功能的智能手机更加普及,在移动支付及公交卡.诊疗卡读写等方面将会发挥更大的作用. 首先介绍Android NFC的工作流程: 步骤1:通过android.nfc.NfcAdapter ...

  4. 125KHZ|134.2KHZ低频RFID玻璃管标签读写器编码器支持各类标签类型说明

    125KHZ|134.2KHZ低频RFID玻璃管标签读写器编码器CK-A05是基于USB2.0技术开发的低频读写器,可支持对RFID地感标签的读写操作,同时支持EMID,FDX-B两种数据格式.读写器 ...

  5. android nfc标签类型,Android NFC标签 开发深度解析 触碰的艺术

    原标题:Android NFC标签 开发深度解析 触碰的艺术 本文来自于CSDN博客,作者:郭朝,已获授权,版权归原作者所有,未经作者同意,请勿转载. 欢迎同有博客好文章的作者加微信(ID:tm_fo ...

  6. Android NFC标签 开发深度解析 触碰的艺术

    这篇博客是在鸿洋的微信公众号看到的感觉收益非浅.于是转存于自己博客上以后可查阅. 本文由郭朝投稿. 郭朝的博客地址: http://blog.csdn.net/smartbetter 有几天没有更新博 ...

  7. 手机nfc_如何在Android中编写NFC标签

    手机nfc 这篇文章介绍了如何在Android中使用NFC编写智能标签. Android智能手机不仅能够读取包含URL,电话号码等数据的NFC标签,但使用Android NFC Api可以写入NFC标 ...

  8. 华为一碰传nfc标签_NFC标签?NFC碰碰贴?NFC一碰传?只要6块钱4个,嘿嘿~

    NFC标签?NFC碰碰贴?NFC一碰传?只要6块钱4个,嘿嘿~ 2020-08-17 23:00:00 758点赞 4970收藏 362评论 创作立场声明:本文所测商品为自费购入.如参加张大妈家的活动 ...

  9. 购买恩智浦的NFC标签NFC支付系统由中国RFID

    购买恩智浦的NFC标签NFC支付系统由中国RFID 作为(近场通信),恩智浦NFC标签已被广泛应用在NFC支付系统,中国RFID(射频识别日报)发布了最新的恩智浦NFC标签(NFC:近场通信),以帮助 ...

  10. Android基于nfc的读写(一)

    这里写自定义目录标题 Android的NFC读写(一) NFC简介 代码解析 源码(Demo) Android的NFC读写(一) 近来,因需求需要开发nfc读写功能,网上查阅了许多资料,发现相关方面资 ...

最新文章

  1. 函数重写 java_java 函数的重载和重写实例代码
  2. 字符串中统计单词个数
  3. C++ Primer 5th笔记(chap 15 OOP)访问控制与继承
  4. 计算机中减法英语,计算机中的减法运算
  5. python 值传递还是引用传递_python函数是值传递还是引用传递
  6. 用汇编写改进的冒泡排序
  7. 第三十三讲:tapestry表单组件详解之Label
  8. mysql close 出错_MySQL错误Forcing close of thread的两种解决方法
  9. 磁共振t1t2信号记忆顺口溜_10分钟记住脑出血核磁表现(一):T1、T2篇
  10. 服务器根没有web文件系统,Web服务器
  11. python 执行shellcode_简述获取shellcode的几种方式
  12. 使用JRebel进行Java Web项目的热部署
  13. 【分层图最短路】通信线路
  14. 如何使用Java以编程方式在Excel中创建数据透视表?
  15. 一、时间序列(1)资产收益率、随机过程、白噪声序列定义
  16. python控制步进电机代码tx2_步进电机按键控制.lst
  17. CoinBene 满币荣获「2020 年度最佳品牌增长」大奖 未来可期
  18. 高德地图我的队伍查岗_高德地图查岗新功能 让你的行踪无所遁形
  19. 机房计算机课提交作业,信息技术课机房上课规则
  20. 手把手教你搭建一个属于自己的网站

热门文章

  1. [MLDN魔乐科技]Oracle视频教程
  2. win8普通版连接远程桌面---RDPWrap
  3. Linux网络抓包分析工具(tcpdump、wireshark)
  4. DB9接口定义、232串口公头和母头的引脚定义接法
  5. html默认半透明遮罩层,css遮罩层 半透明
  6. 泛微OA-SQL注入漏洞
  7. 1、常用DOS命令大全
  8. 云教务学校管理系统源码
  9. php+分割文本文件,python实现:将文本文件分割成多个小文本文件(php也可实现)...
  10. NLPIR ICTCLAS2015分词系统的使用