如何使用线程一直寻找到指定文本并且点击
第 1 条补充
· 1 个月前
如何使用ocr识别指定文本区域点击
第 2 条补充
· 1 个月前
如何让脚本持有cpu锁,不休眠
回答
要实现持续寻找指定文本并点击的功能,可以通过后台线程结合条件判断和点击操作完成。以下是具体实现方法:
// 启动后台线程
threads.start(function () {
// 定义递归检查函数
const check = () => {
// 检查当前界面是否存在目标文本
if (text("需要点击的文本").exists()) {
// 找到文本后点击(默认点击第一个匹配项)
text("需要点击的文本").findOnce().click();
// 点击成功后停止检查
return;
}
// 未找到时每500ms重复检查
setTimeout(check, 500);
};
// 初始调用检查函数
check();
});
代码说明:
- 线程机制:使用
threads.start()
创建独立线程,避免阻塞主脚本流程 - 文本检测:通过
text("文本内容").exists()
实时监控目标文本出现 - 精准点击:
findOnce().click()
确保只点击最先发现的匹配项(可替换为click()
点击全部匹配项) - 循环策略:未找到时通过
setTimeout
实现每 500ms 轮询检查
参数定制:
- 将
text("需要点击的文本")
替换为实际目标文本 - 如需点击特定位置可追加索引参数:
text("文本").findOnce(i)
(i 从 0 开始) - 若需要匹配复杂文本模式,可使用正则表达式:
textMatches(/正则表达式/).exists()
终止条件:
- 成功点击后自动停止
- 若需强制终止线程,可调用
threads.shutDownAll()
结束所有线程
注意事项:
- 需确保已启用无障碍服务
- 复杂界面建议配合
id("控件ID")
定位提升准确性 - 可通过
sleep(1000)
添加延迟防止过快重复操作
完整实现参考以下模板:
// 监控线程模板
threads.start(function () {
const targetText = "目标文本";
const check = () => {
if(text(targetText).exists()){
let widget = text(targetText).findOnce();
if(widget && widget.click()){
log(`成功点击:${targetText}`);
return; // 点击成功后退出
}
}
setTimeout(check, 500); // 继续监控
};
check();
});
文档地址 https://docs.hamibot.com/
补充回答 1
// 文档地址 https://docs.hamibot.com/
// 申请截图权限
auto.waitFor();
if (!requestScreenCapture()) {
toastLog("请授予截图权限");
hamibot.exit();
}
// 定义识别点击函数
function ocrClick(targetText) {
// 截取全屏
const img = captureScreen();
// OCR识别(带坐标信息)
let results = ocr.recognize(img);
// 遍历识别结果
for (let i = 0; i < results.length; i++) {
if (results[i].text.includes(targetText)) {
// 获取文本区域坐标
let bounds = results[i].bounds;
// 计算中心点
let centerX = (bounds.left + bounds.right) / 2;
let centerY = (bounds.top + bounds.bottom) / 2;
// 点击中心区域(±10像素范围)
gesture(1000, [
[centerX - 10, centerY - 10],
[centerX + 10, centerY + 10]
]);
return true;
}
}
return false;
}
// 调用示例
if (ocrClick("需要点击的文本")) {
toastLog("点击成功");
} else {
toastLog("未找到目标文本");
}
实现原理:
- 权限准备:通过
auto.waitFor()
和requestScreenCapture()
获取必要权限 - 精准截图:使用
captureScreen()
获取当前屏幕图像 - 坐标识别:调用
ocr.recognize()
获取包含位置信息的识别结果(返回数组格式) - 文本匹配:通过
.includes()
模糊匹配目标文本(可替换为正则匹配) - 坐标计算:根据 bounds 对象计算文本区域中心点坐标
- 手势模拟:使用
gesture()
执行点击动作(比 click() 更适合精确坐标操作)
参数说明:
bounds
对象包含:- left: 文本区域左侧坐标
- top: 文本区域顶部坐标
- right: 文本区域右侧坐标
- bottom: 文本区域底部坐标
gesture(duration, points)
:- duration: 手势持续时间(毫秒)
- points: 坐标范围数组 [[x1,y1],[x2,y2]]
优化建议:
- 区域限制:对特定区域截图可提高效率:
const regionImg = images.clip(img, 100, 200, 500, 400); // 左、上、右、下坐标 const result = ocr.recognize(regionImg);
- 异常处理:
try { const result = ocr.recognize(img); } catch (e) { toastLog("识别失败:" + e); }
- 图像预处理:
const grayImg = images.grayscale(img); // 灰度处理 const resizedImg = images.resize(img, [300, 400]); // 缩放优化
典型应用场景:
- 自动点击验证码
- 识别对话框按钮
- 处理无控件ID的界面
- 动态文本响应系统
补充回答 2
要防止设备休眠并保持CPU活跃,可通过以下方式实现:
核心方案
// 保持屏幕常亮(推荐使用超长超时替代永久)
device.keepScreenOn(3600 * 1000); // 保持1小时常亮(最大支持时间)
// 可选:允许屏幕变暗但保持CPU运行
device.keepScreenDim(3600 * 1000);
// 释放屏幕常亮锁
device.cancelKeepingAwake();
完整代码示例
// 文档地址 https://docs.hamibot.com/
// 开始保持CPU活跃
device.keepScreenOn(3600 * 1000); // 保持1小时
// 模拟长时间任务
toastLog("开始执行耗时任务...");
sleep(300000); // 模拟5分钟任务
toastLog("任务完成");
// 释放锁(建议在任务结束时调用)
device.cancelKeepingAwake();
实现原理:
- 屏幕常亮锁:通过
device.keepScreenOn()
持有屏幕电源锁 - CPU保活机制:安卓系统在屏幕常亮状态下会保持CPU唤醒
- 超时控制:由于安卓系统限制,建议使用最大可接受时间替代永久保持
设备适配建议:
- MIUI系统:
- 设置 > 电池 > 应用省电管理 > 选择Hamibot > 关闭省电策略
- 设置 > 应用管理 > Hamibot > 自启动权限 > 开启
- EMUI系统:
- 电池 > 应用启动管理 > Hamibot > 关闭自动管理
- 通用设置:
- 保持Hamibot在最近任务列表中
- 确保未启用深度睡眠模式
高级技巧:
- 结合唤醒机制:
// 每小时自动续期
setInterval(function() {
device.keepScreenOn(3600 * 1000);
}, 3500000); // 58分钟刷新一次
- 检测屏幕状态:
if (!device.isScreenOn()) {
device.wakeUp(); // 激活屏幕
sleep(5000); // 等待屏幕完全唤醒
}
- 电量优化:
// 使用变暗模式降低功耗
device.keepScreenDim(3600 * 1000);
// 监控电量
setInterval(function() {
var level = device.getBattery(); // 获取当前电量
if(level < 15) {
toastLog("电量低于15%,建议停止脚本");
}
}, 300000); // 每5分钟检测一次
注意事项:
- 部分设备最大支持时长为3600000ms(1小时)
- 需确保无障碍服务和前台服务已启用
- 长时间运行建议连接充电器
- 不同安卓版本电源策略存在差异
- 某些设备需要保持Hamibot在前台显示
ℹ️ 本回答由 AI 生成,内容仅供参考