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 很多太折腾了

Magma · 4 个月前
第 1 条补充
·
4 个月前

补充在回答里了

第 2 条补充
·
4 个月前

这段代码目前还遇到了一个问题,就是运行到 console.log("发现公告浮窗, 点击确定按钮"); 这里,控制台输出日志之后,就点击不到按钮了,整个脚本阻塞住,不会往下运行了。
单独 console.log(id("commit_btn").findOne()); 是可以输出的,也是能找到组件的,但是点击就会卡住

第 3 条补充
·
4 个月前

我测试了一下,以下是最短的复现代码:

console.show();
auto.waitFor();

setInterval(() => {
	console.log(currentActivity());
}, 1000);
第 4 条补充
·
4 个月前

我发现好像只要有不是满屏的 Activity 出现,就会有这个问题。
即使是我按了一下音量键,系统的音量条出来,currentActivity() 的返回也会持续变成 android.app.Dialog。直到前台下一个 Activity 切换。
我提到的这个 App 的加载 Activity 看起来也是一个透明的不是满屏的界面。

而且我已经最小化到上面这六行代码了,还是这样,是不是说明 currentActivity() 这个方法本来返回的内容就不完全是对的... 有没有别的什么方法鉴别当前界面的,我可以改成别的方法

第 5 条补充
·
4 个月前

那不好判断啊... 因为 currentPackage() 返回的内容也是不一定准确的,之前遇见过在 App 内获取的还是系统桌面。
估计没法用这俩方法来写了,得研究个别的判断界面的方法

回答

神秘机师
250
· 4 个月前

如果能稳定复现,可以贴下代码,拿 Hamibot 这个 app 来测试。
ps:会不会是没给权限,比如后台弹出什么的


拿 Hamibot 来测试,最小能复现的代码就行,否则没环境去复现


currentActivity 名字有些不准确,实际是获取最近一次,可以加个判断,不是目标 app 的话 launch 回去,有时候可能要先 home 到桌面再 launch

0
Magma · 4 个月前
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

权限都给了,所有能给的权限都给了

0