Android NFC Intent-filter for all type

2019-03-05 09:48发布

问题:

I would like to create an Android app that handle all of the NFC event like NDEF, TECH and TAG discovered for all categories and all data types.

These intent filters are in my Android Manifest file:

<intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
    <action android:name="android.nfc.action.NDEF_DISCOVERED" />
    <action android:name="android.nfc.action.TECH_DISCOVERED" />
    <action android:name="android.nfc.action.TAG_DISCOVERED" />
    <category android:name="android.intent.category.DEFAULT" />
</intent-filter>

This code works when the event is TAG_DISCOVERED. NDEF_DISCOVERED don't call my app.

Can anyone spot what I'm doing wrong?

回答1:

Your intent filter

<intent-filter>
    <action android:name="android.nfc.action.NDEF_DISCOVERED" />
    <action android:name="android.nfc.action.TECH_DISCOVERED" />
    <action android:name="android.nfc.action.TAG_DISCOVERED" />
    <category android:name="android.intent.category.DEFAULT" />
</intent-filter>

does not make much sense due to the fact how intent dispatching for NFC works (see How NFC Tags are Dispatched to Applications)

  1. TAG_DISCOVERED (when used in the manifest) will only ever be fired if no app is registered for a TECH_DISCOVERED or NDEF_DISCOVERED intent that matches the tag. Hence, if you also intend to register your app to handle all TECH_DISCOVERED and NDEF_DISCOVERED intents, there is typically no need to also register for TAG_DISCOVERED.

  2. The NDEF_DISCOVERED intent filter requires (on many platform versions/devices, optional on some) an additional data type that you want to listen for (see <data ... />). There is no such thing as a catch-all NDEF_DISCOVERED intent filter (though you can get close to that by using TECH_DISCOVERED for Ndef and NdefFormatable technologies). NDEF_DISCOVERED will only match the most specific intent filter. For example, if you register for all URLs that start with "http://", any app that registers for URLs starting with "http://www.example.com/" will get precedence over your app. Thus, you would need to register for an endless number of data types in order to get precedence over all other apps.

  3. The TECH_DISCOVERED intent filter requires an additional definition of tag technologies that you want to listen for (see LaurentY's answer). The available technologies are those in the namespace android.nfc.tech.*, currently:

    android.nfc.tech.IsoDep
    android.nfc.tech.MifareClassic
    android.nfc.tech.MifareUltralight
    android.nfc.tech.Ndef
    android.nfc.tech.NdefFormatable
    android.nfc.tech.NfcA
    android.nfc.tech.NfcB
    android.nfc.tech.NfcBarcode
    android.nfc.tech.NfcF
    android.nfc.tech.NfcV
    

    You specify them in an XML file. For instance, to match all NfcA and all NfcB tags, you could use this in a file called xml/nfc_tech_filter.xml:

    <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
        <tech-list>
            <tech>android.nfc.tech.NfcA</tech>
        </tech-list>
        <tech-list>
            <tech>android.nfc.tech.NfcB</tech>
        </tech-list>
    </resources>
    

    You can then attach this XML file using the <meta-data> tag (within the <activity> tag but outside the <intent-filter> tag:

    <meta-data android:name="android.nfc.action.TECH_DISCOVERED"
               android:resource="@xml/nfc_tech_filter" />
    


回答2:

You have to create multiple intent-filter as this:

<intent-filter>
    <action android:name="android.nfc.action.NDEF_DISCOVERED" />
    <category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
   <action android:name="android.nfc.action.TECH_DISCOVERED" />
    <category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<meta-data android:name="android.nfc.action.TECH_DISCOVERED" android:resource="@xml/filter_nfc" />
<intent-filter>
    <action android:name="android.nfc.action.TAG_DISCOVERED" />
    <category android:name="android.intent.category.DEFAULT" />
</intent-filter>

For TECH_DISCOVERED you must create an XML resource file that specifies the technologies that your activity supports within a tech-list set as explained here:http://developer.android.com/guide/topics/connectivity/nfc/nfc.html#tech-disc