NFC读写MifareClassic协议的NFC卡

news/2025/3/28 10:43:38/

IC卡 (Integrated Circuit Card,集成电路卡)

有些国家和地区也称智能卡(smart card)、智慧卡(intelligent card)、微电路卡(microcircuit card)或微芯片卡等。它是将一个微电子芯片嵌入符合ISO 7816标准的卡基中,做成卡片形式。所以非接触式IC卡又被称为射频卡或者电子标签IC卡是指集成电路卡,一般用的公交车卡就是IC卡的一种,也应用在门禁管理、身份证明和电子钱包。IC卡有别于磁卡,所以说IC卡消磁纯属伪科学!简单来说,其工作原理就是读卡器发射一个根据信息变化的电磁波。卡片内部的感应线圈把这个电磁波转换成感应电流,用以传递信息和驱动芯片工作。

射频识别即RFID(Radio Frequency IDentification)

又称电子标签、无线射频识别,是一种通信技术,可通过无线电讯号识别特定目标并读写相关数据,而无需识别系统与特定目标之间建立机械或光学接触。常用的有低频(125k~134.2K)、高频(13.56Mhz)、超高频,无源等技术。RFID读写器也分移动式的和固定式的,目前RFID技术应用很广,如:图书馆,门禁系统,食品安全溯源等。

NFC是Near Field Communication缩写,即近距离无线通讯技术。

由飞利浦公司和索尼公司共同开发的NFC是一种非接触式识别和互联技术,可以在移动设备、消费类电子产品、PC 和智能控件工具间进行近距离无线通信。NFC 提供了一种简单、触控式的解决方案,可以让消费者简单直观地交换信息、访问内容与服务。

以上介绍我们可以知道IC卡是一种存储数据的卡,而RFID是一种通讯技术,IC卡属于RFID的一种物理形式。NFC是由RFID演变出来的,向下兼容RFID,自然也兼容IC卡。

NFC是一套短距离的无线通信,通常距离是4厘米或更短。NFC工作频率是13.56M Hz,传输速率是106kbit/s 到848kbit/s. NFC总是在一个发起者和一个被动目标之间发生。发起者发出近场无线电波,这个近场可以给被动目标供电。这些被动的目标包括不需要电源的标签,卡,也可以是有电源的设备。

与其他无线通信技术比较, 例如蓝牙和WiFi, NFC提供更低贷款和距离,并且低成本,不需要供电,不需要实现匹配,整个通信过程仅仅是短短的靠近一秒就能完成。

一个带有NFC支持的android设备通常是一个发起者。也可以作为NFC的读写设备。他将检测NFC tags并且打开一个Activity来处理. Android 2.3.3还有支持有限的P2P。

Tags分很多种,其中简单的只提供读写段,有的只能读。复杂的tags可以支持一些运算,加密来控制对tags里数据段的读写。甚至一些tags上有简单的操作系统,允许一些复杂的交互和可以执行一些代码。

本文的代码例子是基于API10的。

要在Android手机中使用NFC,必须在AndroidManifest.xml中如下配置:

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

Tag发布系统

当android设备扫描到一个NFC tag,通用的行为是自动找最合适的Activity会处理这个tag Intent而不需要用户来选择哪个Activity来处理。因为设备扫描NFC tags是在很短的范围和时间,如果让用户选择的话,那就有可能需要移动设备,这样将会打断这个扫描过程。你应该开发你只处理需要处理的tags的Activity,以防止让用户选择使用哪个Activity来处理的情况。Android提供两个系统来帮助你正确的识别一个NFC tag是否是你的Activity想要处理的:Intent发布系统和前台Activity发布系统。

Intent发布系统检查所有Activities的intent filters,找出那些定义了可以处理此tag的Activity,如果有多个Activity都配置了处理同一个tag Intent,那么将使用Activity选择器来让用户选择使用哪个Activity。用户选择之后,将使用选择的Activity来处理此Intent.

前台发布系统允许一个Activity覆盖掉Intent发布系统而首先处理此tag Intent,这要求你将要处理Tag Intent的Activity运行在前台,这样当一个NFC tag被扫描到,系统先检测前台的Activity是否支持处理此Intent,如果支持,即将此Intent传给此Activity,如果不支持,则转到Intent发布系统。

以前台前台发布系统为例,需要编写如下代码:

1. 定义变量

private NfcAdapter mAdapter;private String[][] techList;private IntentFilter[] intentFilters;private PendingIntent pendingIntent;private Tag tag;

2. 添加下列代码到Activity的onCreate() 方法里:

复制代码
//获取nfc适配器mAdapter = NfcAdapter.getDefaultAdapter(this);//定义程序可以兼容的nfc协议,例子为nfca和nfcv//在Intent filters里声明你想要处理的Intent,一个tag被检测到时先检查前台发布系统,//如果前台Activity符合Intent filter的要求,那么前台的Activity的将处理此Intent。//如果不符合,前台发布系统将Intent转到Intent发布系统。如果指定了null的Intent filters,//当任意tag被检测到时,你将收到TAG_DISCOVERED intent。因此请注意你应该只处理你想要的Intent。techList = new String[][] {new String[] { android.nfc.tech.NfcV.class.getName() },new String[] { android.nfc.tech.NfcA.class.getName() } };intentFilters = new IntentFilter[] { new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED), };//创建一个 PendingIntent 对象, 这样Android系统就能在一个tag被检测到时定位到这个对象pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this,getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
复制代码

3. 在onNewIntent方法中:

    public void onNewIntent(Intent intent) {tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);return;}

4. 在OnPause方法中:

    @Overrideprotected void onPause() {super.onPause();mAdapter.disableForegroundDispatch(this);}

4. 在OnResume方法中:

复制代码
@Overrideprotected void onResume() {super.onResume();//使用前台发布系统mAdapter.enableForegroundDispatch(this, pendingIntent, intentFilters,techList);}}
复制代码

定义了这些方法以后,运行程序,在不锁屏的情况下,使用NFCV或NFCA的NFC卡靠近的手机的时候OnNewIntent就会被触发。Tag就可以被获取到,可以使用获取到的TAG来查询该卡的一些详细信息和数据。


http://www.cnblogs.com/haoxinyue/archive/2012/05/03/2479599.html


先了解一下MifareClassic协议

在android sdk 的文档中,描述道 “all MifareClassic I/O operations will be supported, andMIFARE_CLASSIC NDEF tags will also be supported. In either case,NfcA will also be enumerated on the tag, because all MIFARE Classic tags are alsoNfcA.” 所以说NFCA协议是兼容MifareClassic 协议的, 我们可以通过NfcA在android的相关类来处理给予MifareClassic 的RFID卡。

一般来说,给予MifareClassic的射频卡,一般内存大小有3种:

1K: 16个分区(sector),每个分区4个块(block),每个块(block) 16个byte数据

2K: 32个分区,每个分区4个块(block),每个块(block) 16个byte数据

4K:64个分区,每个分区4个块(block),每个块(block) 16个byte数据

对于所有基于MifareClassic的卡来说,每个区最后一个块叫Trailer,16个byte, 主要来存放读写该区的key,可以有A,B两个KEY,每个key长6byte,默认的key一般是FF 或 0,最后一个块的内存结构如下:

Block 0 Data 16bytes
Block 1 Data 16 bytes
Block 2 Data 16 bytes
Block 3 Trailer 16 bytes
Trailer:
Key A: 6 bytes
Access Conditions: 4 bytes
Key B: 6 bytes
所以在写卡的内存的时候,一般不能写每个sector的最后一个block,除非你有要修改KEY和访问权限的需求。如果KEY A 被你不小心修改掉了,而你不知道修改成什么,那与之对应的那个sector你就没有办法访问了。因为在MifareClassic中,如果你要读取数据,那么必须要有这个数据地址所在的sector的权限,这个权限就是这个sector的trailer的keyA或KEY B。
读数据的例子:
复制代码
//tag 就是在上一篇中onNewIntent中获取的tag
MifareClassic mc = MifareClassic.get(tag);short startAddress = 0;short endAddress = 5;byte[] data = new byte[(endAddress - startAddress + 1 ) * ByteCountPerBlock];try {            mc.connect();for (short i = startAddress; i <= endAddress; i++ ,time++) {boolean auth = false;short sectorAddress = getSectorAddress(i);auth = mc.authenticateSectorWithKeyA(sectorAddress, MifareClassic.KEY_DEFAULT);if (auth){//the last block of the sector is used for KeyA and KeyB cannot be overwrittedshort readAddress = (short)(sectorAddress == 0 ? i : i + sectorAddress);byte[] response = mc.readBlock(readAddress);CombineByteArray(data, response, time * ByteCountPerBlock);}else{throw new NfcException(NfcErrorCode.TemporaryError,"Authorization Error.");}}mc.close();}catch (NfcException ne) {throw ne;}catch (IOException e) {throw new NfcException(NfcErrorCode.TemporaryError,"Get response, what it is not successfully.", e);}finally{try {mc.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}
复制代码

写数据的例子:
复制代码
//tag 就是在上一篇中onNewIntent中获取的tag
MifareClassic mc = MifareClassic.get(tag);try {mc.connect();boolean auth = false;short sectorAddress = 0auth = mc.authenticateSectorWithKeyA(sectorAddress,MifareClassic.KEY_DEFAULT);if (auth) {//the last block of the sector is used for KeyA and KeyB cannot be overwrittedmc.writeBlock(readAddress, dataTemp);mc.close();} }finally{try {mc.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
复制代码

完整的代码示例在这里下载



http://www.ppmy.cn/news/436375.html

相关文章

使用安卓手机的NFC功能进行数据读取操作

记录一下使用安卓手机的NFC功能来识别各类高频RFID标签或卡片的基本操作思路。因为我的项目中还存在有大量的业务逻辑代码,所以只能整理出当中的一些重要步骤,并贴上代码片段。 1、第一步:在AndroidManifest.xml配置文件里增加以下权限 <uses-permission android:name=&…

NFC如何使用

NFC 是一种比较新型的无线通信的技术&#xff0c;它的原理和蓝牙的原理是一样的&#xff0c;都是只能进行近距离的传送数据。一般这个功能是使用在手机上的&#xff0c;NFC 的用处主要体现在我们使用电子钱包 he 支付宝上。现在大部分的智能手机都是有 NFC 这个功能的&#xff…

关于手机功能NFC(以华为V9为例)

NFC&#xff08;Near Field Communication&#xff09;即近场通信技术&#xff0c;可以实现快速、便捷又安全的支付&#xff1b;又能进行即时传输&#xff0c;将自己的图片、应用程序等分享给好友。 NFC 主要有三种运行模式&#xff1a;卡模拟模式、读写模式和点对点模式&#…

STM32的中断系统详解(嵌入式学习)

中断系统 1. 基本概念2. 中断的意义3. 中断处理过程处理过程过程详述 4. 中断体系结构5. NVIC概念主要功能 6. EXTI概念主要功能结构框图中断和事件的区别 7. 总结 1. 基本概念 中断是处理器中的一种机制&#xff0c;用于响应和处理突发事件或紧急事件。当发生中断时&#xff…

关于HCE——Android手机NFC模拟刷卡成果和心得(上)

关于HCE——Android手机NFC模拟刷卡成果和心得 一、前言 在最近&#xff0c;开始研究了手机模拟NFC刷卡的一些内容&#xff0c;想是自己实现一次手机模拟刷卡。 NFC大家应该都了解&#xff0c;这两年的安卓手机基本都是支持了NFC功能&#xff0c;手机厂商也给出了各自的“钱…

Android近场通信---高级NFC(一)

本文译自&#xff1a;http://developer.android.com/guide/topics/connectivity/nfc/advanced-nfc.html 本文介绍一些高级的NFC专题&#xff0c;如多样的NFC标签技术、编写NFC标签、以及前台调度&#xff0c;前台调度允许在前台的应用程序优先调度Intent事件&#xff0c;即使还…

PN532读写卡器(支持NFC、RFID)

简介&#xff1a;一个基于PN532的RFID读写器&#xff0c;可以读写M1、UID、CUID、FUID、带NFC功能的手环、手机等&#xff0c;门禁卡解决方案的不二之选。 经作者允许&#xff0c;转载自PN532读写卡器&#xff08;支持NFC、RFID&#xff09; - 嘉立创EDA开源硬件平台 开源协议…

Android MTK支持哪些NFC芯片 M

前言 欢迎大家我分享和推荐好用的代码段~~ 声明 欢迎转载&#xff0c;但请保留文章原始出处&#xff1a; CSDN&#xff1a;http://www.csdn.net 雨季o莫忧离&#xff1a;http://blog.csdn.net/luckkof 正文 目前MTK支持的NFC芯片有两颗&am…