I'm using pending intent with notification to send a push to my device.
My pending intent contains fields that will be used in my MainActivity
onCreate()
method to handle navigation. After successful navigation to any point in my application I tapping on the back button until my app goes to the background. Right after that my activity instantly invokes onDestroy()
for some reasons (using android emulator API 28). The problem is that after lifting up app to the foreground, PendingIntent still there and my app performs navigation again.
It's really strange. I always thought that intents with FLAG_ONE_SHOT
could be used only once. I also tried to clear intent by myself but it didn't work out too.
My Intent construction
const val NAVIGATION_BUDNLE = "nav_bundle"
private fun createPendingIntent(): PendingIntent? {
val destination = resolveDestionation()
val intent = Intent(context.applicationContext, MainActivity::class.java).apply {
flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_CLEAR_TASK
putExtra(NAVIGATION_BUDNLE, destination)
}
return PendingIntent.getActivity(context, Random.nextInt(), intent, FLAG_ONE_SHOT)
}
At the end of the activity onCreate()
method, I've got these lines to handle navigation.
intent?.extras?.get(NAVIGATION_BUNDLE)?.let {
navController.setGraph(R.navigation.nav_graph, it as Bundle)
clearCurrentIntent() // intent = null and intent?.extras?.remove(NAVIGATION_BUNDLE)
}
Ok, I've got it (great thanks to this answer)! So this behavior can happen if you leave your activity with back button press. In this cases your activity will call onDestroy()
method without calling onSaveInstanceState()
and you will receive same intent over and over again (while clicking back to quit your app, of course). All you need to do is check if your app was called from recent. To do that you can implement this check before your main activity reading your intent:
if (intent.flags and FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY == 0) {
intent?.extras?.get(NAVIGATION_BUNDLE)?.let {
navController.setGraph(R.navigation.nav_graph, it as Bundle)
}
}
Flag FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
will appear if your app is launched from recent and that's a very tiny workaround for this particular problem. If this flag presented just don't read your intent and that's it.