监听通知的同时执行模拟操作代码,监听到微信消息内容符合条件的,模拟操作停止执行,点击进入聊天窗口执行部分操作后,重新开始执行模拟操作代码,这个该怎么写

已存档
七月CX · 2 个月前
第 1 条补充
·
2 个月前

当模拟操作是一个死循环时,如何在循环中不影响模拟操作并不断地检测是否有新的微信消息进入

第 2 条补充
·
2 个月前

如果模拟操作和监听通知分别放入两个线程使用,会出现不可预知的问题么

回答

Hamibot AI
1
· 2 个月前

以下是一个实现监听通知并执行模拟操作的代码框架,符合你的需求:

// 文档地址 https://docs.hamibot.com/
var isRunning = true; // 控制主循环运行状态
var shouldPause = false; // 暂停标志

// 开启通知监听
events.observeNotification();
events.on('notification', function(n) {
    if (n.getPackageName() === 'com.tencent.mm') { // 微信通知
        var text = n.getText(); // 获取通知内容
        if (text && text.match(/符合条件的关键词/)) {
            shouldPause = true; // 设置暂停标志
        }
    }
});

// 主循环函数
function mainOperation() {
    while (isRunning) {
        // 检查是否需要暂停
        if (shouldPause) {
            handleWeChatMessage();
            shouldPause = false; // 重置标志
        }
        
        // 你的模拟操作代码
        // 例如: click("按钮文字");
        // 或: gesture(1000, [0, 0], [500, 500]);
        
        sleep(1000); // 操作间隔
    }
}

// 处理微信消息函数
function handleWeChatMessage() {
    // 1. 停止当前操作
    isRunning = false;
    
    // 2. 进入微信聊天窗口
    launch("com.tencent.mm");
    waitForPackage("com.tencent.mm");
    sleep(2000);
    
    // 3. 点击通知进入聊天(根据实际界面调整选择器)
    var notification = className("android.widget.TextView").textContains("联系人名字").findOne(5000);
    if (notification) notification.click();
    
    // 4. 在聊天窗口执行操作
    sleep(1500);
    // 例如: click("发消息");
    // 或输入文字: className("EditText").setText("回复内容");
    
    // 5. 返回主界面重新开始
    back(); // 返回
    sleep(1000);
    
    // 6. 重启主循环
    isRunning = true;
    mainOperation();
}

// 启动主循环
mainOperation();

关键点说明:

  1. 双标志控制

    • isRunning:控制整个脚本运行状态
    • shouldPause:通知触发时暂停主操作
  2. 通知处理流程

    • 使用 events.on('notification') 监听通知
    • 通过 n.getPackageName() 识别微信通知
    • 使用正则匹配关键词(修改 /符合条件的关键词/
  3. 微信操作注意事项

    • 实际选择器需要根据微信界面调整
    • 使用 waitForPackage() 确保界面加载完成
    • 操作之间添加 sleep() 避免操作过快
  4. 恢复机制

    • 微信操作完成后重置标志
    • 递归调用 mainOperation() 重启主循环

使用前需要:

  1. 替换代码中的 符合条件的关键词 为实际匹配文本
  2. 根据实际界面调整选择器(如 className("android.widget.TextView")
  3. 在Hamibot设置中开启「无障碍服务」和「后台弹出界面」权限

提示:如果遇到界面识别问题,可以使用Hamibot的「布局分析」功能获取准确的控件信息。


补充回答 1

要在死循环中执行模拟操作的同时不断检测是否有新的微信消息进入,可以使用多线程技术来实现。以下是一个基于 Hamibot 的代码示例:

// 文档地址 https://docs.hamibot.com/
var stopFlag = false; // 控制模拟操作是否停止

// 监听通知的线程
threads.start(function () {
    events.observeNotification();
    events.on('notification', function(n) {
        if (n.getPackageName() === 'com.tencent.mm') { // 微信通知
            var text = n.getText(); // 获取通知内容
            if (text && text.match(/符合条件/)) {
                stopFlag = true; // 设置停止标志
            }
        }
    });
});

// 模拟操作的主循环
function simulateOperations() {
    while (true) {
        if (stopFlag) {
            // 执行点击进入聊天窗口等操作
            click(100, 200); // 示例坐标,请根据实际需求修改
            sleep(1000);
            // 其他操作...

            stopFlag = false; // 重置标志位
        }

        // 正常的模拟操作
        // 例如: click("按钮文字");
        // 或: gesture(1000, [0, 0], [500, 500]);

        sleep(100); // 控制循环频率,避免占用过高CPU
    }
}

// 启动模拟操作
simulateOperations();

关键点说明:

  1. 多线程处理

    • 使用 threads.start() 创建一个独立线程专门监听通知
    • 主循环负责执行模拟操作
  2. 通信机制

    • 使用全局变量 stopFlag 作为信号量,在线程和主循环之间传递信息
  3. 性能优化

    • 在主循环中添加 sleep(100) 避免 CPU 占用过高
    • 在处理微信消息后重置标志位
  4. 扩展性设计

    • 可以在 if (stopFlag) 块中添加复杂的逻辑处理
    • 可以根据需要调整正则匹配条件 /符合条件/

注意事项:

  • 确保已经开启无障碍服务和后台弹窗权限
  • 实际坐标和控件选择器需要根据具体界面调整
  • 复杂操作建议分步骤添加日志输出方便调试

提示:对于长时间运行的脚本,建议添加异常处理机制,并定期检查内存使用情况。如果遇到复杂界面交互,推荐使用 className()id() 等选择器配合 findOne() 方法确保准确性。


补充回答 2

将模拟操作和监听通知分别放入两个线程中使用,是 Hamibot 中常见的多任务处理方式。只要合理设计,一般不会出现不可预知的问题。但需要注意以下几点:

✅ 推荐做法

  1. 独立职责分配

    • 一个线程负责监听通知(如 events.on('notification')
    • 另一个线程负责执行模拟操作(如点击、滑动等)
    • 使用共享变量或队列进行线程间通信
  2. 使用原子变量或锁机制

    • 当多个线程需要访问或修改同一个变量时,建议使用 threads.atomic()threads.lock() 来保证线程安全。
// 文档地址 https://docs.hamibot.com/
var flag = threads.atomic(false); // 原子变量,用于线程间通信

// 监听通知的线程
threads.start(function () {
    events.observeNotification();
    events.on('notification', function(n) {
        if (n.getPackageName() === 'com.tencent.mm') {
            var text = n.getText();
            if (text && text.match(/关键词/)) {
                flag.set(true); // 修改原子变量
            }
        }
    });
});

// 模拟操作的线程
threads.start(function () {
    while (true) {
        if (flag.get()) {
            // 执行暂停后的操作
            click(500, 1000);
            flag.set(false); // 重置标志
        }

        // 正常模拟操作
        gesture(1000, [100, 100], [500, 500]);
        sleep(1000);
    }
});

⚠️ 注意事项

  1. 避免长时间阻塞事件线程

    • 如果在 events.on() 回调中执行耗时操作(如循环、sleep 过长),会阻塞其他事件响应。
    • 应该在回调中只设置标志位,然后由主操作线程处理具体逻辑。
  2. 不要在多个线程中同时操作 UI 控件

    • Hamibot 的 UI 操作不是线程安全的,只能在一个线程中执行 UI 操作(例如:click(), gesture())。
    • 若多个线程都需要触发 UI 操作,建议通过标志变量通知主操作线程执行。
  3. 资源竞争问题

    • 多个线程访问共享变量(如 var count = 0;)时,可能造成数据不一致。
    • 使用 threads.atomic()threads.lock() 解决此类问题。

✅ 总结

项目 是否推荐
将监听通知与模拟操作放在不同线程 ✅ 推荐
在事件回调中直接执行复杂逻辑 ❌ 不推荐
多个线程同时执行 UI 操作 ❌ 不推荐
使用原子变量或锁处理共享数据 ✅ 推荐

只要遵循上述原则,使用多线程来实现监听通知和模拟操作是可以稳定运行的。

ℹ️ 本回答由 AI 生成,内容仅供参考