如何获取后台运行的app名称
如果要获取实时在后台运行的app呢
监听最近任务切换记录(使用 useUsageStats 和 recents 事件)——只能知道“曾经前台过”,不能确定“仍在运行”。
结合 currentPackage() 轮询变化 —— 只能感知前台切换。如何实现这个功能
回答
你可以通过 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 命令执行 ps 或 dumpsys 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 执行命令获取进程列表
你可以使用 ps 或 ps -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 才能完整获取。
替代思路(局限性大):
- 监听最近任务切换记录(使用
useUsageStats和recents事件)——只能知道“曾经前台过”,不能确定“仍在运行”。 - 结合
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() 轮询,可以较准确地感知前台应用切换。这种方法只能知道哪个应用进入了前台,不能判断之前在最近任务中的应用是否仍在运行。
综上,该方案依赖于:
- 开启“使用情况统计”权限;
- 使用
auto.setFlags('useUsageStats')提高currentPackage()准确性; - 通过短间隔轮询检测前台变化;
- 利用自定义事件分发机制解耦逻辑。
这是目前 Hamibot 环境下最可靠的前台应用切换感知方案。