Search code examples
androidbroadcastreceivertask-switching

Is there a way to handle the task switcher active?


So our app is handling when the app goes to background via this hack found elsewhere:

 public static boolean isAppGoingToBackground(Context context)
    {
        boolean retVal = false;
        ActivityManager mgr = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningTaskInfo> runningTasks = mgr.getRunningTasks(1);
        if (!runningTasks.isEmpty())
        {
            // If the package name of the current activity doesn't equal the context's
            // package name, then the user is no longer in the context's app.
            ComponentName currentActivity = runningTasks.get(0).topActivity;
            retVal = !currentActivity.getPackageName().equals(context.getPackageName());
        }
        return retVal;
    }

However this doesn't handle if the screen is turned off via the power button, so we added a broadcast receiver for that event:

_receiver = new BroadcastReceiver()
        {
            @Override
            public void onReceive(Context context, Intent intent)
            {
                if(intent.getAction() == Intent.ACTION_SCREEN_ON)
                {
                    //resume
                }
                else if(intent.getAction() == Intent.ACTION_SCREEN_OFF)
                {
                    handleAppGoingToBackground(_context);
                }
            }
        };

However neither of these give the correct response when users background the app using the task switcher:

enter image description here

If you background the app in this manner, the isGoingToBackground returns false. I was hoping there was another event in the broadcast receiver I could use to handle this event, but I haven't found anything. Is there anyway to know within your app when it is backgrounding in this manner?


Solution

  • OK so I got a working solution, I took a little different approach to using the getTasks call as it's deprecated. This seems to work for everything I've tested so far, but I'll continue to test to see if I have any other problems. Essentially all my activities have a super class defined as such:

    public abstract class BaseActivity extends AppCompatActivity
    {
        boolean isStartingActivity = false;
        boolean appWentToBackground = false;
        @Override
        protected void onPostResume()
        {
            super.onPostResume();
    
            if (appWentToBackground) 
            {
                appWentToBackground = false;
                handleAppComingToForeground();
            }
        }
    
        @Override
        protected void onStop()
        {
            super.onStop();
            if (!isFinishing() && !isStartingActivity && getChangingConfigurations() == 0)
            {
                appWentToBackground = true;
                //If all of the above is true the app must be going to background
                handleAppGoingToBackground();
            }
            isStartingActivity = false;
        }
    
        @Override
        public void startActivityForResult(Intent intent, int requestCode, Bundle options)
        {
            isStartingActivity = true;
            super.startActivityForResult(intent, requestCode, options);
        }
    
        @Override
        public void startActivityFromFragment(Fragment fragment, Intent intent, int requestCode)
        {
            isStartingActivity = true;
            super.startActivityFromFragment(fragment, intent, requestCode);
        }
    }
    

    The thought process is ChangingConfigs check handles rotation, isFinishing handles back pressed (it doesn't handle going back to the point of being in another app, but that case is OK in my situation), and isStartingActivity handles the case I'm transitioning to another activity, if all those conditions are met it must mean I'm backgrounding in some form or another (works for me for app switcher and normal background).

    I'll update if I notice anything else that could use improvements, or cases I missed.