Android API22环境下如何获取前后台所有运行应用的名称与PID
我明白你的问题啦——在Android 5.0(API21)之后,Google收紧了普通应用获取其他进程信息的权限,所以你用ActivityManager的旧方法只能拿到自己的应用进程。针对API22的情况,分两种场景给你解决方案:
场景1:普通应用(非系统应用)
普通应用无法直接获取其他应用的PID,但可以获取所有最近运行过的应用名称(包括前台后台),如果需要PID,只能拿到自己应用的。以下是实现代码:
步骤1:添加权限到Manifest
首先在AndroidManifest.xml中添加权限:
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" tools:ignore="ProtectedPermissions" />
步骤2:检查并引导用户授权
这个权限需要用户手动在系统设置中开启,所以先检查权限:
private boolean hasUsageStatsPermission(Context context) { AppOpsManager appOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); int mode = appOps.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS, android.os.Process.myUid(), context.getPackageName()); return mode == AppOpsManager.MODE_ALLOWED; } private void requestUsageStatsPermission(Context context) { Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS); context.startActivity(intent); }
步骤3:获取应用名称和可获取的PID
// 先定义一个实体类存储应用信息 public class AppInfo { public String appName; public int pid; public String packageName; public AppInfo(String appName, int pid, String packageName) { this.appName = appName; this.pid = pid; this.packageName = packageName; } } public List<AppInfo> getRunningApps(Context context) { List<AppInfo> appInfoList = new ArrayList<>(); PackageManager packageManager = context.getPackageManager(); // 先获取自己应用的PID和信息 ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); List<ActivityManager.RunningAppProcessInfo> ownProcesses = activityManager.getRunningAppProcesses(); for (ActivityManager.RunningAppProcessInfo info : ownProcesses) { try { ApplicationInfo appInfo = packageManager.getApplicationInfo(info.processName, 0); String appName = packageManager.getApplicationLabel(appInfo).toString(); appInfoList.add(new AppInfo(appName, info.pid, info.processName)); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } } // 再通过UsageStatsManager获取其他应用的名称(无法获取PID) if (!hasUsageStatsPermission(context)) { return appInfoList; } UsageStatsManager usageStatsManager = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE); long endTime = System.currentTimeMillis(); long startTime = endTime - 1000 * 60 * 60; // 查询过去1小时内的应用 List<UsageStats> usageStatsList = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_BEST, startTime, endTime); if (usageStatsList == null || usageStatsList.isEmpty()) { return appInfoList; } // 去重并添加其他应用名称 Set<String> addedPackages = new HashSet<>(); for (AppInfo info : appInfoList) { addedPackages.add(info.packageName); } for (UsageStats stats : usageStatsList) { String packageName = stats.getPackageName(); if (addedPackages.contains(packageName)) { continue; } try { ApplicationInfo appInfo = packageManager.getApplicationInfo(packageName, 0); String appName = packageManager.getApplicationLabel(appInfo).toString(); appInfoList.add(new AppInfo(appName, -1, packageName)); // PID设为-1表示无法获取 addedPackages.add(packageName); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } } return appInfoList; }
场景2:系统应用(拥有系统权限)
如果你的应用是系统应用或者拥有android.permission.GET_TASKS权限,可以直接用ActivityManager.getRunningAppProcesses()获取所有应用的PID和名称:
public List<AppInfo> getAllRunningApps(Context context) { List<AppInfo> appInfoList = new ArrayList<>(); ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); PackageManager packageManager = context.getPackageManager(); List<ActivityManager.RunningAppProcessInfo> processInfos = activityManager.getRunningAppProcesses(); for (ActivityManager.RunningAppProcessInfo info : processInfos) { try { ApplicationInfo appInfo = packageManager.getApplicationInfo(info.processName, 0); String appName = packageManager.getApplicationLabel(appInfo).toString(); appInfoList.add(new AppInfo(appName, info.pid, info.processName)); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } } return appInfoList; }
记得在Manifest中添加权限:
<uses-permission android:name="android.permission.GET_TASKS" />
补充说明:在API21+,Google对应用获取其他进程信息做了严格限制,主要是为了用户隐私和系统安全。普通应用只能通过UsageStatsManager获取应用名称,无法获取PID;只有系统应用或拥有特殊权限的应用才能获取完整的PID信息。
内容的提问来源于stack exchange,提问作者bukubapi
相关产品推荐
相关产品推荐

