ADB 아날로그 입력 이벤트 요약

ADB 아날로그 입력 이벤트

adb shell 명령어를 통해 사용자의 입력 동작을 시뮬레이션하고 스크립트 형태로 휴대폰을 조작할 수 있습니다. 시뮬레이션된 동작을 지원하는 두 가지 명령인 input 및 sendevent가 있습니다.

입력 명령

help 명령을 통해 사용량 보기:

➜  ~ adb shell input help
Usage: input [<source>] [-d DISPLAY_ID] <command> [<arg>...]

The sources are:
      dpad
      keyboard
      mouse
      touchpad
      gamepad
      touchnavigation
      joystick
      touchscreen
      stylus
      trackball

-d: specify the display ID.
      (Default: -1 for key event, 0 for motion event if not specified.)
      
The commands and default sources are:
      text <string> (Default: touchscreen)
      keyevent [--longpress] <key code number or name> ... (Default: keyboard)
      tap <x> <y> (Default: touchscreen)
      swipe <x1> <y1> <x2> <y2> [duration(ms)] (Default: touchscreen)
      draganddrop <x1> <y1> <x2> <y2> [duration(ms)] (Default: touchscreen)
      press (Default: trackball)
      roll <dx> <dy> (Default: trackball)
      motionevent <DOWN|UP|MOVE> <x> <y> (Default: touchscreen)

소스 유형은 다음과 같습니다.

소스 유형 의미
디패드 D-패드, 일반적으로 게임패드의 화살표 키
건반 건반
생쥐 생쥐
터치패드 터치패드
게임패드 핸들
터치네비게이션 탐색 모음
조종간 조종간
터치 스크린 터치 스크린
첨필 첨필
트랙볼 트랙볼

세 번째 매개변수는 -d특히 디스플레이 ID이고 기본값 -1은 키 값 이벤트를 나타내고 0은 제스처 이벤트를 나타냅니다.

명령의 목적 및 기본 소스 대상 장치 유형 구성:

주문하다 사용 기본 대상 장치 유형
text <string> 텍스트 입력 시뮬레이션 터치 스크린
keyevent [--longpress] <key code number or name> ... 키-값 이벤트 시뮬레이션 건반
tap <x> <y> 제스처 클릭 이벤트 시뮬레이션 터치 스크린
swipe <x1> <y1> <x2> <y2> [duration(ms)] 슬라이딩 시뮬레이션 터치 스크린
draganddrop <x1> <y1> <x2> <y2> [duration(ms)] 드래그 앤 드롭 시뮬레이션 터치 스크린
press 트랙볼 누르기 시뮬레이션 트랙볼
roll <dx> <dy> 롤링 트랙볼 시뮬레이션 트랙볼
`모션 이벤트 <DOWN 위로 이동> `

여기서 알 수 있듯이 ADB의 입력 명령을 통해 KeyEvent와 MotionEvent의 두 가지 이벤트를 시뮬레이션할 수 있습니다.

KeyEvent 이벤트 시뮬레이션

adb shell input keyevent <keycode>

키 코드는 int 유형 android.view.KeyEvent이며 KEYCODE_클래스에서 접두사가 붙은 상수 값으로 이벤트 정의를 지원합니다.

공식 위키 참조: developer.android.com/reference/a…

다음은 간단한 예입니다.

# 模拟点击音量 - 键
adb shell input keyevent EYCODE_VOLUME_DOWN
# 也可以换成数字
adb shell input keyevent 25
# 模拟长按事件,触发长按事件后就会取消按压。长按时间短,仅触发长按需要的最短时间。
adb shell input --longpress keyevent 25

시뮬레이션을 지원하는 키는 기본적으로 가능한 모든 주변 장치를 포함하는 키보드, 마우스, 게임 패드 등을 포함합니다.

MotionEvent 이벤트 시뮬레이션

# 模拟 ACTION_DOWN ,坐标位置 100,200
adb shell input motionevent DOWN 100 200

MotionEvent는 ACTION_DOWN / ACTION_MOVE / ACTION_UP에 해당하는 3가지 유형의 이벤트를 지원하고 해당 좌표를 입력합니다.

그러나 테스트 결과 MOVE의 경우 명령 입력의 거리가 너무 길지 않은 것으로 나타났습니다. 예를 들면 다음과 같습니다.

adb shell input motionevent DOWN 500 1000
adb shell input motionevent MOVE 500 900
adb shell input motionevent UP 500 900

명백한 미끄러짐이 없습니다.

그러나 업데이트할 때마다 거리는 작아집니다.

adb shell input motionevent DOWN 500 1000
adb shell input motionevent MOVE 500 990
adb shell input motionevent MOVE 500 980
adb shell input motionevent MOVE 500 970
adb shell input motionevent MOVE 500 960
adb shell input motionevent MOVE 500 950
adb shell input motionevent MOVE 500 940
adb shell input motionevent MOVE 500 930
adb shell input motionevent MOVE 500 920
adb shell input motionevent MOVE 500 910
adb shell input motionevent MOVE 500 900
adb shell input motionevent UP 500 900

这样屏幕上就会出现明显的滑动了,这里建议使用 for 来循环执行一个连续的移动。

当然上面的一组代码可以直接使用 adb shell input swipe x1 y1 x2 y2 来执行,更加方便。

getevent / sendevent command

getevent

通过 adb shell sendevent 也可以完成模拟 KeyEvent 和 MotionEvent 操作。但在模拟操作前,先通过监听设备的输入事件来分析下事件内容,终端输入:

➜  ~ adb shell getevent
add device 1: /dev/input/event6
  name:     "sdm660-snd-card-mtp Button Jack" # 高通 660 平台上的按钮
add device 2: /dev/input/event5
  name:     "sdm660-snd-card-mtp Headset Jack" # 高通 660 平台上的耳机接口
add device 3: /dev/input/event1
  name:     "touchpanel" # 触控面板
add device 4: /dev/input/event4
  name:     "gpio-keys" # linux内核中的驱动, 这里定义了输入音量加减键的事件
add device 5: /dev/input/event2
  name:     "touchpanel_kpd" # 虚拟按键
add device 6: /dev/input/event0
  name:     "qpnp_pon" # 高通平台按键驱动 (电源键)
add device 7: /dev/input/event3
  name:     "STM VL53L0 proximity sensor" # 距离传感器
could not get driver version for /dev/input/mice, Not a typewriter

输入 adb shell getevent 后,会打印出几个设备信息,此时如果你操作手机,就会在终端中不断输出输入事件。例如这里按了一下电源键:

/dev/input/event0: 0001 0074 00000001
/dev/input/event0: 0000 0000 00000000
/dev/input/event0: 0001 0074 00000000
/dev/input/event0: 0000 0000 00000000

按音量键:

/dev/input/event4: 0001 0072 00000001
/dev/input/event4: 0000 0000 00000000
/dev/input/event4: 0001 0072 00000000
/dev/input/event4: 0000 0000 00000000

触摸屏幕:

/dev/input/event1: 0003 0039 00003b0e
/dev/input/event1: 0001 014a 00000001
/dev/input/event1: 0003 0032 00000007
/dev/input/event1: 0003 003a 0000000a
/dev/input/event1: 0003 0035 00000071
/dev/input/event1: 0003 0036 000000d2
/dev/input/event1: 0000 0000 00000000
/dev/input/event1: 0003 0039 ffffffff
/dev/input/event1: 0001 014a 00000000
/dev/input/event1: 0000 0000 00000000

通过 -l 参数以字符串的形式输出内容:

➜  ~ adb shell getevent -l
...
# 按下音量 - 键
/dev/input/event4: EV_KEY       KEY_VOLUMEDOWN       DOWN
/dev/input/event4: EV_SYN       SYN_REPORT           00000000
/dev/input/event4: EV_KEY       KEY_VOLUMEDOWN       UP
/dev/input/event4: EV_SYN       SYN_REPORT           00000000
# 点击屏幕
/dev/input/event1: EV_ABS       ABS_MT_TRACKING_ID   00003b19
/dev/input/event1: EV_KEY       BTN_TOUCH            DOWN
/dev/input/event1: EV_ABS       ABS_MT_WIDTH_MAJOR   00000009
/dev/input/event1: EV_ABS       ABS_MT_PRESSURE      0000000a
/dev/input/event1: EV_ABS       ABS_MT_POSITION_X    00000219
/dev/input/event1: EV_ABS       ABS_MT_POSITION_Y    0000059b
/dev/input/event1: EV_SYN       SYN_REPORT           00000000
/dev/input/event1: EV_ABS       ABS_MT_PRESSURE      00000008
/dev/input/event1: EV_SYN       SYN_REPORT           00000000
/dev/input/event1: EV_ABS       ABS_MT_PRESSURE      00000005
/dev/input/event1: EV_SYN       SYN_REPORT           00000000
/dev/input/event1: EV_ABS       ABS_MT_TRACKING_ID   ffffffff
/dev/input/event1: EV_KEY       BTN_TOUCH            UP
/dev/input/event1: EV_SYN       SYN_REPORT           00000000

/dev/input/event4: 0001 0072 00000001 为例,说明一下事件的格式和含义:

日志组成部分 /dev/input/event4 0001 0072 00000001
含义 代表输入设备 事件类型 事件唯一 ID,例如 KEY_VOLUMEDOWN ACTION 类型或其他参数

getevent 命令的其他参数和用法

➜  ~ adb shell getevent --help
getevent: invalid option --
Usage: getevent [-t] [-n] [-s switchmask] [-S] [-v [mask]] [-d] [-p] [-i] [-l] [-q] [-c count] [-r] [device]
    -t: 展示时间戳
    -n: don't print newlines
    -s: print switch states for given bits
    -S: print all switch states
    -v: verbosity mask (errs=1, dev=2, name=4, info=8, vers=16, pos. events=32, props=64)
    -d: show HID descriptor, if available
    -p: show possible events (errs, dev, name, pos. events)
    -i: show all device info and possible events
    -l: label event types and names in plain text
    -q: quiet (clear verbosity mask)
    -c: print given number of events then exit
    -r: print rate events are received

sendevent

在了解了 getevent 抓取到的事件内容后,我们可以模仿事件日志来输入,通过 adb shell sendevent 命令来完成:

# 按下 Power 键
adb shell sendevent /dev/input/event0 1 116 1
adb shell sendevent /dev/input/event0 0 0 0

adb shell sendevent /dev/input/event0 1 116 0
adb shell sendevent /dev/input/event0 0 0 0

通过 sendevent 我们可以模拟自定义时间的长按:

adb shell sendevent /dev/input/event0 1 116 1
adb shell sendevent /dev/input/event0 0 0 0
# 长按 3s
sleep 3 
adb shell sendevent /dev/input/event0 1 116 0
adb shell sendevent /dev/input/event0 0 0 0

sendevent 的事件格式和 getevent 接收到的格式相同。

рекомендация

отjuejin.im/post/7116442991610298381