NFC(Near Field Communication,近场通信),是一种数据传输技术。
NFC有3种工作模式:
1,读卡器模式(Reader/writer mode)
--NFC设备读取带有nfc芯片的标签
2,仿真卡模式(Card Emulation Mode)
--NFC设备把自己模拟成nfc标签,如手机成为公交卡
3, 点对点模式(P2P mode)
--如手机间传送文件
android 在api =9时开始支持NFC功能,在api=14的时候开始可以借助蓝牙传输大量的数据;Android SDK API主要支持NFC论坛标准(Forum Standard),这种标准
被称为NDEF(NFC Data Exchange Format,NFC数据交换格式)。
Android SDK API支持如下3种NDEF数据的操作。
1),从NFC标签读取NDEF格式的数据。
2),向NFC标签写入NDEF格式的数据。
3),通过Android Beam技术将NDEF数据发送到另一部NFC设备。
如果Android手机带有NFC功能,并且NFC功能是开启的,当手机靠近带有NFC芯片的标签时,系统自动捕获动作,需找最适合的activity(启动包含这个activity的应用)去处理,匹配规则在Intent中的3种action:
1),ACTION_NDEF_DISCOVERED:当系统检测到tag中含有NDEF格式的数据时,且系统中有activity声明可以接受包含NDEF数据的Intent的时候,系统会优先发出这个action的intent。
2),ACTION_TECH_DISCOVERED:当没有任何一个activity声明自己可以响应
ACTION_NDEF_DISCOVERED时,系统会尝试发出TECH的intent.即便你的tag中所包含的数据是NDEF的,但是如果这个数据的MIME type或URI不能和任何一个activity所声明的想吻合,系统也一样会尝试发出tech格式的intent,而不是NDEF.
3),ACTION_TAG_DISCOVERED:当系统发现前两个intent在系统中无人会接受的时候,就只好发这个默认的TAG类型的
除了带有匹配的声明还不够,还有赋予权限:
<uses-permission android:name="android.permission.NFC" />
然后是sdk支持: API>=9 ,<uses-sdk android:minSdkVersion="9"/>
如果添加了
<uses-feature android:name="android.hardware.nfc" android:required="true" />,
那么只有带有NFC功能的手机才能安装这个应用。
如果手机中有多个activity(多个应用)响应这个action,android系统会列出所有的应用供你选择,为了提高匹配的准确性,google提供了3种过滤条件
1),过滤ACTION_TAG_DISCOVERED:
<intent-filter>
<action android:name="android.nfc.action.TAG_DISCOVERED"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
这个最简单,但优先级低,最后才被处理;
2:过滤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>
其中最重要的应该算是data的mimeType类型了,这个定义的越准确,intent指向你这个activity的成功率就越高,否则系统可能不会发出你想要的NDEF intent了。
3:过滤ACTION_TECH_DISCOVERED:
你首先需要在你的<project-path>/res/xml下面创建一个过滤规则文件。名字任取,比如可以叫做nfc_tech_filter.xml。这个里面定义的是nfc实现的各种标准,每一个nfc卡都会符合多个不同的标准,个人理解为这些标准有些相互之间也是兼容的。你可以在检测到nfc标签后使用getTechList()方法来查看你所检测的tag到底支持哪些nfc标准。
一个nfc_tech_filter.xml中可以定义多个<tech-list>结构组。每一组代表我声明我只接受同时满足这些标准的nfc标签。比如A组表示,只有同时满足IsoDep,NfcA,NfcB,NfcF这四个标准的nfc标签的intent才能进入。A与B组之间的关系就是只要满足其中一个就可以了。换句话说,你的nfc标签技术,满足A的声明也可以,满足B的声明也可以。
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<tech-list> --------------------------------A组
<tech>android.nfc.tech.IsoDep</tech> <tech>android.nfc.tech.NfcA</tech> <tech>android.nfc.tech.NfcB</tech> <tech>android.nfc.tech.NfcF</tech>
</tech-list>
<tech-list>-----------------------------------------B组
<tech>android.nfc.tech.NfcV</tech> <tech>android.nfc.tech.Ndef</tech> <tech>android.nfc.tech.NdefFormatable</tech> <tech>android.nfc.tech.MifareClassic</tech> <tech>android.nfc.tech.MifareUltralight</tech>
</tech-list>
</resources>
在androidManifest文件中声明xml过滤的举例如下
<activity>
<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" />-------------这个就是你的资源文件名
</activity>