您的位置:首页 > 移动开发 > Android开发

Android NFC的初次使用——公交卡信息读取

2017-05-18 09:49 816 查看
通过NFC的读模式,读取公交卡的余额和交易记录。这是一个开源的工程,可以读取深圳通、羊城通、北京卡、八达通、武汉通等等。1.首先要在AndroidManifest.xml中声明如下配置信息:使用<uses-permission>元素允许设备访问NFC硬件:<uses-permission android:name="android.permission.NFC" />  使用<uses-sdk>元素设置最小SDK版本,本人基于android 4.4环境,因此声明如下:
<uses-sdk android:minSdkVersion="10" android:targetSdkVersion="19" />
备注:API Level 9只通过ACTION_TAG_DISCOVERED来支持有限的标签调度,并且只能通过EXTRA_NDEF_MESSAGES来访问NDEF消息。没有其他的标签属性或I/O操作可用。API Level 10中包含了广泛的读写支持,从而更好的推动了NDEF的应用前景,并且API Leve 14用Android   Beam和额外的方便的创建NDEF记录的方法,向外提供了更容易的把NDEF消息推送给其他设备的方法。

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

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


2.NFC TAG的发布系统:

当android设备扫描到一个NFC标签时,会自动寻找最适合的Activity来处理这个TAG,如果有多个Activity满足条件的话,会让用户来选择到底使用哪一个Activity来处理,可以理解为就是简单的事件响应与事件处理。

那么如何让一个Activity监听 ”当扫描到NFC标签时” 的这一个事件呢?使用intent filter。

可以理解为当检测到一个NFC标签时,系统自动创建一个相关的Intent对象,含有响应intent filter的Activity将处理这个Intent。

其中,intent filter声明如下:(在AndroidManifest.xml中声明在你需要捕获这个Intent的Activity里)(如下是识别公交卡的TECH格式过滤标签):

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


在res文件夹下新建一个xml的文件夹,里面放的是Android支持的NFC类型的配置数据。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>


另外还有:

NDEF格式

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


有兴趣的同学可以看看Google官方的NFC介绍说明: https://developer.android.com/guide/topics/connectivity/nfc/nfc.html
到此你所写的activity就能通过刷一下公交卡被调起来了,剩下的是怎么读取卡内信息,读取部分相对麻烦,因为区分了多种模式卡的数据解析,在此不做详细说明,可参照最下方源码下载;
简单来说分四个步骤:

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', };

2.选择公交卡应用的名字或者ID
每个公交卡的名字都会不一样。
深圳通:
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, };
北京市政交通卡ID:
byte[] DFI_EP = { (byte) 0x10, (byte) 0x01 };

其他公交卡:

3.读取余额
发送命令读取电子钱包的余额:
final byte[] cmd = { (byte) 0x80, // CLA Class
(byte) 0x5C, // INS Instruction
(byte) 0x00, // P1 Parameter 1
(byte) 0x02, // P2 Parameter 2
(byte) 0x04, // Le
};
获取到的余额数据是byte[] data, 前4字节合并成int,再除以100(两个小数点),得到的结果就是余额。

4.读取交易记录
一次性读取命令,在不知道有多少条记录的时候,用这个命令:
byte[] cmd = { (byte) 0x00, // CLA Class
(byte) 0xB2, // INS Instruction
(byte) 0x01, // P1 Parameter 1
(byte) 0xC5, // P2 Parameter 2
(byte) 0x00, // Le
};
返回所有的记录byte[] data,每23个字节代表一条记录
也可以一条一条的读取:
cmd = { (byte) 0x00, // CLA Class
(byte) 0xB2, // INS Instruction
(byte) index, // P1 Parameter 1
(byte) 0xC4, // P2 Parameter 2
(byte) 0x00, // Le
};
一条记录是23个字节byte[] data,对其解码如下
data[0]-data[1]:index
data[2]-data[4]:over,金额溢出?
data[5]-data[8]:交易金额
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]);



源码下载地址

http://download.csdn.net/detail/bbenskye/9845382
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Android nfc 公交卡