Fix notification open not always resuming app #1277
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Scope
Fix
This fix prevents notification opens affecting the Activity backstack.
Fixes issue where if the app's main Activity was not the last Activity opened tapping on a notification would create another instance of it. Basically this behavior fix aligns with everything an Android Launcher would do.
Solutions
Solution D below was used but all options that were attempted / considered.
A. Android API
Tired searching for a built in Android API that directly resumes the app. This doesn't exist and wasn't expecting it to but looked for completeness.
B. startActivity Intent.FLAG_ACTIVITY_* Flags
I read though the description and tried a few different
Intent.FLAG_ACTIVITY_*
flags to ourstartActivity
in ourstartOrResumeApp
to get the app to resume without affecting the backstack. HoweverFLAG_ACTIVITY_SINGLE_TOP
,FLAG_ACTIVITY_BROUGHT_TO_FRONT
, and some others I tried did not have the resume affected in all cases or not at all.C. Show non-visible Activity
As a "workaround" it is possible to show an non-visible Activity and call
finish()
right away to bring the app forward to then to put the app back to the last Activity. This would require adding anotherActivity
and it would create extraonResume
andonPause
events would be mostly acceptable, but could results in unintended side effects.This something I confirmed as a valid option, but was also discovered by others.
D. Omit package from Intent passed to startActivity
Using
Intent.setPackage(null)
seems to have a side effect of always resuming the app instead of effecting the backstace. I wasn't able to find any official Google documentation on this effect but it does seems to be what Android Launchers depend on. I confirmed this by checking the source of an open source launcher,OpenLauncherTeam/openlauncher
and confirmed package would benull
on theirIntent
.This solution was found here:
https://stackoverflow.com/a/42002705/1244574
I also confirmed that
getLaunchIntentForPackage
in ASOP generates anIntent
that usesIntent.setClassName
that includes both the package name &Activity
name so there is no risk in a different app being started if it happened to have the same fully namespacedActivity
.Based on testing on Android 11 (API 30) (both an emu and Samsung device) using
setPackage(null)
isn't required, the resume behavior works with or without it. I wasn't able to find any documentation on this behavior change so it is unknown if it was intentional.Tests
Automated
Robolectric does not have an API to get the backstack write an integration test for this. The closest thing I could find is
getNextStartedActivity
which would only tell me the call order but none of the behavior changes.Manual
App w/ splash and single Activity (the example app in this repo)
App w/ two Activities, Main Activity A starts B (the example app in this repo but
makeRestartActivityTask
in example removed)Tested on Emulators - Android 11 & 10.
Tested on OnePlus 6T - Android 10
Tested on LG G7 - Android 9
This change is