Android获取运行中应用列表重复问题的解决方法咨询
Hey there, let's break down what's going wrong here and fix it step by step!
First off, there's a core misunderstanding in your current code logic: PackageManager.getInstalledApplications() is designed to fetch all installed apps on the device, not apps that are currently running. The FLAG_STOPPED flag only indicates if an app has been stopped (e.g., never launched before or manually stopped by the system)—it doesn't reflect whether the app is actively running right now. That's why you're seeing the same repeated list even after restarting your device.
To get apps that are actually running, you need to use APIs from ActivityManager instead. Note there are compatibility considerations across Android versions:
1. Add Required Permissions
First, add these permissions to your AndroidManifest.xml:
<!-- For Android 8.0 and below --> <uses-permission android:name="android.permission.GET_TASKS" /> <!-- For Android 8.0+ --> <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" tools:ignore="ProtectedPermissions" />
Important: The PACKAGE_USAGE_STATS permission is a special one—users need to manually enable it for your app in the system settings under "App usage access".
2. Revised Code Example
public static String getActiveApps(Context context) { ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); PackageManager pm = context.getPackageManager(); String value = u.dateStamp(); // basic date stamp value += "---------------------------------\n"; value += "Active Apps\n"; value += "=================================\n"; List<ActivityManager.RunningAppProcessInfo> runningProcesses = activityManager.getRunningAppProcesses(); if (runningProcesses != null) { for (ActivityManager.RunningAppProcessInfo processInfo : runningProcesses) { // Filter for foreground/visible apps (adjust based on your needs) if (processInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND || processInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE) { try { ApplicationInfo appInfo = pm.getApplicationInfo(processInfo.processName, 0); // Exclude system apps (if needed) if ((appInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { String appLabel = pm.getApplicationLabel(appInfo).toString(); value += appLabel + "\n" + processInfo.processName + "\n-----------------------\n"; } } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } } } } return value; }
3. Optimize Your getApplicationLabel Method
Your original method loops through all installed apps every time, which is inefficient. Here's a better version:
public static String getApplicationLabel(Context context, String packageName) { PackageManager packageManager = context.getPackageManager(); try { ApplicationInfo appInfo = packageManager.getApplicationInfo(packageName, 0); return packageManager.getApplicationLabel(appInfo).toString(); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); return packageName; // Fallback to package name if label isn't found } }
- On Android 8.0 (API 26) and above,
getRunningAppProcesses()has limited visibility. For more precise running state data, you can useUsageStatsManagerto query app usage statistics, using methods likequeryUsageStatsorqueryEventsto determine if an app is in the foreground. - If you only need the current foreground app, Android 5.0+ offers
ActivityManager.getAppTasks(), though you'll still need to handle permission requirements.
内容的提问来源于stack exchange,提问作者user9214428

