高级nfc课题
这篇文档描述了高级nfc课题,比如各种各样的标签技术,写NFC标签,还有允许当前前端app处理nfc的intent即时还有其他的app也过滤这个nfc标签的intent的时候。
Android支持的标签技术
nfc标签和Android设备通信,读写tag数据最常用的格式是NDEF格式,对此Android提供了支持可以解析消息并以NdefMessage的方式传递信息,然而有些时候,可能扫描到不包含ndef格式的nfc标签或者包含ndef数据但是不能够映射出mime type(uri)的情形,这时,不得不直接和tag进行交互然后使用自己定义的私有协议读写数据(以raw byte的形式,xml,json都可以)。Android通过 android.nfc.tech包对这些情况的底层提供了最基本的支持。你也可以使用方法getTechList()获取到当前activity支持的tag技术(这个api在nfc基础中有着更详细的解释)然后使用android.nfc.tech包提供的相应的类来创建TagTechnology对象(利用这个对象可以实现nfc tag中的数据的读写).
Android支持的标签技术规范:
可选的Android支持的标签技术规范(是否支持取决于设备):
标签技术的实现和ACTION_TECH_INTENT intent
当设备扫描到的标签不含有ndef数据或者映射不到mime type(uri)的时候,标签匹配系统会通过Intent(ACTION_TECH_INTENT)来启动activity,这个备份intent允许你直接和tag进行交互和使用自定义协议读写nfc tag中的数据,和tag直接交互的步骤如下:
在你想要直接处理tag的activity的manifest文件中声明ACTION_TECH_INTENT intentfilter。正常情况下,标签匹配系统扫描到不含有ndef格式数据或者映射不到mime type(uri)的时候会通过这个intent去启动activity,想要了解更多可以参考nfc基础
当app获取到intent的时候,从intent中读取tag对象,即:
获取TagTechnology的实例。通过android.nfc.tech包tag技术的对应类的get方法获取,在调用get方法前可以通过方法getTechList()方法获取到当前activity支持的tag技术。例如,tag技术之一的MifareUltralight获取TagTechnology的实例的方式如下:
读和写标签数据
读写nfc标签包含从intent中读取tag和读写tag数据,读写tag数据需要自定义协议栈(ndef数据格式定义好了数据协议tnf,type,id,payload,tag数据没有定义需要自定义)需要注意的是,和tag直接交互的时候仍然可以读写ndef的数据(在上面的类型上有NDEF这个tag类型,使用NDEF这个类可以读写ndef数据写ndef tag标签也是通过这个类完成)。下面的例子显示了如何读写MifaREUitralight格式的标签数据:
使用前端匹配系统代替标签匹配系统
前端匹配系统:通过配置使得当前在前端的activity具有过滤和接受nfc标签的更高的优先级。分为两种情况:
特殊配置的activity没有启动的时候,设备发现nfc标签以后还是通过aar和intentfilter的标签匹配系统进行匹配分发。
当特殊配置的activity启动并在当前时,设备发现nfc标签以后优先经过当前的activity的筛选,看其是否处理,如果处理优先处理,如果不处理将其再交于intentfilter 标签匹配系统去处理去。
在activity中配置前端匹配的步骤是:
在activity的oncreate生命周期方法中添加如下代码:
创建一个PendingIntent对象以便Android系统可以将扫描到的nfc标签数据封装到这个intent中去。
生成你的activity想要拦截的intentfilter集合,前端匹配系统发现nfc标签后会通过接收到的这个特殊的intentfilter集合来过滤匹配,如果匹配,你的app将会处理这个nfc标签,如果不匹配,前端匹配系统将会把数据交还给intentfilter匹配系统去匹配。如果指定一个intentfilter集合的空数组代表你要拦截所有的标签。下面的代码片段指定了拦截NDEF_DISCOVERED的所有mimetype的标签:
建立一个你的activity想要处理的标签技术类型的集合,使用Object.class.getName()方法可以获取到想要支持的类型类
重写activity的生命周期回调,添加允许和屏蔽前端匹配系统的逻辑代码
前端匹配系统针对的对象是正处于前端的activity,所以在onresume()中允许前端匹配功能在onpause()中屏蔽了前端匹配功能,即在onresume()中调用方法 enableForegroundDispatch())即可。
需要注意的是:
enable和disable都需要主线程中调用,还有就是需要重写onNewIntent()来获取nfc的标签数据,获取方法参考nfc基础