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

Java中如何获取其他应用后台RunningTasks并判断其运行状态

实现指定包名应用后台运行状态检测

原代码存在的核心问题

  • 判断条件写错:仅检测了IMPORTANCE_FOREGROUND前台进程,完全没有覆盖后台运行的进程场景,和检测后台任务的需求不匹配
  • 弹窗逻辑错误:在遍历进程的内层循环里做判断,每遍历到一个不匹配的包名就弹一次提示,会出现大量重复弹窗、结果误判
  • 返回值无效:无论检测结果如何固定返回true,方法返回值没有实际判断意义
  • 缺少版本适配:Android 5.0之后系统对进程获取接口做了严格限制,普通应用调用getRunningAppProcesses无法拿到完整的第三方应用进程列表,直接使用会出现检测结果不准的问题

适配全版本的实现代码

首先在AndroidManifest.xml中添加必要权限:

<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission
    android:name="android.permission.PACKAGE_USAGE_STATS"
    tools:ignore="ProtectedPermissions" />

核心检测逻辑实现:

/**
 * 检测指定包名应用是否处于后台运行状态
 * @param packageName 待检测的目标应用包名,如com.example.app
 * @return 目标应用在后台运行返回true,否则返回false
 */
public boolean isAppRunningInBackground(String packageName) {
    ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
    boolean isBackgroundRunning = false;

    // Android 5.0以下版本直接通过进程列表判断
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
        List<ActivityManager.RunningAppProcessInfo> runningProcesses = activityManager.getRunningAppProcesses();
        if (runningProcesses == null) {
            Toast.makeText(this, "App is not running", Toast.LENGTH_LONG).show();
            return false;
        }
        for (ActivityManager.RunningAppProcessInfo processInfo : runningProcesses) {
            // 排除前台进程、前台服务进程,只匹配后台进程
            if (processInfo.importance != ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND
                    && processInfo.importance != ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE) {
                for (String activePkg : processInfo.pkgList) {
                    if (TextUtils.equals(activePkg, packageName)) {
                        isBackgroundRunning = true;
                        break;
                    }
                }
            }
            if (isBackgroundRunning) break;
        }
    } else {
        // Android 5.0及以上版本通过UsageStatsManager结合进程存活状态判断
        UsageStatsManager usageStatsManager = (UsageStatsManager) getSystemService(Context.USAGE_STATS_SERVICE);
        long currentTime = System.currentTimeMillis();
        // 查询最近10秒内的应用使用记录
        List<UsageStats> usageStatsList = usageStatsManager.queryUsageStats(
                UsageStatsManager.INTERVAL_BEST,
                currentTime - 10 * 1000,
                currentTime
        );

        if (usageStatsList == null || usageStatsList.isEmpty()) {
            // 无权限时引导用户跳转设置开启使用情况访问权限
            Toast.makeText(this, "请先授予使用情况访问权限", Toast.LENGTH_LONG).show();
            startActivity(new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS));
            Toast.makeText(this, "App is not running", Toast.LENGTH_LONG).show();
            return false;
        }

        // 按最后使用时间排序,获取当前栈顶应用
        TreeMap<Long, UsageStats> taskSortMap = new TreeMap<>();
        for (UsageStats stats : usageStatsList) {
            taskSortMap.put(stats.getLastTimeUsed(), stats);
        }
        UsageStats topTask = taskSortMap.get(taskSortMap.lastKey());

        // 判断目标应用进程是否存活
        boolean isProcessAlive = false;
        List<ActivityManager.RunningAppProcessInfo> runningProcesses = activityManager.getRunningAppProcesses();
        if (runningProcesses != null) {
            for (ActivityManager.RunningAppProcessInfo info : runningProcesses) {
                for (String pkg : info.pkgList) {
                    if (TextUtils.equals(pkg, packageName)) {
                        isProcessAlive = true;
                        break;
                    }
                }
                if (isProcessAlive) break;
            }
        }

        // 进程存活且当前栈顶不是目标应用,判定为后台运行
        if (isProcessAlive && !TextUtils.equals(topTask.getPackageName(), packageName)) {
            isBackgroundRunning = true;
        }
    }

    // 遍历完成后统一弹提示,避免重复弹窗
    if (isBackgroundRunning) {
        Toast.makeText(this, "App is Running", Toast.LENGTH_LONG).show();
    } else {
        Toast.makeText(this, "App is not running", Toast.LENGTH_LONG).show();
    }
    return isBackgroundRunning;
}

关键注意点

  • Android 5.0以上版本使用UsageStatsManager接口时,需要用户手动在「设置-应用-特殊权限-使用情况访问」中为当前应用开启权限,否则无法获取应用运行数据
  • 不要在遍历进程/任务的循环中弹出Toast,否则会因为遍历到多个非目标应用出现连续弹窗的异常
  • 不要使用已废弃的getRunningTasks()接口做高版本适配,该接口在Android 5.0以上只会返回当前应用自身的任务信息,无法检测第三方应用状态
  • 部分深度定制的国产ROM可能对后台进程管控有特殊逻辑,需要根据实际机型做针对性适配

内容的提问来源于stack exchange,提问作者Adi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 02:54:19