I have an annoying issue with the foreground dispatch behavior. Sometimes instead of calling onNewIntent()
, it completely recreates the activity, which breaks the app's workflow.
My concrete situation: Activity A is the MainActivity, which uses the foreground dispatch. Everything works as it should. However, in my activity B, which is launched from the browser (VIEW action), the foreground dispatch doesn't work under some circumstances anymore.
The workflow:
I start the MainActivity, switch to the browser (without closing the MainActivity), launch activity B and attach my NFC device --> it creates a new activity B.
I start the MainActivity and close it again. After that I switch
to the browser, launch activity B and attach my NFC device -->
everything works with onNewIntent()
The code is correct, e.g. if I attach the NFC device in the first scenario twice, it works as it should at the second time, but not at the first time. In the MainActivity and activity B I definitively call the disableForegroundDispatch() method in the activity's onPause() method.
Is there a solution for my specific problem? For me it sounds like a bug.
Edit:
public void resume(Activity targetActivity) {
if (nfc != null && nfc.isEnabled()) {
// nfc is the default NFC adapter and never null on my devices
Intent intent = new Intent(targetActivity, targetActivity.getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(targetActivity, 0, intent, 0);
nfc.enableForegroundDispatch(targetActivity, pendingIntent, null, new String[][] { new String[] { IsoDep.class.getName() } });
}
}
public void pause(Activity targetActivity) {
if (nfc != null && nfc.isEnabled()) {
nfc.disableForegroundDispatch(targetActivity);
}
}
These methods are called in the corresponding methods in each activity. Thanks for the help!
Solution: After a very long research I finally found the issue. Logcat printed:
I found other issues at Stackoverflow, where people had have the same issue with the NotificationManager, but all the hints didn't help me. Adding the flag singleTask to my activity B did the trick for me, but to be honest I don't understand it, because the context is always an activity.
I removed all the code from the MainActivity and the first scenario still didn't work. I romved the MainActivity from the manifest and after that everything was fine. Maybe it is a problem, that an app instance is running and activity B is launched from the browser? I don't know.
Anyway, thanks for the help NFC guy!
The IntentFilter[]
that you pass to enableForegroundDispatch
is empty. So your NFC intent probably arrive at your Activity due to the IntentFilter(s) in the manifest file. This explains the behaviour you observe, as an NFC intent always creates a new instance when delivered this way.
Add something like this instead to your code for enabling foreground dispatch:
IntentFilter[] iFilters = new IntentFilter[2];
iFilters[0] = new IntentFilter();
iFilters[0].addAction("android.nfc.action.TECH_DISCOVERED");
iFilters[1] = new IntentFilter();
iFilters[1].addAction("android.nfc.action.TAG_DISCOVERED");
iFilters[1].addCategory(Intent.CATEGORY_DEFAULT);
And pass that as parameter to enableForegroundDispatch
.
UPDATE: I recently learned more about this specific problem. It is caused by the way Android determines in which task a new Activity should be launched. I don't know or understand the specific details of how that works, but the effect is that:
Because of 2., the SINGLE_TOP is not ignored: there is only one instance of Activity B at the top of A's task. When Activity A is closed, it's task has disappeared, so Activity B will always be created in the Browser's task, as you have observed.
You may feel that this is an Android bug in this case (I do, I think), but this behaviour of how to create activities in which task is so fundamental to Android that many apps rely on it. So it is very unlikely that this will ever change.
Possible work-around: declare Activity B with launchMode
"singleTask" (or "singleInstance"). Then a new (3rd) task will be created when B is launched.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With