You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 18:31:17