Android,如何清除最近的任务列表,可以从主页button在大多数手机? 反思是一种可能的方式?

我正在写一个启动器,它需要从系统清除最近的应用程序/任务列表,而不是“没有显示我的应用程序在最近的任务列表”,但我现在不知道。 我已经在stackoverflowsearch,只有这个问题是匹配的,但答案没有任何帮助。 其他一些人也提出了相同的问题,他提到了来自Android 4.0的RemoveTask。 是的,我已经检查了Android 2.3.7和Android 4.0的源代码,估计我估计可以达到终点,如果我可以删除ActivityMangerService.Java中定义的mRecentTasks列表:

final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 

另一个可能的定义是:

 static ActivityManagerService mSelf; public static ActivityManagerService self() { return mSelf; } 

因为我不熟悉Java和refelction,所以我需要关于清单的方法帮忙,下面是我的代码:

  public static <T> void clearRecentTaskList(Launcher launcher){ ActivityManager am = (ActivityManager) launcher.getSystemService(Context.ACTIVITY_SERVICE); Object systemRecentTask = new ArrayList<T>(); Object receiver = null; Field recentTaskList = null; Class<?> service = null; Field self = null; try { service = Class.forName("com.android.server.am.ActivityManagerService"); Log.d(LOG_TAG, "clearRecentTaskList, service gotton"+service.getName()); } catch (ClassNotFoundException e2) { Log.d(LOG_TAG, "clearRecentTaskList, class service not found"); } try { self = service.getDeclaredField("mSelf"); } catch (SecurityException e2) { Log.d(LOG_TAG, "clearRecentTaskList, SecurityException during get mSelf"); } catch (NoSuchFieldException e2) { Log.d(LOG_TAG, "clearRecentTaskList, NoSuchFieldException during get mSelf"); } Log.d(LOG_TAG, "clearRecentTaskList, self gotton " + self.toGenericString()); try { self.setAccessible(true); receiver = self.get(null); } catch (IllegalArgumentException e2) { Log.d(LOG_TAG, "clearRecentTaskList, IllegalArgumentException during use self to get the receiver"); } catch (IllegalAccessException e2) { Log.d(LOG_TAG, "clearRecentTaskList, IllegalAccessException during use self to get the receiver"); } if ( receiver != null){ Log.d(LOG_TAG, "clearRecentTaskList, receiver is : "+receiver.toString()); } else { Log.d(LOG_TAG, "clearRecentTaskList, receiver is NULL"); } try { recentTaskList = service.getDeclaredField("mRecentTasks"); recentTaskList.setAccessible(true); Log.d(LOG_TAG, "clearRecentTaskList, recentTaskList gotton"+recentTaskList.toGenericString()); try { systemRecentTask = recentTaskList.get(receiver); } catch (IllegalArgumentException e1) { Log.d(LOG_TAG, "IllegalArgumentException during try to clearRecentTask"); } catch (IllegalAccessException e1) { Log.d(LOG_TAG, "IllegalAccessException during try to clearRecentTask"); } Log.d(LOG_TAG, "Try to print the size of recent task: "+((ArrayList<T>) systemRecentTask).size()); } catch (SecurityException e) { Log.d(LOG_TAG, "SecurityException during try to clearRecentTask"); } catch (NoSuchFieldException e) { Log.d(LOG_TAG, "NoSuchFieldException during try to clearRecentTask"); } } 

有了这个函数,我总是遇到“NullPointerException”,因为接收者是自己得到的null。 我试过另一种方式(如果我删除所有的try / catch):

 self = service.getDeclaredMethod("mSelf", null); receiver = self.invoke(null, null); // mSelf is a static method which in ActivityMangerService class 

同样的结果,我无法得到ActivityManagerService的实例,然后我无法得到mRecentTasks。 任何意见是赞赏,虽然我不知道“如何删除此列表中的所有项目”,但它可能是另一个问题。

谢谢。

虽然我可以编辑我以前的答案,但是我在另一个项目中使用的这个解决scheme是非常全面的(更容易),所以最好重新开始。

在这种情况下,我简单地使用了reflection来访问ActivityManager的removeTask()方法,并且将所有这些包装到MyActivityManager的便捷类中,如下所示:

 import java.lang.reflect.Method; public class MyActivityManager { private ActivityManager mActivityManager = null; private Method mRemoveTask; public MyActivityManager(Context context) { try { Class<?> activityManagerClass = Class.forName("android.app.ActivityManager"); mActivityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); mRemoveTask = activityManagerClass.getMethod("removeTask", new Class[] { int.class, int.class }); mRemoveTask.setAccessible(true); } catch ( ClassNotFoundException e ) { Log.i("MyActivityManager", "No Such Class Found Exception", e); } catch ( Exception e ) { Log.i("MyActivityManager", "General Exception occurred", e); } } /** * If set, the process of the root activity of the task will be killed * as part of removing the task. */ public static final int REMOVE_TASK_KILL_PROCESS = 0x0001; /** * Completely remove the given task. * * @param taskId Identifier of the task to be removed. * @param flags Additional operational flags. May be 0 or * {@link #REMOVE_TASK_KILL_PROCESS}. * @return Returns true if the given task was found and removed. */ public boolean removeTask(int taskId, int flags) { try { return (Boolean) mRemoveTask.invoke(mActivityManager, Integer.valueOf(taskId), Integer.valueOf(flags) ); } catch (Exception ex) { Log.i("MyActivityManager", "Task removal failed", ex); } return false; } public void clearRecentTasks() { List<RecentTaskInfo> recents = mActivityManager.getRecentTasks(1000, ActivityManager.RECENT_IGNORE_UNAVAILABLE); // Start from 1, since we don't want to kill ourselves! for( int i=1; i < recents.size(); i++ ) { removeTask( recents.get(i).persistentId, 0); } } } 

然后,当我想清除最近的任务时,我执行以下操作:

 new MyActivityManager(this).clearRecentTasks(); 

这可能是一个或两个这些工作需要:

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

在我的情况下,应用程序与系统权限一起安装。

我发现的最好的方法是做到这一点:

 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/ 

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

关于如何在这个问题上这样做有一些很好的线索:

改变getRecentTasks的结果

在这之后,我为了自己的目的采取了以下的方式(类似的情况,平板电脑借给人,然后有人必须“清除历史”,然后把它交给下一个人)。

首先,在我的清单中,我创build了18个这样的任务:

 <activity android:name=".nul.Null0" android:enabled="false" android:excludeFromRecents="false" android:exported="false" android:label="n0" android:launchMode="singleInstance" android:stateNotNeeded="true" android:taskAffinity="" android:theme="@android:style/Theme.Translucent.NoTitleBar" > <intent-filter> <action android:name="com.morphoss.blah.welcome.nul.Null0" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> 

其次,在助手为下一个使用平板电脑的人启动“欢迎屏幕”时启动的AsyncTask中,在清除浏览器历史logging和Cookie后,我执行以下操作:

 try { PackageManager pm = getPackageManager(); ComponentName cn; Intent nullActivity; for( int i=0; i<19; i++ ) { cn = new ComponentName("com.morphoss.blah.welcome","com.morphoss.blah.welcome.nul.Null"+i); pm.setComponentEnabledSetting(cn, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP); nullActivity = new Intent(); nullActivity.setComponent(cn); nullActivity.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(nullActivity); Thread.sleep(20); } Thread.sleep(100); for( int i=0; i<18; i++ ) { cn = new ComponentName("com.morphoss.blah.welcome","com.morphoss.blah.welcome.nul.Null"+i); pm.setComponentEnabledSetting(cn, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP); } } catch( Exception e) { if ( Constants.LOG_DEBUG ) Log.d(TAG,Log.getStackTraceString(e)); } 

虽然我在每个任务的启动之间使用了“Thread.sleep(20)”,但我还没有完全检查到底需要什么,也许更短的时间可能会奏效。 对于我的目的1秒延迟,而这些被删除是没有问题的。

最终的成分是十八个(非常简单的)正在开始的活动,看起来像这样:

 package com.morphoss.blah.welcome.nul; import android.app.Activity; import android.os.Bundle; public class Null0 extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.finish(); } } 

希望这是有帮助的。

我刚刚遇到了同样的问题。 好吧,我不知道最近的清单有多清楚,但我知道,怎么不把你的应用程序放在那里。 以FLAG_ACTIVITY_NO_HISTORY标志开始。

这对我有用,我希望我可以帮你。 干杯,细节:最小SDK级别14