// 企业微信自动打卡 - 自动解锁版
// 锁屏密码: 521241
auto.waitFor();
auto.setMode("fast");

// ==================== 配置区 ====================
var PIN = "521241"; // 锁屏密码
var MORNING_START = 8; // 上班打卡开始
var MORNING_END = 9; // 上班打卡结束
var EVENING_START = 17; // 下班打卡开始
var EVENING_END = 19; // 下班打卡结束
// ===============================================

var now = new Date();
var hour = now.getHours();
var minute = now.getMinutes();

// 时间段判断
var mode = "";
if (hour >= MORNING_START && hour < MORNING_END) {
mode = "morning";
} else if (hour >= EVENING_START && hour < EVENING_END) {
mode = "evening";
} else {
toast("不在打卡时段");
exit();
}

// 随机延迟 0-180 秒
var delay = Math.floor(Math.random() * 180);
console.log("随机延迟 " + delay + " 秒");
sleep(delay * 1000);

// ==================== 解锁手机 ====================
console.log("开始解锁...");

// 唤醒屏幕
device.wakeUpIfNeeded();
sleep(800);

// 上滑显示密码输入界面
var w = device.width;
var h = device.height;
swipe(w / 2, h * 0.8, w / 2, h * 0.3, 300);
sleep(1000);

// PIN 密码键盘坐标计算
// 标准 Android 密码键盘: 3列 x 4行
// 列: 左=17%, 中=50%, 右=83%
// 行: row1=40%, row2=55%, row3=70%, row4=85%
function getPinPos(num) {
var col, row;
if (num == 0) { col = 1; row = 3; }
else if (num <= 3) { col = num - 1; row = 0; }
else if (num <= 6) { col = num - 4; row = 1; }
else if (num <= 9) { col = num - 7; row = 2; }

var x = w * (0.17 + col * 0.33);
var y = h * (0.40 + row * 0.15);
return [x, y];

}

// 输入密码
var pins = PIN.split("");
for (var i = 0; i < pins.length; i++) {
var num = parseInt(pins[i]);
var pos = getPinPos(num);
click(pos[0], pos[1]);
sleep(200);
}

console.log("密码输入完成");
sleep(1500);

// ==================== 打开企业微信 ====================
app.launchApp("企业微信");
console.log("打开企业微信");
sleep(5000);

// ==================== 进入工作台 ====================
var workTab = text("工作台").findOne(5000);
if (workTab) {
workTab.parent().click();
} else {
click(w / 2, h * 0.88);
}
sleep(3000);

// ==================== 找到打卡 ====================
swipe(w / 2, h * 0.6, w / 2, h * 0.3, 300);
sleep(2000);

var daka = text("打卡").findOne(5000);
if (daka) {
daka.parent().click();
} else {
toast("未找到打卡入口");
exit();
}
sleep(4000);

// ==================== 打卡 ====================
if (mode == "morning") {
var btn = text("上班打卡").findOne(5000);
if (btn) {
btn.parent().click();
toast("✅ 上班打卡 " + hour + ":" + minute);
}
} else {
var btn = text("下班打卡").findOne(5000);
if (btn) {
btn.parent().click();
toast("✅ 下班打卡 " + hour + ":" + minute);
}
}

sleep(3000);
home();
console.log("完成");

HAMI_7400109535 · 4 小时前

回答

Hamibot AI
1
· 4 小时前

你的脚本整体思路可行,但存在几个关键问题,可能导致运行失败或重复打卡。下面逐一说明并给出优化方案。


1. 脚本被重复执行(严重)

脚本末尾又完整复制了一遍前半部分代码,导致实际会执行两次打卡:第一次完毕后,会再次进入时间判断→延迟→解锁→打卡。
必须删除从第二个 // 企业微信自动打卡 - 自动解锁版 开始到结尾的所有重复内容。


2. app.launchApp 参数错误

app.launchApp("企业微信") 应使用包名而非应用显示名称。企业微信的包名是 com.tencent.wework
改为:

app.launchApp("com.tencent.wework");

3. 解锁流程不够健壮

  • device.wakeUpIfNeeded() 仅点亮屏幕,如果设备已亮屏但处于锁屏界面,你的上滑解锁动作可能失效。
  • 上滑解锁的坐标 swipe(w/2, h*0.8, w/2, h*0.3, 300) 假设锁屏界面就是上滑进入密码,但不同系统/主题可能不同(如需要先上滑再输入密码,或直接显示密码键盘)。
  • 密码键盘坐标基于固定百分比,不同分辨率和 DPI 的设备上数字位置可能偏移,导致点击错误密码,多次失败后可能锁死。

建议

  • 使用 Hamibot 的解锁插件或官方 unlock() 函数(若有),避免手动计算坐标。
  • 如果必须手动输入,应增加前置判断:检测当前是否在锁屏密码输入界面,例如通过寻找“重新输入”或“PIN”等文本,或使用 className("android.widget.TextView").text("0") 等控件定位键盘,但最可靠的方式仍是使用插件。

4. 界面元素查找可能不稳定

  • text("工作台").findOne(5000)text("打卡").findOne(5000) 依赖界面文本,企业微信改版后可能变化。
  • 坐标点击 click(w/2, h*0.88) 作为兜底,也容易点错。
  • 建议使用控件 ID 或 desc 定位,可先用 auto.layoutHierarchy() 或悬停分析工具获取属性。

5. 代码兼容性

你使用的语法(普通函数、无箭头函数、无默认参数)均兼容 Hamibot 的 Rhino 引擎,无需修改。


6. 建议的优化结构

  • 将解锁、打开企业微信、进入打卡等步骤封装成函数,提高可读性。
  • 增加异常处理,如解锁失败重试、打卡按钮不存在时重试一次。
  • 打卡完成后可加 device.cancelKeepingAwake() 恢复屏幕超时,避免耗电。

修改后的核心代码示例(已删除重复,修正包名,添加注释)

// 文档地址 https://docs.hamibot.com/
auto.waitFor();
auto.setMode("fast");

var PIN = "521241";
var MORNING_START = 8, MORNING_END = 9;
var EVENING_START = 17, EVENING_END = 19;

var now = new Date();
var hour = now.getHours();
var minute = now.getMinutes();

var mode = "";
if (hour >= MORNING_START && hour < MORNING_END) {
    mode = "morning";
} else if (hour >= EVENING_START && hour < EVENING_END) {
    mode = "evening";
} else {
    toast("不在打卡时段");
    exit();
}

var delay = Math.floor(Math.random() * 180);
console.log("随机延迟 " + delay + " 秒");
sleep(delay * 1000);

// 解锁
console.log("开始解锁...");
device.wakeUpIfNeeded();
sleep(800);
var w = device.width, h = device.height;
swipe(w / 2, h * 0.8, w / 2, h * 0.3, 300);
sleep(1000);

function getPinPos(num) {
    var col, row;
    if (num == 0) { col = 1; row = 3; }
    else if (num <= 3) { col = num - 1; row = 0; }
    else if (num <= 6) { col = num - 4; row = 1; }
    else if (num <= 9) { col = num - 7; row = 2; }
    var x = w * (0.17 + col * 0.33);
    var y = h * (0.40 + row * 0.15);
    return [x, y];
}

var pins = PIN.split("");
for (var i = 0; i < pins.length; i++) {
    var num = parseInt(pins[i]);
    var pos = getPinPos(num);
    click(pos[0], pos[1]);
    sleep(200);
}
console.log("密码输入完成");
sleep(1500);

// 打开企业微信
app.launchApp("com.tencent.wework");
sleep(5000);

// 进入工作台
var workTab = text("工作台").findOne(5000);
if (workTab) {
    workTab.parent().click();
} else {
    click(w / 2, h * 0.88);
}
sleep(3000);

// 找到打卡
swipe(w / 2, h * 0.6, w / 2, h * 0.3, 300);
sleep(2000);
var daka = text("打卡").findOne(5000);
if (daka) {
    daka.parent().click();
} else {
    toast("未找到打卡入口");
    exit();
}
sleep(4000);

// 执行打卡
if (mode == "morning") {
    var btn = text("上班打卡").findOne(5000);
    if (btn) btn.parent().click();
} else {
    var btn = text("下班打卡").findOne(5000);
    if (btn) btn.parent().click();
}
toast("✅ 打卡成功 " + hour + ":" + minute);
sleep(3000);
home();
console.log("完成");

建议下一步

  • 在实际设备上测试解锁坐标是否准确,若不准请改用插件。
  • 打开企业微信后,可增加 waitForPackage("com.tencent.wework") 确保完全启动。
  • 如果不想每次手动调试,可使用 Hamibot 的定时任务功能,让脚本在指定时段自动运行。

如果遇到其他具体问题,欢迎继续提问。

ℹ️ 内容由 AI 生成,可能不准确,请注意核实