Android 5.1.1及以上 – getRunningAppProcesses()只返回我的应用程序包

Google似乎最终closures了获取当前前台应用程序包的所有大门。

在Lollipop更新之后,杀死了getRunningTasks(int maxNum)并感谢这个答案 ,我使用这个代码来获取自Lollipop以来的前台应用程序包:

 final int PROCESS_STATE_TOP = 2; RunningAppProcessInfo currentInfo = null; Field field = null; try { field = RunningAppProcessInfo.class.getDeclaredField("processState"); } catch (Exception ignored) { } ActivityManager am = (ActivityManager) this.getSystemService(Context.ACTIVITY_SERVICE); List<RunningAppProcessInfo> appList = am.getRunningAppProcesses(); for (RunningAppProcessInfo app : appList) { if (app.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND && app.importanceReasonCode == 0 ) { Integer state = null; try { state = field.getInt( app ); } catch (Exception ignored) { } if (state != null && state == PROCESS_STATE_TOP) { currentInfo = app; break; } } } return currentInfo; 

Android 5.1.1及更高版本(6.0棉花糖)似乎也杀死了getRunningAppProcesses() 。 现在它返回你自己的应用程序包列表。


UsageStatsManager

我们可以使用这里描述的新的UsageStatsManager API,但它不适用于所有应用程序。 一些系统应用程序将返回相同的包

 com.google.android.googlequicksearchbox 

AccessibilityService (2017年12月:将被禁止供Google使用)

有些应用程序使用AccessibilityService (如图所示 ),但有一些缺点。


是否有另一种获得当前正在运行的应用程序包的方式?

要获得Android 1.6上运行的进程的列表 – Android 6.0,你可以使用这个库我写道: https : //github.com/jaredrummler/AndroidProcesses库读/ proc来获取进程信息。

Google在Android Nougat中明​​显限制了对/ proc的访问。 要获取Android Nougat上正在运行的进程的列表,您需要使用UsageStatsManager或具有root权限。

点击以前的替代解决scheme的编辑历史。

  private String printForegroundTask() { String currentApp = "NULL"; if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) { UsageStatsManager usm = (UsageStatsManager)this.getSystemService("usagestats"); long time = System.currentTimeMillis(); List<UsageStats> appList = usm.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, time - 1000*1000, time); if (appList != null && appList.size() > 0) { SortedMap<Long, UsageStats> mySortedMap = new TreeMap<Long, UsageStats>(); for (UsageStats usageStats : appList) { mySortedMap.put(usageStats.getLastTimeUsed(), usageStats); } if (mySortedMap != null && !mySortedMap.isEmpty()) { currentApp = mySortedMap.get(mySortedMap.lastKey()).getPackageName(); } } } else { ActivityManager am = (ActivityManager)this.getSystemService(Context.ACTIVITY_SERVICE); List<ActivityManager.RunningAppProcessInfo> tasks = am.getRunningAppProcesses(); currentApp = tasks.get(0).processName; } Log.e("adapter", "Current App in foreground is: " + currentApp); return currentApp; } 

使用此方法获取前景任务。 U将需要一个系统权限“android:get_usage_stats”

 public static boolean needPermissionForBlocking(Context context){ try { PackageManager packageManager = context.getPackageManager(); ApplicationInfo applicationInfo = packageManager.getApplicationInfo(context.getPackageName(), 0); AppOpsManager appOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); int mode = appOpsManager.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS, applicationInfo.uid, applicationInfo.packageName); return (mode != AppOpsManager.MODE_ALLOWED); } catch (PackageManager.NameNotFoundException e) { return true; } } 

如果用户在设置 – >安全 – >使用访问权限的应用程序中启用。 之后,你会得到前台的任务。 类似的过程清洁mather由Cheetahamobile 谷歌播放链接

看看https://github.com/ricvalerio/foregroundappchecker ,这可能是你需要的。 提供示例代码,并带走了实现跨版本前景探测器的痛苦。

这里有两个样本:

 AppChecker appChecker = new AppChecker(); String packageName = appChecker.getForegroundApp(); 

或定期检查:

 AppChecker appChecker = new AppChecker(); appChecker .when("com.other.app", new AppChecker.Listener() { @Override public void onForeground(String packageName) { // do something } ) .when("com.my.app", new AppChecker.Listener() { @Override public void onForeground(String packageName) { // do something } ) .other(new AppChecker.Listener() { @Override public void onForeground(String packageName) { // do something } ) .timeout(1000) .start(this); 

Google仅限于系统应用程序限制此function。 如错误票据中所报告的,您将需要REAL_GET_TASKS权限才能访问此处。

应用程序现在必须具有… permission.REAL_GET_TASKS才能获取所有应用程序的进程信息。 如果应用程序没有权限,则只会返callback用应用程序的进程信息。 权限应用程序暂时能够获得所有应用程序的进程信息,如果他们没有新的权限,但已弃用… permission.GET_TASKS此外,只有系统应用程序可以获得REAL_GET_TASKS权限。

 public class AccessibilityDetectingService extends AccessibilityService { @Override protected void onServiceConnected() { super.onServiceConnected(); //Configure these here for compatibility with API 13 and below. AccessibilityServiceInfo config = new AccessibilityServiceInfo(); config.eventTypes = AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED; config.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC; if (Build.VERSION.SDK_INT >= 16) //Just in case this helps config.flags = AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS; setServiceInfo(config); } @Override public void onAccessibilityEvent(final AccessibilityEvent event) { if (event == null ) { return; } else if(event.getPackageName() == null && event.getClassName() == null){ return; } if (activityInfo != null){ Log.d("CurrentActivity", componentName.flattenToShortString()); } } private ActivityInfo tryGetActivity(ComponentName componentName) { try { return getPackageManager().getActivityInfo(componentName, 0); } catch (PackageManager.NameNotFoundException e) { return null; } } @Override public void onInterrupt() { } } }//`enter code here`uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE" /> <uses-permission android:name="android.permission.GET_TASKS" /> 

然后在您的设备设置 – >辅助function – >该服务的应用程序启动服务和应用程序的辅助function。

请尝试使用getRunningServices()而不是getRunningAppProcesses()方法。

  ActivityManager mActivityManager = (ActivityManager) getSy stemService(Context.ACTIVITY_SERVICE); List<ActivityManager.RunningServiceInfo> appProcessInfoList = mActivityManager.getRunningServices(Integer.MAX_VALUE);