(开发阶段:详解如何读取一个标签)
还对NFC的格式和映射方式不太了解?还对NFC的感应机制很模糊?
没关系!本文将先从一个简单的应用入手,让你有个基本的感受。
上文说了,甭管怎么开发,第一步便是配置好应用的权限,如下图:
在AndroidManifest.xml中添加如上权限。这样就能对NFC模块进行操作了。
本次开发的NFC应用具有对标签进行读和写的两个功能模块,那么我们就先从“读”模块入手吧。由之前介绍的标签调度系统可知,设备感应到NFC标签将会有一个映射过程,映射后的类型和内容打包进一个Intent,此Intent将会用来触发设备中的应用(其实就是打开匹配的Activitiy)。如果想要你开发的应用能过滤到该Intent,那么你就需要在工程的主Activity添加如下过滤了:
首先<action android:name="android.nfc.action.NDEF_DISCOVERED" />说明该Activity针对的是NDEF格式的Intent,如果感应的标签里是其它格式(比如为TECH)那么就不进行过滤接收了。
记住<data android:mimeType="text/plain" > </data>这个标签,它表明本Activity将只过滤到MiMe类型为“text/plain”为的Intent。
所以,从配置的<intent-filter>内容来看,我们可以知道本应用将只处理NDEF数据格式且里面的MiMe类型为“text/plain”的标签。
那么,当该Activity过滤到匹配的Intent时,将如何去处理呢?首先,相应的Intent将会触发该Activity,所以就会调用Activity的onCreate()方法,我们需要在此方法添加一些读取前的初始化工作,如图:
init()方法的代码如下所示:
很明显,我们在代码中发现了NfcAdapter这个关键类,它是个NFC处理方面的适配器,在整个处理流程中NfcAdapter都扮演着管理的角色。对于pendingIntent、ndef等类,我们暂且先搁着一边,接下来,我们来看看实际的读取过程:
代码中的intent表示的正是我们过滤到的对象(先不考虑怎么获得该对象),只要我们接收到了intent对象,那么接下来的处理就是顺理成章的事了。对于接收到的intent我们要先判断是否属于NDEF的格式,只要满足这个条件我们才可以进行接下来的数据获取。记住,这个非常关键,因为如果有其它意外导致不是NDEF格式的话那么我们很可能就不能解析到正确的数据了。
readFromTag(intent)方法如下:
以上代码简单的解释了如何去获取intent里面的信息,你看见了么,Parcelable[] rawArray = intent
.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);说明我们要获取的是标签里面的一组Ndef信息,如果你不清楚没关系,也先搁着一边,反正知道该操作专门获得里面存储数据的内容就是了。
之前已经提过了,NDEF格式的数据先是存储在NdefRecord的数组中,NdefRecord数组然后被封装在NdefMessage类的对象中。所以按此结构我们就得到了上面代码中获取数据的方式。需要特别注意的,本次应用只是读取标签中的第一个NdefRecord内容,但这不说明其它标签也是这样,如果标签中的数据存在多个NdefRecord那么就需要一个个读取了。最后:
readResult = new String(mNdefRecord.getPayload(), "UTF-8");
恭喜,readResult获得内容就是我们所要读取的信息啦。
我们再来回顾下整个过程:
你或许已经认识到这样的问题了,文中所说的Intent对象又是从哪里获得呢?这里涉及到Activity的生命周期知识了。我们知道,Activity一旦被Intent触发,那么首先会调用Oncreate()方法,然后是onStart(),有这么个过程:
onCreate()->onStart()->onResume()->onPause()->onResume(),一般一个Activity从被打开到显示在屏幕都会经过onCreate()->onStart()->onResume()这三个过程,所以我们需要在onResume中添加处理方法:
那么,这只是考虑了从感应到打开这么一种情况,如果你的应用被感应后再次去接触标签,那么此时还是重复刚才整个过程么?出于效率和性能的问题,我们应该这么设计:当多次去感应标签时,那么应该调用刚才那个Activity实例进行多次重复处理!
因此,结合实际的生命周期,我们还需要在onPause()和onNewIntent(Intent intent)中进行处理代码的布置。如下图:
为何是在onNewIntent()中添加处理的代码呢?如果还不明白也没关系,总之,我们已经在读取NDEF数据方面做了个详细的了解,下一篇将会接着本篇搁着的几个问题继续探讨。我们从生命周期方面学习如何合理的解决Intent的对象获取问题,我们也开始学习如何往标签写入数据,并将会把本次开发的Demo(完整代码)奉献给大家参考,请继续关注咯。