12

I have an application meant for children and I do not want them to be able to click the "Recent Apps" button (the one that looks like two rectangles on top of each other). I am taking care of capturing the back button and the home button and I have searched and read a lot about about trying to capture the Recent Apps button, but most say you cannot or the way they do it is very questionable.

The App "Kids Place" pops up a view that says "Action Not Allowed" and redirects you to its home screen if you press the Recent Apps button, this works even if you are in a different app, so how are they doing this?

Any suggestions, hints would be appreciated.

Thanks.

esse
  • 5,429
  • 3
  • 19
  • 20
  • Yes, I have a home screen and I take care of that with an intent-filter. My question is with regard to the "Recent Apps" button. – esse Jul 21 '13 at 05:38
  • I know this isn't an answer, but if all else fails you can try decompiling that app and see how they do it – Shmuel Jul 21 '13 at 06:13
  • Related: http://stackoverflow.com/questions/14574239/how-to-disable-the-recent-tasks-apps-button-in-android?rq=1 – talkol Jul 21 '13 at 08:12
  • do you want to hide your app from recent apps.? – Swaminathan V Dec 30 '15 at 13:28

5 Answers5

22

After lots of searching and coding the current best solution I found is the following:

   @Override
public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);

    if (!hasFocus) {
        windowCloseHandler.postDelayed(windowCloserRunnable, 0);
    }
}

private void toggleRecents() {
    Intent closeRecents = new Intent("com.android.systemui.recent.action.TOGGLE_RECENTS");
    closeRecents.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
    ComponentName recents = new ComponentName("com.android.systemui", "com.android.systemui.recent.RecentsActivity");
    closeRecents.setComponent(recents);
    this.startActivity(closeRecents);
}

private Handler windowCloseHandler = new Handler();
private Runnable windowCloserRunnable = new Runnable() {
    @Override
    public void run() {
        ActivityManager am = (ActivityManager)getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
        ComponentName cn = am.getRunningTasks(1).get(0).topActivity;

        if (cn != null && cn.getClassName().equals("com.android.systemui.recent.RecentsActivity")) {
            toggleRecents();
        }
    }
}

This requires that you use <uses-permission android:name="android.permission.GET_TASKS" />

When using this approach when the user presses the recent apps button it will cause your activity will go through the activity lifecycle as follows: onPause -> onWindowFocusChanged -> onResume.

To the user the behavior appears that pressing the recent apps button has no response. NOTE: that I have found that if you press the recent apps button quickly it will display that view for brief time.

This is not the best solution, but it is a stab at it. If you have a better solution please share.

esse
  • 5,429
  • 3
  • 19
  • 20
2

The best way I have found is to do this:

public class BaseActivity extends Activity {
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);

            Log.d("Focus debug", "Focus changed !");

        if(!hasFocus) {
            Log.d("Focus debug", "Lost focus !");

            Intent closeDialog = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
            sendBroadcast(closeDialog);
        }
    }
}// all credit goes here: http://www.juliencavandoli.com/how-to-disable-recent-apps-dialog-on-long-press-home-button/

This is not my own code, but this just hides the recent apps list from showing.

Quintin Balsdon
  • 5,484
  • 10
  • 54
  • 95
2

In the accepted answer you're using ClassName only for Android 4.2 - 4.4. It won't work on 5.0 and higher, or Android 4.1.

Here is the list of ClassNames for main Android versions:

  • 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)

The best solution for you will be to utilize Accessibility Service. Override onAccessibilityEvent() method, filter out ClassNames listed above and do something when you detect this event. For example simulate pressing the 'Home' button. You can do this by making a global action in Accessibility Service.

Kirill Karmazin
  • 6,256
  • 2
  • 54
  • 42
0

thanks esse for solution for higher SDK! I missed it.

But in my case I need to duplicate call (or effect is unstable)

        if (SDK>15){
            windowCloseHandler.postDelayed(windowCloserRunnable, 10);
            windowCloseHandler.postDelayed(windowCloserRunnable, 300);
        }
djdance
  • 3,110
  • 27
  • 33
0

If you are interested in disabling all system buttons, may be the option would be to kill system bar completely, see Easy way to hide system bar on Android ICS

Community
  • 1
  • 1
Miros
  • 1
  • 2