I have a react-native app which reads NFC tags and writes a URL to them.
It uses ForegroundDispatch
to make sure the app captures the scanned info and doesn't navigate away to the browser when the link is detected. The link is used only when the app is not launched, it opens a browser and shows information from my server to the external user.
When I'm in the app and I turn the screen off (power button), then turn it back on again and scan an NFC tag, the browser opens up. It looks like the scanned intent doesn't deliver to the app and is instead handled by the phone as default. After the first scan, which opens the browser, I navigate back to the app and the following scans work fine inside the app.
Here is the twist: on most phones it works as expected. Works on Pixel 3 (Android 9), on Huawei (Android 5.1) on Sony (Android 7) an a few others. But when I use UleFone X2 (http://ulefone.com/product.html) this issue occurs. Am I doing something incorrectly to initialize the app so it handles itself the same every time, even when it's resumed?
From my research it looks like UleFone disables NFC when the screen goes off and when it turns back on, am I not initializing it properly? If I open the recent apps and navigate away from my app, then back into it, the NFC starts working.
This is my main activity:
public class MainActivity extends ReactActivity {
private NfcAdapter mAdapter;
private PendingIntent mPendingIntent;
private IntentFilter[] mFilters;
private String[][] mTechLists;
private int mCount = 0;
@Override
public void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
}
@Override
protected void onCreate(Bundle savedState) {
super.onCreate(savedState);
mAdapter = NfcAdapter.getDefaultAdapter(this);
mPendingIntent = PendingIntent.getActivity(this, 0,
new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
try {
ndef.addDataType("*/*");
} catch (MalformedMimeTypeException e) {
throw new RuntimeException("fail", e);
};
mFilters = new IntentFilter[] {
ndef,
};
mTechLists = new String[][] { new String[] {NfcA.class.getName()}, new String[] {MifareClassic.class.getName()}, new String[] {Ndef.class.getName()}, };
Log.d("scantest", "onCreate completed");
}
@Override
protected void onPause() {
super.onPause();
if (mAdapter != null) mAdapter.disableForegroundDispatch(this);
Log.d("scantest","onPause completed");
}
@Override
public void onResume() {
super.onResume();
Intent intent = getIntent();
if (mAdapter != null) mAdapter.enableForegroundDispatch(this, mPendingIntent, mFilters, mTechLists);
Log.d("scantest","onResume completed");
}
Expected behaviour: All Android phones that support NFC handle NFC scanning in the app the same way, on launch and after it is resumed. The intent should always deliver to my app.
Current behaviour: Most phones work fine after screen goes off/on again. On some phones (UleFone) if I turn the screen off/on, the first scan opens the browser, and the following ones work inside the app.
Current workaround:
After turning screen off/on, if I navigate away from the app using recent apps (I don't even have to click on another app, just have to make sure the recent apps tiles come up) then click to go back to my app, NFC doesn't fail on the first scan.
Otherwise the first scan fails and opens the browser.