Android源码系统层之前可以顺利的获取正在运行的程序和kill正在运行的程序,在第三方应用上加入android.permission.REAL_GET_TASKS权限也可以获取。加入权限<uses-permission android:name="android.permission.GET_TASKS" />
方法如下:
/** * @return The lists of the RunningApps */ public List<HashMap<String, Object>> getRunningApp() { appInfos.clear(); final PackageManager pm = mContext.getPackageManager(); am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); runningProcess = am.getRunningAppProcesses();// use it if the getRunningTasks API is deprecated runningTasks = am.getRunningTasks(MAX_RUNNING_TASKS);//The maximum number of running list Log.i(TAG, "runningProcess = " + runningProcess.size()); Log.i(TAG, "runningTasks = " + runningTasks.size()); for (int i = 0; i< runningTasks.size(); i++){ ActivityManager.RunningTaskInfo rt = runningTasks.get(i); if (i == 0){ //skip the front task, also see the top of tasks stack continue; } HashMap<String, Object> runningAppInfo = new HashMap<String, Object>(); ComponentName component = rt.baseActivity; String pkgName = component.getPackageName(); String className = component.getClassName(); String shortclassName = component.getShortClassName(); ApplicationInfo applicationInfo = null; Log.i(TAG, "runningTasks pkgName = " + pkgName); if (pkgName.equals("com.android.launcher3") || pkgName.equals("com.android.systemui")) { // skip the launcher and systemui, the special tasks. continue; } try { applicationInfo = pm.getApplicationInfo(pkgName, 0); // skip the system app // if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { // continue; // } } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } finally { } String applicationName = (String) pm.getApplicationLabel(applicationInfo); Drawable icon = pm.getApplicationIcon(applicationInfo); int id = rt.id; ActivityManager.TaskThumbnail taskThumbnail = am.getTaskThumbnail(id); Bitmap thumbnail = taskThumbnail.mainThumbnail; runningAppInfo.put("pkgname", pkgName); runningAppInfo.put("appname", applicationName); runningAppInfo.put("thumbnail", thumbnail); runningAppInfo.put("taskid", id); runningAppInfo.put("icon", icon); appInfos.add(runningAppInfo); } return appInfos; }
但是今儿在第三方应用研究Process和Task的关系时发现getRunningTasks()方法只能获取到当前应用和Launcher。确认代码无误后查看该方法源码:
* @deprecated As of {@link android.os.Build.VERSION_CODES#LOLLIPOP}, this method * is no longer available to third party * applications: the introduction of document-centric recents means * it can leak person information to the caller. For backwards compatibility, * it will still retu rn a small subset of its data: at least the caller's * own tasks, and possibly some other tasks * such as home that are known to not be sensitive.
因为Android L以后Google为了提升系统的安全性,进行了权限收敛,限制了很多以前可以使用的接口, 这些被限制的接口大多都容易向第三方泄露用户的隐私信息。但是为了保证向后兼容性,仍然可以获取到一些RunningTasks数据的子集(至少包括当前调用者的Task和Launcher这种不含敏感信息的数据)。
而且文档指出,针对于普通第三方应用(不包含预置APK)这个接口目前只可用于Debug(然而这个本人测试发现Debug也不可以)和展示系统的任务管理器。不清楚360这些在5.0以后是如何实现的,待研究。
对于替代方法可参考:
http://*.com/questions/26714285/is-there-an-alternative-for-getrunningtask-api/27304318#27304318
http://*.com/questions/24625936/getrunningtasks-doesnt-work-in-android-l/27140347#27140347