Block/disable recent apps button

拈花ヽ惹草 提交于 2019-11-28 04:46:47
Aritra Roy

Doing this is not at all difficult. I have implemented it in one of my apps, and it works perfectly.

Step 1

Add this permission to the manifest.xml file

<uses-permission android:name="android.permission.REORDER_TASKS" />

Step 2

Put this code in any Activity on which you want to block/disable the recent apps button

 @Override
 protected void onPause() {
        super.onPause();

        ActivityManager activityManager = (ActivityManager) getApplicationContext()
                .getSystemService(Context.ACTIVITY_SERVICE);

        activityManager.moveTaskToFront(getTaskId(), 0);
}

I have tried in several devices and it is working perfectly. Pressing the recent apps button may turn the screen black for less than a second but will bring your activity back again.

tallpaul

This answer helped me. It is not the best as some methods are now deprecated. It works for me (4.4.2), for now, but I too would like to find a more ideal solution.

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

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

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();
        }
    }
};

With this permission:

<uses-permission android:name="android.permission.GET_TASKS" />

@Tazz You just cannot. Impossible.

Yes, it is frustrating, OSes are sometimes. I often encounter issues like this in needing advanced designs, here you hit a wall. OS does not provide the feature, it is out of your developer power. It is annying but t-r-u-e, you cannot. Even a bounty wont turn SDK into Magic.

Eventually AND if your app is dedicated to inhouse devices - not publications - you can change code in Android SDK - it is opensource. If you intend to publish on the Play store, it is just useless.

You can create a black list,and add "com.android.systemui" in it.then start a service,open infinite loop to check the TopPackageName,if that blacklist contains it,start you own activity. if is not clearly,sorry for my bad english.

and the code:

public class MyService extends Service{
private HashSet<String> blackPackages = new HashSet<String>();

@Override
public void onCreate() {
    m_black_packages.add("com.android.systemui");

    while(true){
        if(blackPackages.contains(getTopPackage(MyApplication.context)){
        //start you own activity
        }
    }
}

public String GetTopPackage(Context context) {
    int version=android.os.Build.VERSION.SDK_INT;
    if(version>=21)
    {
        long ts = System.currentTimeMillis();
        UsageStatsManager mUsageStatsManager = (UsageStatsManager) context.getSystemService("usagestats");
        List<UsageStats> usageStats = mUsageStatsManager.queryUsageStats(
                UsageStatsManager.INTERVAL_BEST, ts - 86400000,     
                ts);
        if (usageStats == null || usageStats.size() == 0) {
            return getTopPackageLegacy(context);
        }
        Collections.sort(usageStats, mRecentComp);
        return usageStats.get(0).getPackageName();
    }
    else
    {
        return getTopPackageLegacy(context);
    }
}

public String getTopPackageLegacy(Context context) {
    ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
    @SuppressWarnings("deprecation")
    List<RunningTaskInfo> tasks = am.getRunningTasks(1);
    if (tasks.size() == 0) {
        return null;
    }
    RunningTaskInfo task = tasks.get(0);
    ComponentName cn = task.topActivity;
    String package_name = cn.getPackageName();
    return package_name;
}

private static class RecentUseComparator implements Comparator<UsageStats> {

    @Override
    public int compare(UsageStats lhs, UsageStats rhs) {
        return (lhs.getLastTimeUsed() > rhs.getLastTimeUsed()) ? -1
                : (lhs.getLastTimeUsed() == rhs.getLastTimeUsed()) ? 0 : 1;
    }
}

}

this is not original code,but something like that.

public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);
    if(!hasFocus) {

        Intent closeDialog = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
        sendBroadcast(closeDialog);
    }
}
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);
    }
}

This is better probably but still haven't found anything close for disabling the button!

An easy trick that worked for me (in a Samsung Galaxy S6) is to launch again the Activity when onStop() is called, because your Activity will call onStop() when user tap on recent apps button.

@Override
public void onStop() {
    startActivity(new Intent(context, YourActivity.class));
}

It is recommended to mark your Activity as singleInstance to avoid multiple app instances:

android:launchMode="singleInstance"
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!