Open Android Activity when NFC_TECH is discovered

2019-01-28 22:40发布

问题:

I am developing an app which is required to open upon scanning an NFC tag that doesn't contain any data(?) except for ID.

The items in database are supposed to be identified by that ID and I am not supposed to write anything on these tags

I can get the device to scan the tag in foreground mode by calling

enableForegroundDispatch()

and it returns me with new intent that contains the required data EXTRA_ID

However when the application is on background and I scan a tag, I can hear the system sound for scan completion but the app is not opened

I have the following intent filter on my application manifest

        <intent-filter>
            <action android:name="android.nfc.action.TAG_DISCOVERED"/>
        </intent-filter>

        <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" />

nfc_tech_filter.xml contains all the tags supported by Android

<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <tech-list>
        <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>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>

The tag I am scanning is of type android.nfc.tech.MifareUltralight, android.nfc.tech.NfcA, android.nfc.tech.NdefFormatable

I am only interested in the tag ID

Is it possible to get my activity opened/notified upon tag scanning without writing anything on the tag?

回答1:

As you already seem to have found out yourself, that's possible using the TECH_DISCOVERED intent filter:

<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" />

The problem is your tech-filter XML file. The tech-filter that you specified translates to *match any tag that is IsoDep and NfcA and NfcB and and NfcF and etc. As some of these tag technologies (e.g. Nfc[A|B|F|V]) are mutually exclusive, no tag will ever match this condition.

You can overcome this by specifying a tech-filter that matches all these technologies with logical or:

<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <tech-list>
        <tech>android.nfc.tech.IsoDep</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.NfcA</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.NfcB</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.NfcF</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.NfcV</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.Ndef</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.NdefFormatable</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.MifareClassic</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.MifareUltralight</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.NfcBarcode</tech>
    </tech-list>
</resources>

Or as you already found that your tag is NfcA, you could also simply match NfcA:

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


回答2:

To open your android app on NDEF_DISCOVERED.

You have to set your custom mimeType. By doing so, you are letting the android know that this is your custom tag and this application is well suitable for that tag.

Note: You can not expect your app to open for all the tag types/mime type that you show. As you know, that is user's choice to select his/her preferred app.

<intent-filter>
    <action android:name="android.nfc.action.NDEF_DISCOVERED" />
    <!-- THIS ONE -->
    <data android:mimeType="application/com.myExample.myVeryOwnMimeType" /> 
    <category android:name="android.intent.category.DEFAULT" />
</intent-filter>