I'm working on an open source app, and these are my requirements for when the root activity is launched:
App needs to always be single task to prevent invalid states occurring via some shared data
When started via launch intents, user should go back to the Activity at top of any previous task
When launched via ACTION_VIEW (e.g. via file manager) user should be taken to the root activity, all previous history cleared, and the intent handled properly by importing the file.
Clearly requirement 2 prohibits using android:launchMode="singleTask"
in manifest, and I have no control over what flags are included in the external intent.
I can handle requirements 1 and 2 by finishing the activity if !isTaskRoot()
. Handling requirement 3 is trickier; after much strife I have found that relaunching the intent with the inclusion of the flag FLAG_ACTIVITY_CLEAR_TOP
kind of works, with the caveat that isTaskRoot()
doesn't seem to return true until the other Activity has finished, so I had to introduce a hack to see if the Activity is going to be root soon, or else the app freezes for several seconds before proceeding.
Anyway, here's the code; any less hacky solution satisfying all requirements would be much appreciated.
@Override
protected void onCreate(Bundle savedInstanceState) {
Intent intent = getIntent();
if (!isTaskRoot() &&
(intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_TOP) == 0) {
// App freezes for a while without hack in second condition above
super.onCreate();
Intent reloadIntent = new Intent(RootActivity.this, RootActivity.class);
if (intent.getExtras() != null) {
reloadIntent.putExtras(intent.getExtras());
}
if (intent.getData() != null) {
reloadIntent.setData(intent.getData());
}
String action = intent.getAction();
switch (action) {
case Intent.ACTION_VIEW:
// Go back to previous task & take user to root, clearing history
reloadIntent.setAction(intent.getAction());
reloadIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
finish();
startActivity(reloadIntent);
break;
default :
// Go back to the top of previous task without clearing history
reloadIntent.setAction(Intent.ACTION_MAIN);
reloadIntent.addCategory(Intent.CATEGORY_LAUNCHER);
reloadIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
finish();
startActivityIfNeeded(reloadIntent, 0);
break;
}
} else {
// Normal onCreate() method for when launched as root
// Import file specified by intent.getData().getEncodedPath()
}
}