調用 ActivityManager.getRunningAppProcesses() 在 Android 5.0 (API 21) 以上返回列表為空或僅包含自身進程,無法獲取第三方應用信息。
Android 5.0 為保護隱私,**限制非系統應用獲取完整進程列表**。getRunningAppProcesses() 僅返回調用者自身進程及少量系統進程。
| 方案 | 適用場景 | 優點 | 缺點 |
|---|---|---|---|
UsageStatsManager | 統計用戶應用使用情況 | 官方推薦,可獲取前台應用、使用時長 | 需用戶授權「查看應用使用權限」(Settings → Security → Apps with usage access) |
| AccessibilityService | 輔助功能,監聽窗口變化 | 可實時感知前台 Activity | 需用戶開啟無障礙服務,審核嚴格 |
| 前台服務 + 通知 | 自身應用保活 | 不依賴系統 API 限制 | 無法獲取其他應用進程 |
| Root / 系統簽名 | 系統級應用、定製 ROM | 繞過所有限制 | 普通應用不可用 |
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public String getTopPackageName(Context context) {
UsageStatsManager usm = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
long now = System.currentTimeMillis();
List stats = usm.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, now - 1000*60*60, now);
if (stats == null || stats.isEmpty()) return null;
UsageStats top = Collections.max(stats, Comparator.comparingLong(UsageStats::getLastTimeUsed));
return top.getPackageName();
}
清單文件聲明權限:
引導用戶授權:
startActivity(new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS));
無法遍歷所有進程計算內存,建議:
Debug.MemoryInfo 針對 android.os.Process.myPid()。ActivityManager.getMemoryInfo(ActivityManager.MemoryInfo)。