Android如何检测应用是否运行?进程列表获取异常求助
问题原因与解决办法
为什么只返回自己的进程?
从Android 10(API 29)开始,系统出于隐私保护目的,收紧了进程访问权限——ActivityManager.getRunningAppProcesses()方法现在仅能返回当前应用自身的进程信息,无法再获取其他应用的进程列表。这不是你代码的逻辑错误,是系统层面的权限限制机制。
你的测试代码额外问题
另外需要注意:你在onCreate中编写的无限循环会直接阻塞UI线程,很快就会触发ANR(应用无响应)。调试时可以改用定时查询的方式,比如用Handler实现:
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { @Override public void run() { List<ActivityManager.RunningAppProcessInfo> processes = am.getRunningAppProcesses(); Log.d(TAG, "SIZE IS" + processes.size()); // 每隔1秒查询一次 this.run(); } }, 1000);
检测其他应用运行状态的替代方案:UsageStatsManager
如果需要判断特定应用是否在运行,需要使用UsageStatsManager,具体步骤如下:
- 在
AndroidManifest.xml中声明权限:
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" tools:ignore="ProtectedPermissions" />
- 引导用户手动开启权限:该权限无法通过代码自动申请,需要跳转至系统设置页面让用户授权:
Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS); startActivity(intent);
- 查询目标应用的运行状态:
UsageStatsManager usageStatsManager = (UsageStatsManager) getSystemService(Context.USAGE_STATS_SERVICE); long currentTime = System.currentTimeMillis(); // 查询最近10分钟内的应用使用记录 List<UsageStats> usageStatsList = usageStatsManager.queryUsageStats( UsageStatsManager.INTERVAL_BEST, currentTime - 1000 * 60 * 10, currentTime ); boolean isTargetAppRunning = false; String targetPackageName = "com.example.targetapp"; // 替换为你要检测的应用包名 for (UsageStats stats : usageStatsList) { if (stats.getPackageName().equals(targetPackageName)) { // 判断应用是否在最近30秒内有活跃记录 if (stats.getLastTimeUsed() > currentTime - 1000 * 30) { isTargetAppRunning = true; break; } } } Log.d(TAG, "目标应用是否运行:" + isTargetAppRunning);
补充注意事项
- 即使使用
UsageStatsManager,也必须获得用户的授权才能获取应用使用数据,这是系统强制的隐私规则 - 不同Android版本的权限细节存在差异,比如API 30+对后台应用的限制更严格,测试时需注意版本适配
内容的提问来源于stack exchange,提问作者WEASELS
相关产品推荐
相关产品推荐

