美文网首页DevSupport
android NFC学习笔记 (一)

android NFC学习笔记 (一)

作者: 巧士周瑜 | 来源:发表于2016-08-16 08:51 被阅读0次

    一:NFC的tag分发系统
    如果想让android设备感应到NFC标签,你要保证两点
    1:屏幕没有锁住
    2:NFC功能已经在设置中打开

    当系统检测到一个NFC标签的时候,他会自动去寻找最合适的activity去处理这个intent.
    他所发出的这个Intent将会有三种action:

    ACTION_NDEF_DISCOVERED:当系统检测到tag中含有NDEF格式的数据时,且系统中有activity声明可以接受包含NDEF数据的Intent的时候,系统会优先发出这个action的intent。

    ACTION_TECH_DISCOVERED:当没有任何一个activity声明自己可以响应ACTION_NDEF_DISCOVERED时,系统会尝试发出TECH的intent.即便你的tag中所包含的数据是NDEF的,但是如果这个数据的MIME type或URI不能和任何一个activity所声明的想吻合,系统也一样会尝试发出tech格式的intent,而不是NDEF.

    ACTION_TAG_DISCOVERED:当系统发现前两个intent在系统中无人会接受的时候,就只好发这个默认的TAG类型的

    二:NFC相关androidManifest文件设置
    首先是权限:<uses-permission android:name="android.permission.NFC" />
    然后是sdk级别限制:建议API10开始比较合适:<uses-sdk android:minSdkVersion="10"/>
    接着是特殊功能限制<uses-feature android:name="android.hardware.nfc" android:required="true" />
    声明使用者必须拥有nfc功能。

    三:NFC标签过滤
    在activity的intent过滤xml声明中,你可以同时声明过滤这三种action.但是由之前所说,你应该知道系统在发送intent的时候是有优先级的,所以你最好清楚自己最想处理哪个。
    1:过滤ACTION_TAG_DISCOVERED:
    <intent-filter>
    <action android:name="android.nfc.action.TAG_DISCOVERED"/>
    <category android:name="android.intent.category.DEFAULT"/>
    </intent-filter>
    这个最简单,也是最后一个被尝试接受intent的选项。

    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了。下面在讲如何使用NDEF写入NFC标签的时候会多举几个类型的例子。

    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>

    4:nfc标签前台分发系统
    之所以把他也归类在nfc的过滤里面,主要是因为他跟解析nfc标签到不是那么的紧密,他解决的是接受哪些nfc标准的标签问题。所以更接近nfc的过滤。

    什么叫nfc的前台发布系统?就是说当我们已经打开我们的应用的时候,那么通过这个前台发布系统的设置,我们可以让我们已经启动的activity拥有更高的优先级来依据我们在代码中定义的标准来过滤和处理intent,而不是让别的声明了intent filter的activity来干扰,甚至连自己声明在androidManifest中的intent filter都不会来干扰。也就是说foreground Dispatch的优先级大于intent filter。

    第一种情况:当你的activity没有启动的时候,去扫描tag,那么系统中所有的intent filter都将一起参与过滤。
    第二种情况:当你的actiity启动了,去扫描tag时,那么将直接使用你在foreground dispatch中代码写入的过滤标准。如果这个标准没有命中任何intent,那么系统将使用所有activity声明的intent filter xml来过滤。

    在OnCreate中你可以添加如下代码
    mPendingIntent = PendingIntent.getActivity(this, 0,
    new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);

        // 做一个IntentFilter过滤你想要的action 这里过滤的是ndef
        IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
    

    //如果你对action的定义有更高的要求,比如data的要求,你可以使用如下的代码来定义intentFilter
    // try {
    // ndef.addDataType("/");
    // } catch (MalformedMimeTypeException e) {
    // // TODO Auto-generated catch block
    // e.printStackTrace();
    // }
    //生成intentFilter
    mFilters = new IntentFilter[] {
    ndef,
    };

        // 做一个tech-list。可以看到是二维数据,每一个一维数组之间的关系是或,但是一个一维数组之内的各个项就是与的关系了
        mTechLists = new String[][] { 
                new String[] { NfcF.class.getName()},
                new String[]{NfcA.class.getName()},
                new String[]{NfcB.class.getName()},
                new String[]{NfcV.class.getName()}
               };
    

    在onPause和 onResume中需要加入相应的代码。
    public void onPause() {
    super.onPause();
    //反注册 mAdapter.disableForegroundDispatch(this);
    }

    public void onResume() {
    super.onResume();
    //设定intentfilter和tech-list。如果两个都为null就代表优先接收任何形式的TAG action。也就是说系统会主动发TAG intent。
    mAdapter.enableForegroundDispatch(this, mPendingIntent, mFilters, mTechLists);

    }

    相关文章

      网友评论

        本文标题:android NFC学习笔记 (一)

        本文链接:https://www.haomeiwen.com/subject/xrhpsttx.html