1

I'd like to, at a certain point in an app, request that the user scan an NFC tag. It seems like enableReaderMode would be a reasonable solution. However, it's not working - consider the following code placed in onCreate in an Activity in a new Android project (with the NFC permission added).

nfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (nfcAdapter == null) {
    Toast.makeText(this, "No NFC", Toast.LENGTH_LONG).show();
    return;
}
System.out.println("NFC enable reader mode");
nfcAdapter.enableReaderMode(this, tag -> {
    System.out.println("NFC tag found");
    Toast.makeText(this, "Tag found", Toast.LENGTH_LONG).show();
}, NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK, null);

I see "NFC enable reader mode" in the logs, and (on one version of Android) while the app is up, tags do not cause other apps to open, suggesting that reader mode is indeed active (with FLAG_READER_SKIP_NDEF_CHECK preventing ndef checking), but the callback isn't called. I've held a tag to the back of the app, observed nothing, exited the app, and the tag immediately scans - so the tags are fine, and their placement is fine, just, for some reason enableReaderMode isn't causing the callback to get called when a tag gets near.

I've tried it on Oxygen OS 10, and on Android 11. On 10, it displayed the behavior given above. On 11, tags opened other apps, as normal (i.e. erroneously), rather than being suppressed by the ndef flag. Neither called the callback.

This seems like so basic a use case that, were it broken, I'd find dozens of threads about it, yet I've turned up only two sorta relevant things: on some device not call callback (NfcAdapter.ReaderCallback) method in nfcAdapter.enableReaderMode and NFCAdpater.enableReaderMode(...) doesn't work consistently if booting in Kiosk mode activity . The former looks pretty relevant, the latter less so, but neither are answered. I sorta figure I have to be doing something wrong - but it's such a simple block of code, I'm not sure what I COULD be doing wrong. Plus, there's the differing behavior between devices. Anybody know what's up?

Erhannis
  • 4,256
  • 4
  • 34
  • 48

1 Answers1

1

You have configured enableReaderMode to skip Ndef detection BUT you have not configured it to read any other Tag Tech types

Instead of NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK you flag options should look like below to be useful to read Tags

NfcAdapter.FLAG_READER_NFC_A |
NfcAdapter.FLAG_READER_NFC_B |
NfcAdapter.FLAG_READER_NFC_F |
NfcAdapter.FLAG_READER_NFC_V |
NfcAdapter.FLAG_READER_NFC_BARCODE |
NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK |
NfcAdapter.FLAG_READER_NO_PLATFORM_SOUND
Andrew
  • 8,198
  • 2
  • 15
  • 35
  • ...Huh. So, I sorta figured "ndef" and e.g. "NFC A" were separate things, but it seems like maybe ndef records are transmitted via NFC A (or B or V etc.), is that right? And it so happens that if you pass `0` to `enableReaderMode` rather than flags, it doesn't block normal tag reading (but if you pass any `NFC_FOO` flag, it does). So if I want to listen for all possible tags, I need to list all the flags? – Erhannis Mar 29 '22 at 15:06
  • 1
    Ndef is really a data format on top of various other communication protocols, so yes Ndef will also use NfcA, NfcB, NfcF or NfcV to communicate to the tag see https://en.wikipedia.org/wiki/Near-field_communication#/media/File:NFC_Protocol_Stack.png . So usually you will just use the complete list I gave in the answer. – Andrew Mar 29 '22 at 16:42
  • @Andrew do we actually need flag FLAG_READER_SKIP_NDEF_CHECK ? Like my suppose to read only NFC A and B cards, so I can remove this flag from list or it is still important? – researcher Apr 22 '23 at 01:56
  • 1
    @researcher NDEF is not the same as A and B which are hardware modulation types, where as NDEF is a data type on top of A and B. If you are not intending to read NDEF then `FLAG_READER_SKIP_NDEF_CHECK` speeds up the system passing on the Tag details to your App (as the system does not try to read the NDEF data on A or B Tags itself). If you skip the check you can still read NDEF yourself just `Ndef.getCachedNdefMessage` won't contain anything. – Andrew Apr 22 '23 at 06:53