Solution 1:

None of standard Activity Lifecycle methods is called when "Recent Apps" button pressed. Activity will stay active after list of recent apps popups. Through semi-transparent left part of this list you can even observe application animation is still running, if you running a game with some animation that didn't handle this situation properly. Actually many of games in Google Play didn't handle this situation properly, even good ones, like Angry Birds.

The only Activity method are getting called when user opens "Recent Apps" list (or returns from it) is onWindowFocusChanged with boolean parameter hasFocus. When user open list of Recent App method onWindowFocusChanged() called with hasFocus equals false, and same method called with hasFocus equals true when user pressing Back in this list.

Solution 2:

I have same problem, i resolved this problem as below.er

Register button click broadcast for Home and RecentApp

InnerReceiver mReceiver = new InnerReceiver();
IntentFilter mFilter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
registerReceiver(mReceiver, mFilter);

Now BroadcastReceiver code

class InnerReceiver extends BroadcastReceiver {
    final String SYSTEM_DIALOG_REASON_KEY = "reason";
    final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
    final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey";

    @Override
    public void onReceive(Context context, Intent intent) {

        if (intent.getAction().equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) {
            String reason = intent.getStringExtra(SYSTEM_DIALOG_REASON_KEY);
            if (reason != null) {
                if (mListener != null) {
                    if (reason.equals(SYSTEM_DIALOG_REASON_HOME_KEY)) {
                        // Home Button click
                    } else if (reason.equals(SYSTEM_DIALOG_REASON_RECENT_APPS)) {
                        // RecentApp or Overview Button click
                    }
                }
            }
        }
    }
}

But Dont forgot to unregisterReceiver BroadcastReceiver

Solution 3:

To detect when 'Recent apps' button was pressed you can use Accessibility Service. You'll need to run your own Accessibility Service and receive events with type "TYPE_WINDOW_STATE_CHANGED" and check event's class name.

  1. Read about Accessibility Service in android developer. Set up your own Accessibility Service, ask for permission from user.
  2. In your Accessibility Service override method onAccessibilityEvent()
  3. In this method you will receive AccessibilityEvent event object, this object contains all necessary information about an event that have just happened on your device.
  4. We are interested in the ClassName. ClassName sometimes can be null so don't forget about != null check. Package names of Recent apps window will vary depending on the version of Android:

    • Android 4.1: "com.android.internal.policy.impl.RecentApplicationsDialog"
    • Android 4.2 - 4.4: "com.android.systemui.recent.RecentsActivity"
    • Android 5.0 - 7.1: "com.android.systemui.recents.RecentsActivity" ("s" letter was added)

Don't know the class name for older devices but I don't think someone maintains them in 2017 ;)

So you will have something like this:

@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
    if (event.getEventType() != AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED || event.getClassName() == null) 
        return;

    String className = String.valueOf(event.getClassName());

    if (className.equals("com.android.internal.policy.impl.RecentApplicationsDialog")
            || className.equals("com.android.systemui.recent.RecentsActivity")
            || className.equals("com.android.systemui.recents.RecentsActivity")){
        //Recent button was pressed. Do something.
    }
}

I've tested it on the following real devices: LG, Nexus, Sony and virtual devices: Motorola, Samsung.

If someone knows exception for these class names please ping me.

Solution 4:

I faced similar problem, so, I needed to know when the user press the recent apps button (menu key button in old versions of android). After a several hours of research I didn't found an event to catch when the home button or the menu button is pressed. I found that it's take a longer time to call onStop() when the user press the home button, so I figured out a trick to distinguish between these tow buttons relating on time of response and overriding two methods:

@Override

public void onUserLeaveHint() {
    // do stuff
    super.onUserLeaveHint();
    userLeaveTime = System.currentTimeMillis() ;
    isNotPower = true;
}

@Override

public void onStop() {
    super.onStop();
    if (isNotPower) {
        defStop = System.currentTimeMillis() - userLeaveTime;
        if (defStop > 200 ) {
            //home button
        }
        if (defStop < 200) {
            //recent apps button
        }
    }
    isNotPower = false;
}
  • The isNotPower parameter that's to check that not the power button is pressed- when the power button pressed the onStop() method is called but not the onUserLeaveHint().

Solution 5:

The best way I have found is listent to Broadcast Action called "ACTION_CLOSE_SYSTEM_DIALOGS".From the Google docs:

Broadcast Action: This is broadcast when a user action should request a temporary system dialog to dismiss. Some examples of temporary system dialogs are the notification window-shade and the recent tasks dialog.

Working code:

IntentFilter intentFilterACSD = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);

    BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) {
                    //do what you want here
            }
        }
    };
    this.registerReceiver(broadcastReceiver, intentFilterACSD);