如何获取后台运行的app名称

已存档
wrekemdkwh · 26 天前
第 1 条补充
·
26 天前

如果要获取实时在后台运行的app呢

第 2 条补充
·
26 天前

监听最近任务切换记录(使用 useUsageStats 和 recents 事件)——只能知道“曾经前台过”,不能确定“仍在运行”。
结合 currentPackage() 轮询变化 —— 只能感知前台切换。如何实现这个功能

回答

Hamibot AI
1
· 26 天前

你可以通过 Hamibot 的 currentPackage() 函数获取当前前台运行的应用包名,但如果你需要获取后台运行的 App 名称,Hamibot 本身并不直接提供列出所有后台进程的应用名称的功能。

不过,可以通过以下方式间接实现:

方法一:使用 auto 模块 + 使用情况统计权限(推荐)

启用 useUsageStats 标志后,auto 模块可以更准确地识别当前活跃应用,并结合“使用情况统计”服务来判断最近使用的应用(包括后台运行过的)。

// 文档地址 https://docs.hamibot.com/
auto.setFlags(['useUsageStats']); // 启用使用情况统计

// 等待无障碍服务和 UsageStats 就绪
if (!auto.service) {
    auto.waitFor();
}

// 获取当前前台应用包名(最准确)
var pkgName = currentPackage();
var appName = app.getAppName(pkgName);

log("当前前台应用包名:", pkgName);
log("当前前台应用名称:", appName);

⚠️ 注意:

  • useUsageStats 需要你手动授予 “查看使用情况统计” 权限。
  • 它只能获取到系统记录中“最近使用”的应用信息,不能实时列出所有后台进程。
  • 无法直接获取完全后台隐藏运行的服务型 App 列表。

方法二:通过 shell 命令(需 Root)

如果你的设备已 root,可以使用 shell 命令执行 psdumpsys activity recents 来查看最近任务或进程列表,然后解析出应用包名并转换为应用名称。

示例代码(获取最近任务中的包名):

// 文档地址 https://docs.hamibot.com/
function getRecentApps() {
    var result = shell("dumpsys activity recents", true);
    if (result.code === 0) {
        var lines = result.stdout.split('\n');
        var packages = [];
        for (var line of lines) {
            var match = line.match(/packageName=(\S+)/);
            if (match && !packages.includes(match[1])) {
                packages.push(match[1]);
            }
        }
        return packages.map(pkg => ({
            packageName: pkg,
            appName: app.getAppName(pkg)
        }));
    } else {
        throw new Error("执行失败: " + result.stderr);
    }
}

// 调用函数
try {
    var recentApps = getRecentApps();
    console.log("最近使用过的应用:", recentApps);
} catch (e) {
    console.error("获取失败:", e.message);
}

📌 说明:

  • 此方法依赖 root 权限(shell 命令必须能执行成功)。
  • dumpsys activity recents 返回的是最近任务列表,不等于所有后台运行的 App,但通常已足够用于自动化场景。

总结

方法 是否需要权限 能否获取后台 App 备注
currentPackage() 无障碍服务 ❌ 只能获取前台 不适合本需求
auto.setFlags(['useUsageStats']) 查看使用情况统计权限 ✅ 近期使用/切换过的App 推荐非 Root 设备使用
shell(dumpsys activity recents) Root 权限 ✅ 最近任务中的 App 功能更强,仅限 Root

建议根据你的设备是否 Root 选择合适的方法。对于大多数用户,使用 useUsageStats 是最稳定可行的方式。


补充回答 1

要获取实时在后台运行的 App(即当前正在运行且处于后台状态的进程),Hamibot 本身没有直接提供列出所有“后台运行应用”的 API。但你可以通过以下方式实现,取决于你的设备是否拥有 Root 权限


✅ 方案一:有 Root 权限 —— 使用 shell 执行命令获取进程列表

你可以使用 psps -A 命令查看当前系统中所有正在运行的进程,然后结合包名匹配和应用名称解析来识别哪些是用户 App 并处于后台。

示例代码:

// 文档地址 https://docs.hamibot.com/
function getRunningBackgroundApps() {
    var result = shell("ps -A", true); // 使用 ps -A 获取所有进程(兼容性更好)
    if (result.code !== 0) {
        throw new Error("shell 命令执行失败: " + result.stderr);
    }

    var lines = result.stdout.split('\n');
    var backgroundApps = [];

    for (var i = 1; i < lines.length; i++) { // 第一行是标题,跳过
        var line = lines[i].trim();
        if (!line) continue;

        var parts = line.split(/\s+/);
        if (parts.length < 9) continue;

        var userName = parts[0]; // 用户名(如 u0_a123)
        var processName = parts[parts.length - 1]; // 最后一列为进程名(通常是包名或 :service)

        // 过滤出以 com. 开头的 Android 应用包名
        if (processName.includes('com.') && !processName.includes(':')) {
            var appName = app.getAppName(processName);
            backgroundApps.push({
                packageName: processName,
                appName: appName || '(未知)',
                user: userName
            });
        }
    }

    // 去重
    var uniqueApps = [];
    var seen = {};
    for (var app of backgroundApps) {
        if (!seen[app.packageName]) {
            seen[app.packageName] = true;
            uniqueApps.push(app);
        }
    }

    return uniqueApps;
}

// 调用函数并输出结果
try {
    auto.waitFor(); // 确保无障碍服务就绪(部分设备可能需要)
    var running = getRunningBackgroundApps();
    console.log("实时后台运行的应用:", running);
} catch (e) {
    console.error("获取失败:", e.message);
}

📌 说明:

  • ps -A 列出所有进程,每行格式为:USER PID PPID VSIZE RSS WCHAN PC NAME
  • 我们提取最后一列 NAME,判断是否为常见 App 包名(如 com.tencent.mm)。
  • 排除包含 : 的进程(一般是子服务,如 com.tencent.mm:push)避免重复。
  • 使用 app.getAppName() 将包名转换为可读的应用名称(如“微信”)。

🔐 要求:

  • 设备必须已 root,并允许 Hamibot 使用 root 权限执行 shell 命令。
  • 某些 Android 版本限制 ps 输出完整性,建议 Android 9 及以下版本使用效果更佳。

⚠️ 方案二:无 Root 权限 —— 无法准确获取实时后台进程

Android 系统出于安全考虑,从 Android 5.0 开始限制非系统应用访问其他进程信息。因此,在没有 Root 的情况下

  • 不能可靠地获取完整后台运行的 App 列表
  • runningApps() 已被废弃,不再可用。
  • dumpsys activity processes 输出复杂且通常需要 root 才能完整获取。

替代思路(局限性大):

  • 监听最近任务切换记录(使用 useUsageStatsrecents 事件)——只能知道“曾经前台过”,不能确定“仍在运行”。
  • 结合 currentPackage() 轮询变化 —— 只能感知前台切换。

👉 结论:无 Root 时无法精确获取“实时在后台运行的 App”列表。


🔚 总结

方法 是否需要 Root 实时性 准确性 推荐程度
shell("ps -A") + 包名解析 ✅ 需要 ✅ 高 ✅ 高 ⭐⭐⭐⭐☆
dumpsys activity processes ❌ 不一定,但常需 root ⭐⭐⭐(复杂

补充回答 2

要在 Hamibot 中实现监听最近任务切换并感知前台应用变化,可以结合 useUsageStats 标志和轮询 currentPackage() 的方式。以下是具体实现方法:

首先,在脚本开始时调用 auto.setFlags('useUsageStats') 启用使用情况统计服务来获取更准确的当前包名信息。这需要你提前授予“查看使用情况统计”权限。

// 文档地址 https://docs.hamibot.com/
auto.setFlags('useUsageStats');
auto.waitFor();

然后通过定时轮询 currentPackage() 来检测前台应用的变化。你可以使用 setInterval 定期检查包名是否发生变化,并在变化时执行相应逻辑。

// 文档地址 https://docs.hamibot.com/
var lastPackage = currentPackage();

// 每500毫秒检查一次前台应用变化
setInterval(function () {
  var currentPkg = currentPackage();
  if (currentPkg !== lastPackage) {
    // 触发前台应用切换事件
    events.emit('packageChanged', {
      from: lastPackage,
      to: currentPkg,
      timestamp: new Date().getTime()
    });
    lastPackage = currentPkg;
  }
}, 500);

同时,你可以监听 events.on('packageChanged', ...) 来处理切换逻辑:

// 文档地址 https://docs.hamibot.com/
events.on('packageChanged', function (data) {
  log('应用切换:', data.from, '->', data.to);
  // 在这里添加你的业务逻辑
});

注意:recents 事件本身无法直接监听,但通过 useUsageStats 配合 currentPackage() 轮询,可以较准确地感知前台应用切换。这种方法只能知道哪个应用进入了前台,不能判断之前在最近任务中的应用是否仍在运行。

综上,该方案依赖于:

  1. 开启“使用情况统计”权限;
  2. 使用 auto.setFlags('useUsageStats') 提高 currentPackage() 准确性;
  3. 通过短间隔轮询检测前台变化;
  4. 利用自定义事件分发机制解耦逻辑。

这是目前 Hamibot 环境下最可靠的前台应用切换感知方案。

ℹ️ 本回答由 AI 生成,内容仅供参考