Reader mode or foreground dispatch: which one should an Android app use?
Reader mode, for a screen whose purpose is reading tags. It hands each tag straight to a callback, can skip the system's NDEF check and sound, and suspends card emulation while it runs. Foreground dispatch suits an app that meets tags occasionally and wants them delivered as intents, like the rest of its input.
What both do
Both give the activity on screen first claim on the next tag, ahead of every app that registered for tags in its manifest. The NfcAdapter reference describes foreground dispatch as giving priority to the foreground activity, and reader mode as limiting the controller while the activity is in the foreground.
Neither outlives the activity leaving the screen. Foreground dispatch must be enabled while the activity is resumed and disabled before its onPause completes, and calling it while the activity is not in the foreground throws IllegalStateException.
And neither changes what happens when the app is closed. A tag that should start the app goes through the manifest, covered on the manifest page.
What reader mode changes
Reader mode turns the controller into a reader and nothing else. The reference states that it disables peer to peer and card emulation for as long as it runs, so a user who opens your reading screen at a checkout cannot pay with the phone until they leave it.
It polls only the technologies you name, through flags such as FLAG_READER_NFC_A or FLAG_READER_NFC_V. A screen built for ISO/IEC 15693 labels that polls NFC-V alone does not react to a bank card held next to it.
FLAG_READER_SKIP_NDEF_CHECK stops the platform reading the tag for NDEF before your callback runs. The reference is explicit about the cost: the Ndef class is then not enumerated on the tag, and NDEF based dispatch does not work. It is the flag for a screen that sends its own commands, and the wrong one for a screen that reads messages.
FLAG_READER_NO_PLATFORM_SOUNDS silences the system's discovery sound, which leaves your app responsible for telling the user that something happened. The EXTRA_READER_PRESENCE_CHECK_DELAY extra sets the delay the platform uses to check that the tag is still there.
Tags arrive through onTagDiscovered rather than as intents. From API level 37 the callback also has onTagLost, called when the tag leaves; before that level, a departure shows up as an exception on the next exchange.
For a phone that emulates a card through host card emulation, the reference recommends FLAG_READER_NFC_A together with FLAG_READER_SKIP_NDEF_CHECK.
What foreground dispatch keeps
Foreground dispatch changes who receives the tag and little else. The platform still reads the tag for NDEF and still plays its discovery sound, the flag that silences it belonging to reader mode, and nothing in the reference suspends card emulation while it is enabled.
The tag arrives as an intent, through the PendingIntent you pass. The Advanced NFC guide builds it with FLAG_MUTABLE, because the system has to add the tag to the intent, and since Android 12 the PendingIntent reference requires every PendingIntent to declare its mutability. The same example adds FLAG_ACTIVITY_SINGLE_TOP, so the tag reaches the open activity in onNewIntent instead of starting a second copy.
Filters and technology lists narrow what the activity receives, with the same rules as the manifest. Passing null for both makes the activity receive every tag through ACTION_TAG_DISCOVERED, an action the reference marks as deprecated from API level 37.
The delivery lands in onNewIntent, and the processes and threads guide says lifecycle callbacks always run on the main thread. Any exchange with the tag has to move elsewhere, since the TagTechnology reference forbids I/O on that thread.
Choosing between them
| Question | Reader mode | Foreground dispatch |
|---|---|---|
| How the tag arrives | A callback, onTagDiscovered | An intent, in onNewIntent |
| Card emulation while active | Suspended | Unchanged |
| Technologies polled | Only those named by flags | All |
| System NDEF check and sound | Can be skipped | Always performed |
| Available from | API level 19 | API level 10 |
Choose reader mode when the screen exists to read tags: a stock check, a configuration tool, a reader for a proprietary card. The tag goes straight to your code and nothing else on the phone competes for it.
Choose foreground dispatch when tags are one input among others, and the phone should keep paying and behaving normally while your activity is open.
Frequently asked questions
Why does the phone stop paying while my app is open?
Reader mode is enabled. The reference states that it disables card emulation for as long as the activity is in the foreground, so reserve it for screens whose purpose is reading.
Which flags should I use to read another phone?
For a phone emulating a card through host card emulation, the reference recommends FLAG_READER_NFC_A together with FLAG_READER_SKIP_NDEF_CHECK.
Do I still need intent filters in the manifest?
Only for tags that should start the app when it is not open. Neither reader mode nor foreground dispatch applies until an activity is on screen.
Why does enableForegroundDispatch throw IllegalStateException?
It was called while the activity was not in the foreground, for instance from onCreate. Enable it in onResume and disable it in onPause.