如何通过ADB锁定安卓屏幕?

60

有没有一种通过ADB锁定Android屏幕的方法?

我找到了在apk中锁定显示的方法,但是我想通过ADB从PC上锁定屏幕,模拟显示超时而不必等待超时。

这是可能的吗?

谢谢, Diane


锁定/解锁和关机/开机一样吗?对我来说它的作用就像是关机/开机。 - ransh
8个回答

92

酷,我刚刚发现 KEYCODE_POWER 是26。

所以它是通过发送以下内容来工作的:

adb shell input keyevent 26

如果屏幕没有锁定,则会锁定屏幕。如果屏幕已经锁定,则唤醒设备。

我的猜想是,确保屏幕被锁定(关闭)的唯一方法是解锁(我们使用keyevent 82(菜单),然后使用电源键keyevent锁定它。有人知道这是否正确吗?


很棒,我将它作为一个批处理文件放在了Windows桌面上,并添加了一个快捷键。 - AVEbrahimi
很遗憾,它在Cubietruck上的作用是关机并关闭设备。 - Cԃաԃ
这太好了。我遇到相反的问题 - 我使用的设备会进入睡眠状态,而且没有任何实体按键,所以我不得不一直重置它。有了这个,就像一个唤醒(按下“电源”按钮)一样方便。谢谢。 - CJBS
它可以开/关机(与锁定/解锁相同?),但在我的一个设备(kitkat)中可以使用,而在另一个设备(marshmellow)中失败。 - ransh

19

迈克尔·R·海恩斯提供了可能是最简单的解决方案。然而,在后面版本的Android中,以下行不再有用。

adb shell input keyevent 82 # unlock

我已经更新了使用特定设备 (平板电脑) 唤醒所需的坐标的 shell 脚本。我的平板电脑不支持锁屏事件的方向更改,因此这些值始终适用于横屏锁屏。如果需要检测方向更改,则简单的 if/then/else 语句就足以选择要用于方向的正确坐标。

#!/bin/bash
if [ "$(adb shell dumpsys power | grep mScreenOn= | grep -oE '(true|false)')" == false ] ; then
    echo "Screen is off. Turning on."
    adb shell input keyevent 26 # wakeup
    adb shell input touchscreen swipe 930 380 1080 380 # unlock
    echo "OK, should be on now."
else 
    echo "Screen is already on."
    echo "Turning off."
    adb shell input keyevent 26 # sleep
fi

你为什么要建议如何解锁设备,当原帖作者想要锁定设备呢? - KurtCobain
你是绝对正确的。我不知怎么错过了这一部分。我已经修改了脚本以反映所需的更改。谢谢@KurtCobain。 - Rescue9
我的手机 Motorola Razr 上没有“touchscreen”这个命令,应该只是“swipe”,而不是“touchscreen swipe”。 - JPM
似乎在Lollipop中没有mScreenOn,但是Display power state=OFF/ON可以起到作用,所以tmp="$(adb -s $udid shell dumpsys power | grep 'mScreenOn=\|state' | grep -oE '(true|false|ON|OFF)')" + if [ "$tmp" == 'false' ] || [ "$tmp" == 'OFF' ]; then {...} - Fanch
为什么你说“adb shell input keyevent 82”在当前版本上不起作用?在安卓7的Nexus 6上它是可以工作的。 - David

10

这是一个完整的 Bash 脚本,它会检查屏幕是否开启,然后一次性唤醒并解锁屏幕:

if [ "$(adb shell dumpsys power | grep mScreenOn= | grep -oE '(true|false)')" == false ] ; then
    echo "Screen is off. Turning on."
    adb shell input keyevent 26 # wakeup
    adb shell input keyevent 82 # unlock
    echo "OK, should be on now."
else 
    echo "Screen is already on."
fi

6

你已经找到了解决方案,但我还是会在这里提供代码作为参考。

你可以注入事件来“按下”电源按钮两次。如果你不知道设备的状态(显示器开/关),则检查屏幕当前是否开启或关闭,并相应地按下电源按钮。

以下是一个简单的monkeyrunner脚本:

import re
from java.util import *
from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice
device = MonkeyRunner.waitForConnection()       # connect to a device
device.shell("input keyevent KEYCODE_POWER")    # turn screen off (or on?)
res = device.shell("dumpsys power")             # fetch power state
m = re.search(r'.*mPowerState=([0-9]+).*', res) # parse the string
if m and int(m.group(1)) == 0:                  # screen is off
  device.shell("input keyevent KEYCODE_POWER")  # turn the screen on

1
mPowerState可能不是int类型。在三星Galaxy SIII上,这一行代码是: mPowerState = SCREEN_BRIGHT_BIT | SCREEN_ON_BIT - Juuso Ohtonen
@Jakub:感谢您的回答!抱歉我花了这么长时间才注意到<脸红>。我几乎完全使用Perl脚本和一些shell脚本来工作,使用adb命令。但是当我需要做更多这样的事情时,我会将此放入我的参考资料中以获取更强大的功能。 - PurpleDiane
@Juuso:知道这点很好,谢谢。我在测试手机上工作,所以知道一个可能会有不同的显示很重要。 - PurpleDiane
请注意,自Android 4.4W(API 20)以来,一直存在常量KEYCODE_SLEEP,它解决了其中的一个问题。“睡眠键。将设备置于睡眠状态。行为类似于KEYCODE_POWER,但如果设备已经处于睡眠状态,则没有任何影响。” - Shenk

5
除了之前的答案,以下是我使用adb锁定/解锁屏幕的方法: adb shell input keyevent 26 将锁定屏幕。
因此,如果您在关闭/锁定屏幕时再次执行该命令,则会打开/解锁屏幕。
adb shell input keyevent 26 也可以解锁屏幕(如果屏幕已锁定)。
此外,我还测试了所有的命令,例如 adb shell input keyevent number,发现 adb shell input keyevent 3 也可以解锁设备。
我还发现(通过测试),键3是主页按钮。 因此,如果您有物理主页按钮(不是屏幕上的软主页按钮),也可以使用它来解锁设备。

1

这里有一个脚本,可以打开/关闭每个连接设备的屏幕,包括任何早于Lollipop版本的设备。我在我的Jenkins服务器上使用它,在运行任何连接的Android测试之前,确保设备已准备好。希望有人会发现这个有用!

#!/bin/sh

# Returns the power state of the screen 1 = on, 0 = off
getDisplayState() {
    state=$(adb -s $1 shell dumpsys power | grep mScreenOn= | grep -oE '(true|false)')

    # If we didn't get anything it might be a pre-lollipop device
    if [ "$state" = "" ]; then
        state=$(adb -s $1 shell dumpsys power | grep 'Display Power' | grep -oE '(ON|OFF)')
    fi

    if [ "$state" = "ON" ] || [ "$state" = "true" ]; then
        return 1;
    else
        return 0;
    fi
}

echo "Turning on screen on all connected devices..."

for device in `adb devices | grep device$ | cut -f1`
do
    echo -n "Found device: $device ... "

    getDisplayState $device
    state=$?

    # If the display is off, turn it on
    if [ $state -eq 0 ]; then
        echo "display was off, turning on"
        adb -s $device shell input keyevent 26
    else
        echo "display was on"
    fi

done

1
你可以使用以下命令来触发显示屏幕开启。 adb shell input keyevent POWER 我已经尝试并在我的项目中使用,希望对你有用。
这是我使用的Ruby代码:
def ScreenCheck()
system("adb shell dumpsys power > c:/interact.log")

File.open("C:\\interact.log").each do |line|
    if line[/mScreenOn/]
        if line.strip == "mScreenOn=true"
            p "Screen is On, Starting execution.."
        else
            p "Screen is Off, starting screen.."
            system("adb shell input keyevent = POWER")
            p "Starting execution.."
        end
    end
end
end

1

对于那些使用较早版本的安卓系统(至少4.2+)的用户,dumpsys power的输出会有所不同。
@Jakub Czaplicki给出的答案mPowerState=不同,我使用了mScreenOn=

p = Runtime.getRuntime().exec("su", null, null);
OutputStream o = p.getOutputStream();
o.write(("dumpsys power").getBytes("ASCII"));
o.flush();
o.close();
p.waitFor();

boolean screenState;
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((res = in.readLine()) != null) dump += res;
screenState = dump.charAt( dump.indexOf("mScreenOn=") + 10 ) == 't';

screenStatetrue (屏幕开启),或者是 false (屏幕关闭)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接