Android 拦截最近应用按钮

12
我有一个专为儿童设计的应用程序,我不希望他们能够点击“最近使用的应用”按钮(看起来像两个矩形叠在一起的那个按钮)。我已经处理了返回按钮和主页按钮的捕捉,并且我已经搜索并阅读了很多关于如何捕捉“最近使用的应用”按钮的内容,但大多数说你不能捕捉或者他们的方法非常可疑。
应用程序“Kids Place”弹出一个视图,显示“不允许的操作”,并将您重定向到其主屏幕,如果您按下“最近使用的应用”按钮,即使您在其他应用程序中,这是如何实现的呢?

是的,我有一个主屏幕,并且我使用意图过滤器来处理它。我的问题与“最近使用的应用”按钮有关。 - esse
我知道这不是一个答案,但如果其他方法都失败了,你可以尝试反编译该应用程序并查看它们是如何实现的。 - Shmuel
相关链接:https://dev59.com/XWUq5IYBdhLWcg3wV_Ei?rq=1 - talkol
你想要隐藏你的应用程序不出现在最近使用的应用程序列表中吗? - Swaminathan V
5个回答

22
我找到的目前最好的解决方案是以下内容:
   @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();
        }
    }
}

这需要您使用<uses-permission android:name="android.permission.GET_TASKS" />
当使用这种方法时,当用户按下最近的应用程序按钮时,您的活动将按照以下活动生命周期进行:onPause -> onWindowFocusChanged -> onResume。
对于用户来说,这种行为似乎没有任何响应。注意:我发现如果您快速按下最近的应用程序按钮,它会在短时间内显示该视图。

棘手,但实现了它的承诺 :) 做得好! - Joao Sousa
"com.android.systemui.recent.RecentsActivity" 仅适用于 Android 4.2 - 4.4。请查看我的回复,了解其他 Android 版本的 ClassNames。 - Kirill Karmazin

2
我发现最好的方法是这样做:
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/

这不是我自己的代码,但它可以隐藏最近使用应用程序列表的显示。

我尝试了一下,但在我的Nexus 7上无法运行,SDK版本>=14。 - esse
2
供日后参考:我相信这只适用于三星设备。 - Randy
无法在Android 4.4.4(API 19)三星SM-G357FZ(Ace 4)上运行。 - Tamás Bolvári
每当您的应用程序获得焦点时,此代码将被触发。 - Natan Lotério

2
在被接受的答案中,你仅使用ClassName适用于Android 4.2-4.4。它在5.0及更高版本或Android 4.1上无法工作。
以下是主要Android版本的ClassNames列表:
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")
对你来说最好的解决方案是利用辅助功能服务。重写onAccessibilityEvent()方法,过滤掉上述列出的ClassNames,并在检测到此事件时执行某些操作。例如模拟按下“Home”按钮。您可以通过在辅助功能服务中进行全局操作来实现此目的。

0

感谢 esse 提供了针对更高级 SDK 的解决方案!我错过了这个。

但在我的情况下,我需要复制调用(否则效果不稳定)

        if (SDK>15){
            windowCloseHandler.postDelayed(windowCloserRunnable, 10);
            windowCloseHandler.postDelayed(windowCloserRunnable, 300);
        }

我不得不重新审视这个问题,并遇到了不稳定的问题,感谢您的帖子。 - esse

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接