auto();
requestScreenCapture();
const IMG_PATH = "/sdcard/Hamibot/";
const CROWN_IMG = IMG_PATH + "王冠.png";
const SVIP_IMG = IMG_PATH + "SVIP.png";
const ADD_BTN_IMG = IMG_PATH + "加好友.png";
const SWIPE_DURATION = 300;
const SCROLL_WAIT = 3000;
const AFTER_CLICK_WAIT = 2000;
const AFTER_ADD_WAIT = 2000;
const MAX_SCROLL_TIMES = 30;
const MATCH_THRESHOLD = 0.8;
const ITEM_HEIGHT = 200;
const FIRST_ITEM_TOP = 290;
function findImageInRegion(screenshot, templatePath, region) {
if (region === undefined) region = null;
let template = images.read(templatePath);
if (!template) return null;
let options = { threshold: MATCH_THRESHOLD };
if (region) options.region = region;
let point = findImage(screenshot, template, options);
template.recycle();
return point;
}
function hasBothIconsInItem(screenshot, itemTopY) {
let screenWidth = device.width;
let region = [0, itemTopY, screenWidth, ITEM_HEIGHT];
let crownPoint = findImageInRegion(screenshot, CROWN_IMG, region);
if (!crownPoint) return false;
let svipPoint = findImageInRegion(screenshot, SVIP_IMG, region);
return svipPoint !== null;
}
function clickUserItem(itemTopY) {
let screenWidth = device.width;
let x = screenWidth / 2;
let y = itemTopY + ITEM_HEIGHT / 2;
click(x, y);
sleep(AFTER_CLICK_WAIT);
}
function clickAddFriendButton() {
let screenshot = captureScreen();
if (!screenshot) return false;
let point = findImageInRegion(screenshot, ADD_BTN_IMG, null);
screenshot.recycle();
if (point) {
click(point.x + point.width / 2, point.y + point.height / 2);
return true;
}
return false;
}
function main() {
if (!requestScreenCapture()) {
toast("截图权限获取失败");
return;
}
launchApp("口信");
sleep(3000);
toast("请进入【想认识的人】列表,3秒后开始");
sleep(3000);
swipe(device.width / 2, 600, device.width / 2, 200, SWIPE_DURATION);
sleep(2000);
let scrollCount = 0;
let successCount = 0;
while (scrollCount < MAX_SCROLL_TIMES) {
let screenshot = captureScreen();
if (!screenshot) {
sleep(1000);
continue;
}
let screenHeight = screenshot.getHeight();
let screenWidth = screenshot.getWidth();
let itemsCount = Math.min(Math.floor((screenHeight - FIRST_ITEM_TOP) / ITEM_HEIGHT), 5);
for (let i = 0; i < itemsCount; i++) {
let itemTop = FIRST_ITEM_TOP + i * ITEM_HEIGHT;
if (itemTop + ITEM_HEIGHT > screenHeight) break;
if (hasBothIconsInItem(screenshot, itemTop)) {
toast("发现目标用户");
clickUserItem(itemTop);
if (clickAddFriendButton()) {
toast("已发送好友申请");
successCount++;
sleep(AFTER_ADD_WAIT);
} else {
toast("未找到加好友按钮");
}
back();
sleep(2000);
screenshot.recycle();
screenshot = captureScreen();
if (!screenshot) break;
}
}
screenshot.recycle();
let startY = screenHeight - 200;
let endY = 200;
swipe(device.width / 2, startY, device.width / 2, endY, SWIPE_DURATION);
sleep(SCROLL_WAIT);
scrollCount++;
}
toast("完成,共添加 " + successCount + " 位");
}
main();
在hamibot运行不了是为什么
回答
脚本无法运行通常由权限配置、资源文件缺失或代码兼容性导致。请按照以下核心要点进行排查和优化:
1. 权限未正确授予(最常见原因)
脚本依赖 Android 无障碍服务和截图权限才能操作界面。如果权限缺失,脚本往往会在启动后立即退出或卡死。
- 无障碍服务:进入手机「设置」→「无障碍」→ 找到 Hamibot 并开启。
- 截图权限:脚本中调用了
requestScreenCapture()。首次运行时系统会弹出授权请求,必须点击“允许”。如果未授权,脚本无法获取屏幕图像,后续查找图片的逻辑会失效。 - 后台弹窗权限:部分安卓系统会拦截 Hamibot 的权限申请弹窗。需在「设置」→「应用管理」→ Hamibot → 权限中,确保允许“后台弹出界面”或类似权限。
2. 图片资源文件缺失
脚本通过 images.read 读取本地图片进行匹配。如果文件不存在,匹配逻辑会静默失败。
- 确认
/sdcard/Hamibot/目录下存在王冠.png、SVIP.png和加好友.png。 - 文件名必须严格匹配,包括后缀名和大小写。
- 建议使用 Hamibot 控制台的文件上传功能,确保路径正确。
3. 代码兼容性与规范
Hamibot 底层使用 Rhino 1.7.15 引擎,对现代 JavaScript 特性支持不完全。
- 变量声明:建议将
const和let替换为var,以避免潜在的语法兼容问题。 - 权限检查:
requestScreenCapture()是阻塞函数,应检查其返回值。如果返回false,说明权限被拒绝,应主动退出或提示,避免后续空指针错误。 - 应用名称:
launchApp("口信")需确保手机上的应用名称完全一致,否则无法启动目标应用。 - 代码头注释:所有脚本代码开头需添加标准文档注释。
4. 优化后的代码示例
以下是针对上述问题的修正版本,增加了兼容性处理和必要的注释:
// 文档地址 https://docs.hamibot.com/
auto();
// 统一使用 var 提高 Rhino 引擎兼容性
var IMG_PATH = "/sdcard/Hamibot/";
var CROWN_IMG = IMG_PATH + "王冠.png";
var SVIP_IMG = IMG_PATH + "SVIP.png";
var ADD_BTN_IMG = IMG_PATH + "加好友.png";
var SWIPE_DURATION = 300;
var SCROLL_WAIT = 3000;
var AFTER_CLICK_WAIT = 2000;
var AFTER_ADD_WAIT = 2000;
var MAX_SCROLL_TIMES = 30;
var MATCH_THRESHOLD = 0.8;
var ITEM_HEIGHT = 200;
var FIRST_ITEM_TOP = 290;
function findImageInRegion(screenshot, templatePath, region) {
if (region === undefined) region = null;
var template = images.read(templatePath);
if (!template) return null;
var options = { threshold: MATCH_THRESHOLD };
if (region) options.region = region;
var point = findImage(screenshot, template, options);
template.recycle();
return point;
}
function hasBothIconsInItem(screenshot, itemTopY) {
var screenWidth = device.width;
var region = [0, itemTopY, screenWidth, ITEM_HEIGHT];
var crownPoint = findImageInRegion(screenshot, CROWN_IMG, region);
if (!crownPoint) return false;
var svipPoint = findImageInRegion(screenshot, SVIP_IMG, region);
return svipPoint !== null;
}
function clickUserItem(itemTopY) {
var screenWidth = device.width;
var x = screenWidth / 2;
var y = itemTopY + ITEM_HEIGHT / 2;
click(x, y);
sleep(AFTER_CLICK_WAIT);
}
function clickAddFriendButton() {
var screenshot = captureScreen();
if (!screenshot) return false;
var point = findImageInRegion(screenshot, ADD_BTN_IMG, null);
screenshot.recycle();
if (point) {
click(point.x + point.width / 2, point.y + point.height / 2);
return true;
}
return false;
}
function main() {
// 确保截图权限已获取
if (!requestScreenCapture()) {
toast("截图权限获取失败,请检查设置");
hamibot.exit();
}
launchApp("口信");
sleep(3000);
toast("请进入【想认识的人】列表,3秒后开始");
sleep(3000);
swipe(device.width / 2, 600, device.width / 2, 200, SWIPE_DURATION);
sleep(2000);
var scrollCount = 0;
var successCount = 0;
while (scrollCount < MAX_SCROLL_TIMES) {
var screenshot = captureScreen();
if (!screenshot) {
sleep(1000);
continue;
}
var screenHeight = screenshot.getHeight();
var screenWidth = screenshot.getWidth();
var itemsCount = Math.min(Math.floor((screenHeight - FIRST_ITEM_TOP) / ITEM_HEIGHT), 5);
for (var i = 0; i < itemsCount; i++) {
var itemTop = FIRST_ITEM_TOP + i * ITEM_HEIGHT;
if (itemTop + ITEM_HEIGHT > screenHeight) break;
if (hasBothIconsInItem(screenshot, itemTop)) {
toast("发现目标用户");
clickUserItem(itemTop);
if (clickAddFriendButton()) {
toast("已发送好友申请");
successCount++;
sleep(AFTER_ADD_WAIT);
} else {
toast("未找到加好友按钮");
}
back();
sleep(2000);
screenshot.recycle();
screenshot = captureScreen();
if (!screenshot) break;
}
}
screenshot.recycle();
var startY = screenHeight - 200;
var endY = 200;
swipe(device.width / 2, startY, device.width / 2, endY, SWIPE_DURATION);
sleep(SCROLL_WAIT);
scrollCount++;
}
toast("完成,共添加 " + successCount + " 位");
}
main();
5. 调试建议
- 如果脚本仍无法运行,请在 Hamibot 控制台的日志中查看具体的报错信息(如
Error: Cannot read property 'width' of null),这通常意味着captureScreen()失败。 - 确保手机处于亮屏状态,部分系统在锁屏下无法执行截图操作。
- 检查 Hamibot 客户端是否为最新版本,旧版本可能存在已知 Bug。