I want to hide my app from recents programmatically when the user press the home or the task button. The user can decide if the app is persistent in background or not, this setting come from backend so pre-login activities are not to be maintened in recents either case. I tried various solution, some works partially, but none of them work perfectly. I'll list all the methods I used.
1st method. manual task removal: removes every task and kill process
//remove the app from recents. TODO doesn't remove if app list button is pressed instead of home
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
ActivityManager am = (ActivityManager) application.getSystemService(Context.ACTIVITY_SERVICE);
if (am != null) {
List<ActivityManager.AppTask> tasks = am.getAppTasks();
if (tasks != null && !tasks.isEmpty()) {
tasks.get(0).setExcludeFromRecents(true);
}
}
} else {
//TODO API 19
}
//kills the process
android.os.Process.killProcess(android.os.Process.myPid());
This works fairly well, but not when tasks button is pressed and not for API 19 (which I'm targeting)
2nd method: ExitActivity: first solution found on the web.
public class RemoveFromRecentsActivity extends ApplicationLayer {
@Override protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
if(android.os.Build.VERSION.SDK_INT >= 21)
{
finishAndRemoveTask();
}
else
{
finish();
}
}
public static void exitApplicationAndRemoveFromRecent(Context context)
{
Intent intent = new Intent(context, RemoveFromRecentsActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS | Intent.FLAG_ACTIVITY_NO_ANIMATION);
context.startActivity(intent);
}
}
that doesn't work because I'm not calling it from onPause(), so it gets executed after the app has gone to background; I'm sure of this because it starts the dummy activity next time I click on the icon or resume it from recents.
3rd method: override startActivity() with excludeFromRecents="true" in first activity (Splash)
so basically I've an activity which extends AppCompatActivityand all my activities extend it. I've overridden startActivity():
@Override
public void startActivity(Intent intent) {
if (isUserOptIn){
if (intent.getComponent().getShortClassName().equals(HomepageActivity.class.getName())){
intent.addFlags( Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
}
}
super.startActivity(intent);
}
Here I tried to set excludeFromRecents="true" on the splash activity, but if the user has chosen to use the feature, a new task should be created before taking the user to the homepage, but doesn't work. App gets removed from recents anyways.
4th method: override startActivity() with excludeFromRecents="false" in first activity (Splash)
@Override
public void startActivity(Intent intent) {
if (!isUserOptIn){
intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
}
super.startActivity(intent);
}
Here I did the opposite, Splash in maintained in recents and EXCLUDE_FROM_RECENTS is added to every new activity, but it doesn't work. When user has not opt-in, the app is not removed from recents. I also tried intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK); thinking that the app was not being removed because the first activity had excludeFromRecents="false" but didn't work either.
5th method: override startActivity() with excludeFromRecents="true" in first activity (Splash)
if (! isUserOptIn){
intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS );
}
if (intent.getComponent().getShortClassName().equals(HomepageActivity.class.getName())){
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK );
}
Here I set excludeFromRecents="true" in Splash and tried create a new task when opening HomeActivity regardless of user's choice and add FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS to every activity if necessary. This way the app is always removed. Opposite result if I set excludeFromRecents="false", it is always maintained.
It seems like intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK ); it's not working at all.
Anyone has any idea on how to accomplish this?
Android will call
onUserLeaveHint()if it is about to put the app in the background because the user pressed the HOME or TASK button. You can set a flag in that method. Android will next callonPause(), where you can check the flag and if the flag is set you can immediately callfinishAndRemoveTask().You should implement this behaviuour in all activities (or in a base activity that you derive all other activities from).
NOTE: This only works on API 21 and higher
For API < 21 you can probably simulate
finishAndRemoveTask()with something like this:Instead of calling
finishAndRemoveTask(), do this:At the very beginning of
onCreate()of your rootActivity(the one with ACTION=MAIN and CATEGORY=LAUNCHER), do this: