Search code examples
androidandroid-intentnfcrfid

Android NFC: Intercept all Tags


I want my app to intercept all tags discovered by the phone. That way I want to check the uid of the tag and pass on the intent afterwards (show an application chooser etc.).

<action android:name="android.nfc.action.NDEF_DISCOVERED"/>
<action android:name="android.nfc.action.TAG_DISCOVERED"/>
<action android:name="android.nfc.action.TECH_DISCOVERED"/>

Thats what I currently have in my manifest, along with a intent filter for TAG_DISCOVERED:

<tech-list>
     <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.IsoDep</tech>
     <tech>android.nfc.tech.MifareClassic</tech>
     <tech>android.nfc.tech.Ultralight</tech>
     <tech>android.nfc.tech.Ndef</tech>
     <tech>android.nfc.tech.NdefFormatable</tech>
 </tech-list>

When I scan a Mifare Smartcard, my app gets called, when i use different tags with NXP ICODE ICs, the standard android tag app is launched.

Any hint on how I can ensure that I get to see ALL tags?


Solution

  • First off, the way a tech-list works is that all the tech's listed are ANDed together, meaning the intent is passed to the app if the tag has ALL the different techs listed. I don't know of any that do. what you are wanting to do is more:

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

    and so on. This ORs the different tags you want. (NfcA or NfcB etc.) Now some of these tech's go together, like NfcA and Ultralight or Ndef. So if you want to catch a card that is NfcA and Ndef you would use

    <tech-list>
        <tech>android.nfc.tech.NfcA</tech>
        <tech>android.nfc.tech.Ndef</tech>
    </tech-list>
    

    Now, the app that most closely matches the tech on the tag would launch, or be shown in a selection menu. But NDEF_DISCOVERED gets priority over TECH_DISCOVERED. Now the NDEF_DISCOVERED intent launcher can be very specific in what tags get passed on. While some formats of NDEF (Like Mime type) allow for "catch all" filters (example, "/" for Mime), some do not. (like for a uri formatted Ndef Record). For those, if there is a specific app targeting it, unless you know it and build it in, you won't be able to guarantee that your app will be launched. Also I've never been able to have more than one intent filter for Ndef tags (Mime OR URI, but not both). But that could be that I haven't tried hard enough.

    And if another app tries to do the same (catch as many tags as possible), you will always be called up with it. So there is no possible way of catching every single tag, unless you have the only app on the phone. But formatting your tech-list code like you see above will get you a lot closer.