在做UI自动化并用定时跑脚本的,都会经过锁屏/唤起这一步骤,为了更好的学习,把过程记录下来(本文以用真机跑为例),目前先写了android的,后面可能会补充iOS的
一、如何确保手机为解锁状态
- 首先,有一种“笨办法”,解锁之后,如下图,更改手机设置选项,开发者选项-保持唤醒状态,使之不会自动锁屏就好,但是这种方法并不是对所有手机适用,而且,有点费电。。
- 其次,就是一般的思路,首先检测一下当前手机屏幕状态是否为锁屏状态,如果是,唤醒,如果不是,继续下一步操作
二、判断当前手机是否为锁屏状态
-
我用的是Airtest,好处是有封装好的方法,例如
-
is_screenon(),如果屏幕没有亮,会返回True,如果屏幕亮了会返回False;
- 注意一点是,这个方法并不是判断锁屏/解锁,而是屏幕亮/不亮,屏幕亮了之后还需要swipe划一下才能解锁
-
is_locked(),如果屏幕锁定会返回True,反之返回False
is_screenon() Perform adb shell dumpsys window policy command and search for information if screen is turned on or off Raises: AirtestError – if screen state can’t be detected 返回: True or False whether the screen is turned on or off
is_locked() Perform adb shell dumpsys window policy command and search for information if screen is locked or not Raises: AirtestError – if lock screen can’t be detected 返回: True or False whether the screen is locked or not
-
-
在实际使用的时候发现有的机型系统用is_sceenon()这个封装的方法并不好使,会报error,于是去翻了下源码,如下
-
可以看到,本质是在shell里使用adb命令,然后用正则匹配出来结果返回
def is_screenon(self): """ Perform `adb shell dumpsys window policy` command and search for information if screen is turned on or off Raises: AirtestError: if screen state can't be detected Returns: True or False whether the screen is turned on or off """ screenOnRE = re.compile('mScreenOnFully=(true|false)') m = screenOnRE.search(self.shell('dumpsys window policy')) if m: return (m.group(1) == 'true') raise AirtestError("Couldn't determine screen ON state")
-
-
于是查看了一下adb的实际返回内容,过滤了一下带有screen的关键词,结果如下图:
-
可以看到封装的方法是用的mScreenOnFully这个字段判断的,而当前机型是用screenState这个字段返回的,找到了根本原因,就好解决啦
三、解锁
-
Airtest中提供了wake()方法用来唤醒屏幕,多数手机通过此操作都能唤醒屏幕
Android().wake()
-
实际使用过程中发现有的手机并不能被唤醒,查看日志发现,这里的wake使用的是home事件
-
对于不能用home唤醒的机型,换成power事件即可解决
keyevent("power")
-