currentActivity() 返回总是错误
我在 Android 14 的一台手机上测试脚本,没有什么问题。把脚本放到客户手机上跑,发现跑一下就不动了。测试发现,脚本用 currentActivity() 识别当前界面总是错误,返回的结果总是当前 Activity 的 上一个 Activity。
例子:当前 App 在主界面,脚本开始运行,一切正常。脚本点击了一个按钮,然后 App 出了一个加载,这个加载是个单独的 Activity。加载完成,App 回到主界面,此时脚本获取 currentActivity() 始终是加载,必须要手动切换一下界面,或者重启脚本,脚本的 currentActivity() 才能正确获取到 Activity。
例子只是例子,不只是这一个地方有这个问题,用到了 currentActivity() 的地方全部都有这样的问题。currentPackage() 也有类似的问题,有时候明明已经在 App 里了,获取到的包名却还是系统桌面。
以上问题在小米的 Android 13、Android 9 两台设备上都能稳定复现,在客户的一个华为的手机上也能复现,Android 版本应该是比较低的。在我手机上就永远不会发生。写了好几天的脚本一使用完全不能用。Hamibot 除了用 currentPackage() currentActivity() 判断界面,有没有更稳妥的方法,自己试 BUG 很多太折腾了
补充在回答里了
这段代码目前还遇到了一个问题,就是运行到 console.log("发现公告浮窗, 点击确定按钮");
这里,控制台输出日志之后,就点击不到按钮了,整个脚本阻塞住,不会往下运行了。
单独 console.log(id("commit_btn").findOne());
是可以输出的,也是能找到组件的,但是点击就会卡住
我测试了一下,以下是最短的复现代码:
console.show();
auto.waitFor();
setInterval(() => {
console.log(currentActivity());
}, 1000);
我发现好像只要有不是满屏的 Activity 出现,就会有这个问题。
即使是我按了一下音量键,系统的音量条出来,currentActivity()
的返回也会持续变成 android.app.Dialog
。直到前台下一个 Activity 切换。
我提到的这个 App 的加载 Activity 看起来也是一个透明的不是满屏的界面。
而且我已经最小化到上面这六行代码了,还是这样,是不是说明 currentActivity()
这个方法本来返回的内容就不完全是对的... 有没有别的什么方法鉴别当前界面的,我可以改成别的方法
那不好判断啊... 因为 currentPackage()
返回的内容也是不一定准确的,之前遇见过在 App 内获取的还是系统桌面。
估计没法用这俩方法来写了,得研究个别的判断界面的方法
回答
如果能稳定复现,可以贴下代码,拿 Hamibot 这个 app 来测试。
ps:会不会是没给权限,比如后台弹出什么的
拿 Hamibot 来测试,最小能复现的代码就行,否则没环境去复现
currentActivity
名字有些不准确,实际是获取最近一次,可以加个判断,不是目标 app 的话 launch
回去,有时候可能要先 home
到桌面再 launch
let config = hamibot.env; // 获取配置
// 解析配置
config.beforeTime = parseFloat(config.beforeTime) || null;
config.lowestPrice = parseFloat(config.lowestPrice) || null;
config.jingpaiDelay = parseFloat(config.jingpaiDelay) || 0;
if (!["预约竞拍", "预约进厂"].includes(config.currentTask)) {
config.currentTask = null;
}
// 校验配置,如果配置不合法直接退出
if (
config.beforeTime === null ||
config.lowestPrice === null ||
config.currentTask === null
) {
alert("脚本将退出", "脚本配置内容有误, 请检查配置.");
hamibot.exit();
}
console.log(`将在剩余 ${config.beforeTime} 秒后开始竞价.`);
console.log(`可发出的最低报价是 ${config.lowestPrice}.`);
console.log(`竞价延迟 ${config.jingpaiDelay} ms.`);
console.log(`当前任务: ${config.currentTask}`);
// debug
setInterval(() => {
console.log(currentActivity());
}, 1000);
function main() {
console.show();
console.log("确保无障碍服务启动...");
auto.setMode("normal");
console.log("无障碍服务正常");
auto.setWindowFilter(function (window) {
// 对于应用窗口,他的title属性就是应用的名称,因此可以通过title属性来判断一个应用
return window.title == "敬业运输司机端";
});
activityRouter();
}
main();
function activityRouter() {
// debug
debugDisplayActivity();
if (currentPackage() !== "com.ibb.tizi") {
console.log("当前前台应用不是敬业运输司机端");
launch("com.hamibot.hamibot");
sleep(1000);
console.log("正在启动敬业运输司机端... 如果启动失败, 请手动启动");
launch("com.ibb.tizi");
setTimeout(activityRouter, 3000);
return;
}
// login
if (currentActivity() === "com.ibb.tizi.activity.LoginActivity") {
console.log("当前为登录界面, 开始登录流程");
while (!click("司机登录"));
id("cb_agreement").findOne().click();
while (!click("登 录"));
setTimeout(activityRouter, 3000);
return;
}
// dialog
if (currentActivity() === "android.app.Dialog") {
console.log("发现公告浮窗, 点击确定按钮");
id("commit_btn").findOne().click();
click("确定");
console.log("已关闭公告浮窗");
setTimeout(activityRouter, 1000);
return;
}
// 主页
if (currentActivity() === "com.ibb.tizi.activity.HomeActivity") {
// 如果不在销售页面, 先进入销售页面
if (id("rd_market").findOne().checked() == false) {
id("rd_market").findOne().click();
console.log("等待进入销售页面...");
setTimeout(activityRouter, 300);
return;
}
if (config.currentTask === "预约竞拍") {
id("sale_jj").findOne().click();
console.log("已点击预约竞拍");
setTimeout(activityRouter, 2000);
return;
}
if (config.currentTask === "预约进厂") {
id("sale_enter_appoint").findOne().click();
console.log("已点击预约进厂");
setTimeout(activityRouter, 2000);
return;
}
}
// loading
if (currentActivity() === "com.ibb.tizi.view.AppLoadingDialog") {
console.log("当前为加载界面, 等待 3 秒...");
setTimeout(activityRouter, 3000);
return;
}
// 预约竞拍
if (
currentActivity() === "com.ibb.tizi.activity.salejj.SaleEnterJjActivity"
) {
alert("提示", "已进入预约竞拍界面,请选择想要竞拍的单子并进入!");
// 竞拍页面点击地区下拉框
id("area").findOne().click();
jingjiaRouter();
return;
}
// 竞价详情
if (
currentActivity() ===
"com.ibb.tizi.activity.salejj.SaleJingjiaDetailActivity"
) {
jingjiaRouter();
return;
}
// 预约进厂
if (
currentActivity() === "com.ibb.tizi.activity.SaleEnterAppointNewActivity"
) {
jinchangRouter();
return;
}
setTimeout(activityRouter, 250);
}
这个是一部分代码,当程序运行之后进入到 currentActivity() === "com.ibb.tizi.activity.HomeActivity"
之后,第一次 id("sale_jj").findOne().click();
是能正常点击的,然后 App 弹一个 Loading 的 Activity,Loading 结束,currentActivity() 就一直是 com.ibb.tizi.view.AppLoadingDialog
了,即使 App 现在已经回到了 com.ibb.tizi.activity.HomeActivity
。
权限都给了,所有能给的权限都给了