Android如何获取所有前后台运行应用?现有检测代码仅返回当前应用
Android应用检测其他应用后台运行问题
问题场景
现有Android应用A,需实现以下逻辑:
- 检测应用B是否已安装
- 若应用B未运行,则启动它
当前代码中isAppRunning()函数依赖ActivityManager.runningAppProcesses获取运行进程,但该方法仅返回应用A自身的进程实例,无法获取其他前后台运行的应用,导致无法准确判断应用B的运行状态。
原代码片段
private const val APPLICATION = "com.example.myapp" class AppLauncher @Inject constructor( @ApplicationContext val context: Context ) { fun launchApplication() { when { !isInstalled() -> throw ApplicationNotInstalledException() !isAppRunning() -> launchApplicationB() } } private fun launchApplicationB() { val launchIntent: Intent? = context.packageManager.getLaunchIntentForPackage(APPLICATION) if (launchIntent != null) { context.startActivity(launchIntent) } } private fun isInstalled(): Boolean { return try { context.packageManager.getPackageInfo( APPLICATION, PackageManager.GET_ACTIVITIES ) true } catch (e: PackageManager.NameNotFoundException) { false } } private fun isAppRunning(): Boolean { val activityManager = context.getSystemService(ACTIVITY_SERVICE) as ActivityManager val runningProcesses = activityManager.runningAppProcesses for (process in runningProcesses) { if (process.processName == APPLICATION) { return process.importance != ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND } } return false } }
问题原因
从Android 8.0(API 26)开始,系统对ActivityManager.runningAppProcesses进行了权限限制,仅允许应用获取自身的进程信息,这是为了保护用户隐私和系统安全。
解决方案
根据不同Android版本,选择对应的实现方式:
1. Android 10(API 29)及以上:使用UsageStatsManager
系统提供UsageStatsManager用于获取应用使用统计数据,需要先申请PACKAGE_USAGE_STATS权限(需用户手动在设置中授予)。
修改后的isAppRunning()函数:
private fun isAppRunning(): Boolean { val usageStatsManager = context.getSystemService(Context.USAGE_STATS_SERVICE) as UsageStatsManager val currentTime = System.currentTimeMillis() // 查询最近1小时内的应用使用记录 val usageStatsList = usageStatsManager.queryUsageStats( UsageStatsManager.INTERVAL_HOURLY, currentTime - 3600 * 1000, currentTime ) usageStatsList?.forEach { usageStats -> if (usageStats.packageName == APPLICATION) { // 判断逻辑:最近10秒内有使用记录,且曾进入前台(可根据业务需求调整) return (currentTime - usageStats.lastTimeUsed) < 10000 && usageStats.totalTimeInForeground > 0 } } return false }
2. Android 8.0-9(API 26-28)
此区间仍可尝试使用UsageStatsManager(同样需要PACKAGE_USAGE_STATS权限),或通过检查应用进程是否存在的方式,但后者可靠性较低。
3. 启动应用B的优化
若应用A在后台启动Activity,需添加FLAG_ACTIVITY_NEW_TASK标记,避免抛出异常:
private fun launchApplicationB() { val launchIntent: Intent? = context.packageManager.getLaunchIntentForPackage(APPLICATION) if (launchIntent != null) { launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) context.startActivity(launchIntent) } }
权限说明
PACKAGE_USAGE_STATS权限无法通过代码直接请求,需引导用户前往设置 > 应用 > 特殊应用权限 > 应用使用情况,为应用A开启权限。
内容的提问来源于stack exchange,提问作者Nontas Papadopoulos
相关产品推荐
相关产品推荐

