NFC( 近场通信 )
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 上有简单的操作系统,允许一些复杂的交互和可以执行一些代码。
API 概览
Android.nfc
package 包含顶层类用来与本地 NFC 适配器交互 . 这些类可以表示被检测到的 tags 和用 NDEF 数据格式。
Class |
Description |
NfcManager |
一个 NFC adapter 的管理器,可以列出所有此 android 设备支持的 NFC adapter. 只不过大部分android 设备只有一个 NFC adapter ,所以你大部分情况下可以直接用静态方法getDefaultAdapter(context) 来取适配器。 |
NfcAdapter |
表示本设备的 NFC adapter, 可以定义 Intent 来请求将系统检测到 tags 的提醒发送到你的 Activity. 并提供方法去注册前台 tag 提醒发布和前台 NDEF 推送。 |
NdefMessageandNdefRecord |
NDEF 是 NFC 论坛定义的数据结构,用来有效的存数据到 NFC tags. 比如文本, URL ,和其他MIME 类型。一个 NdefMessage 扮演一个容器,这个容器存哪些发送和读到的数据。一个NdefMessage 对象包含 0 或多个 NdefRecord, 每个 NDEF record 有一个类型,比如文本, URL ,智慧型海报 / 广告,或其他 MIME 数据。在 NDEFMessage 里的第一个 NfcRecord 的类型用来发送 tag到一个 android 设备上的 activity. |
Tag |
标示一个被动的 NFC 目标,比如 tag , card ,钥匙挂扣,甚至是一个电话模拟的的 NFC 卡 .当一个 tag 被检测到,一个 tag 对象将被创建并且封装到一个 Intent 里,然后 NFC 发布系统将这个Intent 用 startActivity 发送到注册了接受这种 Intent 的 activity 里。你可以用 getTechList() 方法来得到这个 tag 支持的技术细节和创建一个 android.nfc.tech 提供的相应的 TagTechnology 对象。 |
android.nfc.techpackage 包含那些对 tag 查询属性和进行 I/O 操作的类。这些类分别标示一个 tag 支持的不同的 NFC 技术标准。
Class |
Description |
TagTechnology |
这个接口是下面所有 tag technology 类必须实现的。 |
NfcA |
支持 ISO 14443-3A 标准的操作。 Provides access to NFC-A (ISO 14443-3A) properties and I/O operations. |
NfcB |
Provides access to NFC-B (ISO 14443-3B) properties and I/O operations. |
NfcF |
Provides access to NFC-F (JIS 6319-4) properties and I/O operations. |
NfcV |
Provides access to NFC-V (ISO 15693) properties and I/O operations. |
IsoDep |
Provides access to ISO-DEP (ISO 14443-4) properties and I/O operations. |
Ndef |
提供对那些被格式化为 NDEF 的 tag 的数据的访问和其他操作。Provides access to NDEF data and operations on NFC tags that have been formatted as NDEF. |
NdefFormatable |
对那些可以被格式化成 NDEF 格式的 tag 提供一个格式化的操作 |
MifareClassic |
如果 android 设备支持 MIFARE ,提供对 MIFARE Classic 目标的属性和 I/O 操作。 |
MifareUltralight |
如果 android 设备支持 MIFARE ,提供对 MIFARE Ultralight 目标的属性和 I/O 操作。 |
声明 Android Manifest.xml 的元素
在你能访问一个设备的 NFC 硬件和正确的处理 NFC 的 Intent 之前,需要在 AndroidManifest.xml 中先声明下面的项:1.
NFC 使用
<uses-permission>
元素来访问 NFC 硬件 :
2.最小 SDK 版本需要设置正确, API level 9 只包含有限的 tag 支持 , 包括:
. 通过 ACTION_TAG_DISCOVERED来发布 Tag 信息
. 只有通过 EXTRA_NDEF_MESSAGES扩展来访问 NDEF 消息
. 其他的 tag 属性和 I/O 操作都不支持
所以你可能想要用 API level 10 来实现对 tag 的广泛的读写支持。
3.uses-feature 元素定义:你的程序可以再 android 市场里显示有 NFC 硬件。
4.NFC intent filter 告诉 android 系统你的 activity 能处理 NFC 数据,可以定义 1 个或多个 intent filter :
上边 3 个 intent filters 有优先级,更多信息可以看下面的 Tag 发布系统
也可以看 NFCDemo 例子的
AndroidManifest.xml来有个更深的理解。
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 发布系统。
使用 Intent 发布系统
Intent 发布系统指定了 3 个 intent 有不同的优先级。通常当一个 tag 被检测到之后, Intent 就被启动( start )了,这个启动遵循以下行为 :
·
android.nfc.action.NDEF_DISCOVERED : 这个 intent 是在一个包含 NDEF 负载的 tag 被检测到时启动,这是最高优先级的 intent, android 系统不会让你指定一个 Intent 能处理所有的 NFC 数据类型,你必须在 AndroidManifest.xml 中指定与NFC tag 对应的 <data> 元素,这样当扫描到的 tag 传过来的数据类型与你定义的相匹配时,你的 Activity 就会被调用。例如想处理一个包含 plain text 的
NDEF_DISCOVERED intent ,你要按照如下定义 AndroidManifest.xml file:
如果 NDEF_DISCOVERED
intent 已经被启动, TECH_DISCOVERED
和
TAG_DISCOVERED intents 将不会被启动。假如一个未知的 tag 或者不包含 NDEF 负载的 tag 被检测到,此 Intent 就不会被启动。
·
android.nfc.action.TECH_DISCOVERED : 如果
NDEF_DISCOVERED intent 没启动或者没有一个 Activity 的 filter 检测 NDEF_DISCOVERED
,并且此 tag 是已知的,那么此 TECH_DISCOVERED Intent 将会启动 . TECH_DISCOVERED intent 要求你在一个资源文件里 (xml) 里指定你要支持 technologies 列表。更多细节请看下面的 Specifying tag technologies to handle .
·
android.nfc.action.TAG_DISCOVERED : 如果没有一个 activity 处理 _DISCOVERED and TECH_DISCOVEREDintents 或者 tag 被检测为未知的,那么此 Intent 将会被启动。
Specifying tag technologies to handle 指定处理的 technologies
假如你的 Activity 在 AndroidManifest.xml 文件里声明了处理 android.nfc.action.TECH_DISCOVERED intent ,你必须创建一个 Xml 格式的资源文件,并加上你的 activity 支持的 technologies 到 tech-list 集合里。这样你的 activity 将被认作能处理这些 tech-list 的处理者,如果 tag 使用的 technology 属于你的定义的 list 里,你的 Activity 将接收此 Intent 。你可以用getTechList() 来获得 tag 支持的 technologies 。
例如:如果一个 tag 被检测到支持 MifareClassic, NdefFormatable, 和 NfcA ,你的 tech-list 集合必须指定了其中的一项或者多项来保证你的 Activity 能处理此 Intent 。