const img = captureScreen();OCR截图,在部分手机下,一加13,红米k60U,首次打开脚本,开始,然后授权截图权限,脚本正常跑没问题,但是,如果这时候手机锁屏,在解锁,那么就会导致截图拿不到,导致脚本卡死,这是什么问题,正常跑不锁屏就不会有这个问题
回答
这个问题通常是因为锁屏后系统回收了截图权限(MediaProjection 服务被暂停),导致 captureScreen() 阻塞或永远无法返回截图,从而脚本卡死。
原因分析
- 当你首次调用
requestScreenCapture()授权后,系统会启动一个屏幕捕捉会话(MediaProjection)。在部分机型(如一加13、红米K60U)上,锁屏会触发该会话被暂停或终止。 - 解锁后,虽然应用仍在运行,但截图链路已经中断,
captureScreen()会一直等待新的帧数据,如果底层不抛异常也不返回,就会造成死等,即你看到的“卡死”。
解决办法
-
在解锁后重新请求截图权限
可以在脚本中定期检测屏幕是否解锁,解锁后重新调用requestScreenCapture()并再次授权。例如:// 文档地址 https://docs.hamibot.com/ function ensureScreenCapture() { if (!requestScreenCapture()) { toastLog('截图权限获取失败'); hamibot.exit(); } // 等待截图服务就绪 sleep(500); } // 监听解锁事件(需要设备支持) if (device.isScreenOn && device.isScreenOn()) { events.onKeyDown('power', function() { sleep(1000); if (device.isScreenOn()) { ensureScreenCapture(); } }); }如果设备没有可靠的解锁广播,可以改为在每次截图前检查并重试:
function safeCapture() { try { var img = captureScreen(); return img; } catch (e) { // 截图失败,重新请求权限 ensureScreenCapture(); return captureScreen(); } } -
保持屏幕常亮,避免锁屏
在脚本开始时设置:device.keepScreenOn(3600 * 1000); // 保持1小时这样在脚本运行期间不会自动锁屏。
-
使用超时机制避免死等
如果可以,给captureScreen()加一个超时判断,但该函数本身不支持超时参数。你可以通过threads启动一个定时器,如果超时则强制重新请求权限或重启脚本。例如:function captureWithTimeout(timeout) { var result = null; var done = false; var captureThread = threads.start(function() { result = captureScreen(); done = true; }); var start = new Date().getTime(); while (!done && (new Date().getTime() - start) < timeout) { sleep(100); } if (!done) { captureThread.interrupt(); toastLog('截图超时,重新请求权限'); ensureScreenCapture(); return captureScreen(); } return result; }
最佳实践
- 在
requestScreenCapture()后立即调用一次captureScreen()并丢弃结果,确保底层链路完全建立,避免首帧延迟。 - 如果脚本需要长时间运行且可能被锁屏,建议在每次截图前判断
device.isScreenOn(),屏幕关闭时主动等待或唤醒屏幕后再截图。
这些方法可以有效避免锁屏导致的截图卡死问题。如果你使用的是开发脚本,请参考 Hamibot 文档 了解 captureScreen 和 device 模块的更多细节。
ℹ️ 内容由 AI 生成,可能不准确,请注意核实