【问题标题】:How to send key down and key up events separately on android using ADB?如何使用 ADB 在 android 上分别发送 key down 和 key up 事件?
【发布时间】:2021-04-06 00:58:03
【问题描述】:

有一个answered question about sending long presses on android,问题在于

  • 实际上没有一个答案有效,有些使用过时的 API,有些 API 太新
  • 我需要发送按键按下事件,然后才决定解除按键

从链接问题的最高投票答案开始,我有以下代码:

adb shell sendevent /dev/input/event2 1 172 1
adb shell sendevent /dev/input/event2 0  0 0
timeout 1
adb shell sendevent /dev/input/event2 1 172 0
adb shell sendevent /dev/input/event2 0 0 0

这些命令不起作用,答案的作者也没有说出命令的作用和原因。通过一些实验,我发现:

  • 必须是/dev/input/event0 而不是event2
  • 更改任何数字都不会发生任何事情
  • adb shell sendevent /dev/input/event2 0 0 0 是必需的。我不知道它有什么作用

现在我需要发送按键的向上/向下事件,包括那些不在设备上的按键(例如 KEYCODE_DPAD_DOWN),所以 adb shell getevent 没有多大帮助 - 我无法按下不存在的键。我正在使用 Android 4.1.2 三星手机。

还有谁能给我解释一下0 0 0事件是什么?

【问题讨论】:

  • @AlexP。我真的厌倦了在没有彻底阅读问题的情况下投票重复的人。问题的答案是否与您的问题相关联?不,它没有!那么到底是什么? StackOverflow 是否感染了一些根据谷歌搜索结果投接近票的机器人?
  • 您要发送哪个关键事件?你的意思是像卷一样的“关键”。上/下键还是别的什么?
  • @TDG 好问题,我在问题中添加了信息。基本上在KeyEvent specs 中定义的任何键都是有用的。

标签: android shell adb


【解决方案1】:

我很久以前就做过了,所以我不记得所有细节了。希望我不会错过任何重要的事情...
设备上存在的所有输入硬件都映射到文件中(它是 Linux,所以当然一​​切都是文件......)。如果您执行adb shell ls /dev/input,您会看到很少的eventX 文件,从event0 及以上。这些文件映射到屏幕(触摸屏,而不是显示器!通常是event2)、硬键(通常是event0)、接近传感器和设备的所有其他传感器/输入。
要记住的另一件事是这些不是“普通”文件,而是“字符文件”——它是一种仅在相关输入设备被激活时才具有数据的缓冲区。您可以输入adb shell cat /dev/input/event0,直到您按下设备上的某个物理键,例如homevol up,您才会看到任何东西。当您按下某个键时,您会在屏幕上看到一些乱码,但这些乱码当然是有意义的。
键入adb pull /dev/input/event0,按下并释放vol up,然后按下ctrl-c 以停止pull 命令。现在你将有一个名为event0 的二进制文件,所以用一些十六进制编辑器打开它,你会得到类似 -

59 07 00 00 80 C9 07 00 01 00 18 00 01 00 00 00
59 07 00 00 80 C9 07 00 00 00 00 00 00 00 00 00
5A 07 00 00 96 60 01 00 01 00 18 00 00 00 00 00
5A 07 00 00 96 60 01 00 00 00 00 00 00 00 00 00

每行的前 8 个字节是事件的时间戳,其他 8 个字节是事件本身。
第一行正在按下vol. up 键(小端序) :
01 00 是事件的 ID。如果您同时按下两个键,您将获得两个具有两个 ID 的事件。
18 00键代码
01 00 是事件类型。 01 是按下,00(如第 3 行)是释放。
00 00(最后两个字节)在这里没有使用。例如,对于屏幕触摸,它保存屏幕坐标。
第二行是一些包含全零的缓冲区清理/同步事件。
第三行正在释放密钥。和第一行一样,但是事件类型是00
第四行还是同步事件。
现在,如果您创建一个名为eventFile 的文件,其中包含前两行,您实际上有一个按vol. up 键的序列。您可以使用 - adb push eventFile /dev/input/event0 将其注入设备,您会看到 vol. up 键被按下但未释放 - 长按。要释放它,只需发送另一个文件和另外两行。您不必担心时间戳,您可以保持原样。
对于不同的键,您当然必须更改 key code
我已经在我的设备上尝试过 - 三星 S3 mini /4.1.2 带有两个 vol up/down 键,它可以工作。我没有尝试使用不存在的键盘键。

【讨论】:

  • 没有“通常的”输入设备文件分配之类的东西 - 没有规则。事件的确切二进制格式取决于内核位数 - 您的是 32 位内核。此外,每个输入设备都有一个定义支持事件的功能位掩码 - 您将无法使用不受支持的键代码注入事件。
  • @AlexP。 - “没有“通常的”输入设备文件分配之类的东西” - 你的意思是 event0 不是所有设备上的硬键吗?据我回忆,触摸屏和硬键总是一样的,但我不知道其他传感器。
  • 您看过多少台设备?我个人参与了 50 多种 Android 设备的开发,并且我见过大约 200 种其他型号,我告诉你 - 没有规则。
  • 嗯,我见过十几种不同的设备,但其中大多数(如果不是全部)都是三星。
【解决方案2】:

为了帮助以后可能需要此信息的任何人,这是我从@TDG 帖子和其他 StackOverflow 答案中汇总的内容。

有不同的文件可以映射到设备硬件,例如触摸屏或物理按钮。目前尚不清楚相同的文件是否映射到所有 Android 手机上的相同硬件,但我预计会有一些不同的设备,所以要小心。

这些文件称为 /dev/input/eventX,其中 X 指的是硬件的 0 索引编号。

要为您感兴趣的设备找到正确的文件,您可以使用getevent

adb shell su 0 getevent

这将输出每个设备的名称和 ID。当你有了正确的路径后,你就可以开始监听传入的事件了:

adb shell su 0 getevent /dev/input/event0

当它运行时触发您设备上的事件,例如按下您感兴趣的按钮。这将输出如下内容:

0001 0095 00000001
0000 0000 00000000
0001 0095 00000000
0000 0000 00000000

这些是我按下并释放硬件按钮时的条目。请注意,每个事件有 2 组(前 2 组按键向下,后 2 组按键向上)

请注意,这些值是十六进制的。将它们转换为十进制。使用计算器或 hex2dec 站点来执行此操作。然后,您可以使用 sendevent

注入事件

按键

adb shell su 0 sendevent /dev/input/event0 1 149 1 # Hex: 0001 0095 00000001
adb shell su 0 sendevent /dev/input/event0 0 0 0   # Hex: 0000 0000 00000000

按键

adb shell su 0 sendevent /dev/input/event0 1 149 0 # Hex: 0001 0095 00000000
adb shell su 0 sendevent /dev/input/event0 0 0 0   # Hex: 0000 0000 00000000

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多