Search code examples
androidandroid-intentnfcintentfiltermifare

Open Android Activity when NFC_TECH is discovered


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?


Solution

  • 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>