I am currently working on a simple app, which scans an NFC tag and reads the data from it. To implement it, I followed this example here.
For testing, I am using a real android device (Samsung Galaxy J6) and a Mifare NFC card.
At the launch of the app, everything seems fine, the NfcManager has been successfully started, the tag event has been registered (using NfcManager.registerTagEvent),but the problem occurs when requestTechnology has been called and the NFC card scanned.
The difference I noticed is regarding the intent in Android: before running requestTechnology and scanning the card against the phone, the intent and the action attached to it look like this => the action is on the main thread.
After that, the intent and the action look like this.
It seemed strange to me that the action has changed from the main thread.
The Android code is exactly like given in the link above and the code in React Native looks like this:
_read = async () => {
try {
const enabled = await NfcManager.isEnabled();
console.warn('Enabled: ', enabled);
await NfcManager.registerTagEvent((tag) => {
console.warn('Tag Discovered', tag);
}, 'Hold your device over the tag', true);
let tech = Platform.OS === 'ios' ? NfcTech.MifareIOS : [NfcTech.MifareClassic, NfcTech.NfcA];
let resp = await NfcManager.requestTechnology(tech);
let tag = await NfcManager.getTag()
.then(() => { console.warn('Tag: ', tag)})
.catch((err) => console.warn('Tag error: ', err));
{...}
// this._cleanUp();
} catch (ex) {
console.warn(ex);
this._cleanUp();
}
}
Besides that, the method requestTechnology is resolved only if the app is brought to the background and then again to the foreground right away. That also seems strange ...
Does anyone have any idea how to solve these issues and get the NFC card reading process up and running?
I appreciate your help!
I'm not sure why you are looking at the
IntentAction as it is of no significance to NFC really.Some background of how Android handles NFC should help explain it.
In Android all Tag detection is handled by a System NFC service/App.
When you App is not running and a NFC Tag is detected the System Service works out if any App has requested to be started when that type of Tag is seen. It then crafts an Intent to get the
System Launcherto launch the main Activity of you app and bundles information about the NFC data in the extras section of theIntentfor the System Launcher to pass on in the Intent to your app at Launch time.When you are doing
requestTechnologyyour App is already running and you are telling the System NFC Service to pass the NFC data directly to your App, the System Launcher does not need to be involved as your App is already running.Now Android has two methods of passing this data directly to your running App,
enableForegroundDispatchor the later and much betterenableReaderMode.You configured
react-native-nfc-managerto use the olderenableForegroundDispatchwhich tells the system NFC service to send the Tag details directly to your running Activity. So it does not need to add an Action to tell the system Launcher what to do. But to deliver thatIntentwith the extras contain data about the Tag directly to your App, the only way for it to do that is to basically restart your App which causes aPauseandResume.But
react-native-nfc-managerhandles all this for you, so you should not need to worry about what is in theIntentNote you can configure
react-native-nfc-managerto useenableReaderModeand instead of overloading an Intent to deliver this data to you, if basically creates a Thread in your running App and gives the Thread the Tag data directly and thus does not need to pause and resume your App (plus you get more control of things like NFC detection sound with this newer method)So overall the behaviour you are seeing is expected and normal and nothing you should be concerned about or have a problem with.
Note iOS handles this completely differently but again
react-native-nfc-managerhandles this via it's iOS specific methods.