(第二篇:安卓系统如何去处理感应到的NFC标签)
上一篇我们简单了解了NFC领域的相关信息,尤其是目前安卓平台能对NFC所支持的情况,这能帮助我们在开发的时候有个大概的功能把握,从而主导我们在实际项目中能去实现相应的功能。那么,我们现在可以从安卓平台上重点了解整个运行机制了。本篇将从基础层次开始讲述安卓系统在实现NFC感应和处理数据上的流程和技术,只有从整体上把握才能让我们在接下来去探究技术细节。
NFC基础:围绕NDEF格式的数据操作,本模块主要从标签读取NDEF数据和设备间的数据传输展开讨论。
从标签中读取数据主要由一个标签调度系统进行控制管理,具有感应NFC标签并对其进行数据类型分析,再从设备中调用一个最适合该数据类型的NFC应用去处理。如果一个应用程序想要处理感应到的NFC标签,则需要声明一个相应的intent过滤才可请求处理。
另一个功能应用Android Beam则允许两个设备靠在一起然后进行数据的传输。这种交互提供了一个比蓝牙更容易的无线传输方式,因为在这种交互中不需要人工地匹配双方设备,整个连接过程是自动而快速的!Android Beam可依靠一系列相应的api实现,所以任何应用程序都可以在两设备间进行数据传送。比如,像浏览器和YouTube这些应用可以利用Android Beam和其它设备分享一些链接或是网页视频等。
前面已经提到标签调度系统这东西了,它负责设备在感应阶段如何去读取里面的信息,这个过程是在设备屏幕未锁定的前提下进行的。当屏幕未锁定且正常运行中的手机发现一个NFC标签时,理想的状况是系统自动调用一个最合适的应用程序去处理而不用让用户手动的在界面上选择哪个来执行。因为整个感应过程是短暂紧迫的,用户的设备需要在短短几厘米范围内去感应标签,如果需要用户去手动选择程序来处理感应的标签那么往往会因为这个动作打断连接过程。所以每个开发者都需要认识到这一点,尽量避免这种现象产生。
为了让开发者能达到这种目标,安卓系统提供了一个特别的标签调度系统来分析扫描到的NFC标签,解析并尽量选择一个最适合处理该标签数据的应用。整个过程将这样实现:
1.解析NFC标签,确定其MIME类型或一个能判断出标签有效信息容量的URI。
MIME type的缩写为(Multipurpose Internet Mail Extensions)代表互联网媒体类型(Internet media type),MIME使用一个简单的字符串组成,最初是为了标识邮件Email附件的类型,在html文件中可以使用content-type属性表示,描述了文件类型的互联网标准。
MIME类型能包含视频、图像、文本、音频、应用程序等数据。
2.封装过程,即将MIME类型或URI和其信息容量封装进一个intent,这两个过程可以参考“NFC标签如何映射到MIME类型和URIS”。
3.利用intent启动一个activity,这可以参考“NFC标签是如何被派往给应用程序处理的”。
NFC标签如何映射到MIME类型和URIS
在开发NFC应用程序前,了解不同NFC标签的类型是很重要的,还应该对标签调动系统如何解析NFC有具体理解,特别是标签调动系统发现一个NDEF格式的NFC标签时所采取的特殊处理方式。NFC标签采用了较广泛的技术并且有很多种写入数据的方法。安卓对NDEF格式提供了最多的支持,这些都将在NFC论坛进行了定义。
NDEF数据被封装进一个消息类(NdefMessage)中,该类包含一个或多个记录(NdefRecord),每个NDEF记录必须是结构良好的,这根据你需要创建的记录类型进行。安卓也支持其它类型没有包含NDEF数据的标签,开发者可以利用 android.nfc.tech package 包内的api进行操作。处理这些其它类型的数据需要你定义自己的协议栈去和标签进行交互。因此建议开发者使用NDEF格式,这将减轻你的开发难度并且最大限度的支持安卓平台的设备。
Tip:如何创建一个NDEF格式的记录我们将会去实践了解。
相信你已经对NFC标签技术有了一个基本的了解,接下来的几个章节将会详细介绍安卓系统如何处理NDEF格式的标签!
当一个开启的安卓设备扫描到一个包含NDEF格式数据的NFC标签,设备将会去解析里面的信息并尽量去指出数据的MIME类型或URI。系统将通过读取封装在NdefMessage中的第一个NdefRecord记录来确定如何解释剩下的所有NDEF数据。对于一个格式良好的NDEF消息来说,第一个NdefRecord记录包含以下几个内容:
3-bit TNF(类型名称格式)
指示如何解释可变长度类型字段,在下表1中介绍有效值。
可变长度类型
说明记录的类型,如果使用TNF_WELL_KNOWN,那么则使用这个字段来指定记录的类型定义(RTD)。在下表2中定义了有效的RTD值。
可变长度ID
唯一标识该记录。这个字段不经常使用,但是,如果需要唯一的标识一个标记,那么就可以为该字段创建一个ID。
可变长度负载
你想读/写的实际的数据负载。一个NDEF消息能够包含多个NDEF记录,因此不要以为在NDEF消息的第一条NDEF记录中包含了所有的负载。
标签调度系统使用TNF和类型字段来尝试把MIME类型或URI映射到NDEF消息中。如果成功,它会把信息跟实际的负载一起封装到ACTION_NEDF_DISCOVERED类型的Intent中。但是,会有标签调度系统不能根据第一条NDEF记录来判断数据类型的情况,这样就会有NDEF数据不能被映射到MIME类型或URI,或者是NFC标签没有包含NDEF开始数据的情况发生。在这种情况下,就会用一个标签技术信息相关的Tag对象和封装在ACTION_TECH_DISCOVERED类型Intent对象内部的负载来代替。
表1.介绍标签调度系统映射如何把TNF和类型字段映射到MIME型或URI上。同时也介绍了那种类型的TNF不能被映射到MIME类型或URI上。这种情况下,标签调度系统会退化到ACTION_TECH_DISCOVERED类型的Intent对象。
例如,如果标签调度系统遇到一个TNF_ABSOLUTE_URI类型的记录,它会把这个记录的可变长度类型字段映射到一个URI中。标签调度系统会把这个URI跟其他相关的标签的信息(如数据负载)一起封装到ACTION_NDEF_DISCOVERED的Intent对象中。在另一方面,如果遇到了TNF_UNKNOWN类型,它会创建一个封装了标签技术信息的Intent对象来代替。
表1.所支持的TNF和它们的映射
类型名称格式(TNF) |
映射 |
TNF_ABSOLUTE_URI |
基于类型字段的URI |
TNF_EMPTY |
退化到ACTION_TECH_DISCOVERED类型的Intent对象 |
TNF_EXTERNAL_TYPE |
基于类型字段中URN的URI。URN是缩短的格式(<domain_name>:<service_name)被编码到NDEF类型中。Android会把这个URN映射成以下格式的URI:vnd.android.nfc://ext/<domain_name>:<service_name>。 |
TNF_MIME_MEDIA |
基于类型字段的MIME类型 |
TNF_UNCHANGED |
退化到ACTION_TECH_DISCOVERED类型的Intent对象 |
TNF_UNKNOWN |
退化到ACTION_TECH_DISCOVERED类型的Intent对象 |
TNF_WELL_KNOWN |
依赖你在类型字段中设置的记录类型定义(RTD)的MIME类型或URI, |
表2.TNF_WELL_KNOWN所支持的RTD和它们的映射
记录类型定义(RTD) |
映射 |
RTD_ALTERNATIVE_CARRIER |
退化到ACTION_TECH_DISCOVERED类型的Intent对象 |
RTD_HANDOVER_CARRIER |
退化到ACTION_TECH_DISCOVERED类型的Intent对象 |
RTD_HANDOVER_REQUEST |
退化到ACTION_TECH_DISCOVERED类型的Intent对象 |
RTD_HANDOVER_SELECT |
退化到ACTION_TECH_DISCOVERED类型的Intent对象 |
RTD_SMART_POSTER |
基于负载解析的URI |
RTD_TEXT |
text/plain类型的MIME |
RTD_URI |
基于有效负载的URI |
那么,具体上标签数据是如何被派往给应用程序处理的?
当标签调度系统成功创建了一个封装了NFC标签数据的intent,该intent将会被送到满足该过滤条件的对此intent感兴趣的应用程序中去。如果有多个应用满足处理该intent的条件,那么手机界面将弹出应用选择窗口供用户选择。标签调度系统定义了如下三种类型的intent,它们被系统处理的优先级将从高到底进行:ACTION_NDEF_DISCOVERED:当一个标签包含NDEF格式的数据并且为规定的类型时,此类型的Intent将会被创建。这种intent拥有最高优先级,标签调度系统将在其它intent触发前开启。
ACTION_TECH_DISCOVERED:如果没有Activity注册过滤器来处理ACTION_NDEF_DISCOVERED类型的intent,标签调度系统将会尝试用这种intent来启动应用程序。当标签调度系统检测到标签包含NDEF格式数据(或者不包含NDEF数据,但是一种可被识别的标签技术)但不能将其映射到MIME类型或URI时,这种intent也同样会被创建。
ACTION_TAG_DISCOVERED:当没有Activity支持处理ACTION_NDEF_DISCOVERED或ACTION_TECH_DISCOVERED的intent时,该intent便被创建。
标签调度系统的基本流程是这样的:
1.标签调度系统将会创建一个intent(ACTION_NDEF_DISCOVERED 或ACTION_TECH_DISCOVERED类型)来启动一个Activity。
2.如果没有Activities来过滤处理这种intent,则会用优先级更低的ACTION_TECH_DISCOVERED 或 ACTION_TAG_DISCOVERED类型的intent来尝试启动Activities。
3.如果没有任何Activities来匹配这种intent,则不触发任何动作。
这个过程可用如下图示来描述:
在对整个安卓系统关于NFC标签的调用机制有了全面了解后,我们有理由进行第一次NFC应用开发了,下一篇我们将从开发层面进行实际操作。很快,我们将可以用自己的应用程序去对NFC标签进行简单的读写操作了。请继续关注!