動機解釋
本來直接使用 adb shell -> input 即可模擬 鍵盤事件,觸屏事件keyevent ,text,tap
但是手上的這台目標Android機4.0.3系統的input只支持text和keyevent,不支持tap,無法模擬觸屏點擊事件.
usage: input [text|keyevent]
input text <string>
input keyevent <event_code>
於是開始尋找模擬觸屏的替代解決方案.
最新的Android API.24模擬器的input支持范圍很廣:
Usage: input [<source>] <command> [<arg>...]
The sources are:
keyboard
mouse
joystick
touchnavigation
touchpad
trackball
dpad
stylus
gamepad
touchscreen
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)
press (Default: trackball)
roll (Default: trackball)
參考源碼
- radhoo/android-event-injector: A JNI approach to injecting events (keys and touch) on rooted Android
參考資料
- Event 原語 Android 多點觸摸接口詳解 - arm-linux - 博客園
- Programmatically Injecting Events on Android - Part 1 - PocketMagic
- Programmatically Injecting Events on Android - Part 2 - PocketMagic
- Android 模擬系統事件(三) - banketree - 博客頻道 - CSDN.NET
- Android 模擬系統事件(二) - banketree - 博客頻道 - CSDN.NET
- Android 模擬系統事件(一) - banketree - 博客頻道 - CSDN.NET
- Android sendevent/getevent 用法 - kickxxx的專欄 - 博客頻道 - CSDN.NET
- android高分段進階攻略(4)android模擬點擊 - aimn的開源庫 - 博客頻道 - CSDN.NET
- 記錄小米設備事件獲取 - banketree - 博客頻道 - CSDN.NET
事件回放方式
- 新建一個.sh腳本(換行符必須為UNIX.LF)
- 將捕獲到的指定操作的所有event放入腳本
- 將event里的數值全部轉換為10進制
- 在全部event前都加上
sendevent
命令sendevent /dev/input/event1 1 330 1
- 把腳本導入設備
adb push x.sh /data/local/tmp/x.sh
- 執行腳本
adb shell -> su -> sh /data/local/tmp/x.sh
- 觀察操作是否正確回放.
系統鍵盤,觸摸事件捕獲方式
- Root后的設備
- adb shell -> su -> getevent
- 在手機屏幕點擊某個指定的X,Y坐標位置
-
在命令行窗口可見監聽到很多event,類似以下內容
add device 1: /dev/input/event3
name: “bma222e”
add device 2: /dev/input/event2
name: “headset-keyboard”
add device 3: /dev/input/event1
name: “ft5x0x_ts”
add device 4: /dev/input/event0
name: “sprd-keypad”
/dev/input/event1: 0001 014a 00000001
/dev/input/event1: 0003 0030 000000c8
/dev/input/event1: 0003 0035 00000015
/dev/input/event1: 0003 0036 000002ff
/dev/input/event1: 0003 0032 00000001
/dev/input/event1: 0000 0002 00000000
/dev/input/event1: 0000 0000 00000000
/dev/input/event1: 0003 0030 000000c8
/dev/input/event1: 0003 0035 00000015
/dev/input/event1: 0003 0036 000002ff
/dev/input/event1: 0003 0032 00000001
/dev/input/event1: 0000 0002 00000000
/dev/input/event1: 0000 0000 00000000
/dev/input/event1: 0001 014a 00000000
/dev/input/event1: 0000 0000 00000000event [type] [code] [value]
(不同系統版本的手機監聽到的內容可能不太一樣.單點觸控,和多點觸控設備事件不一樣.)
event0:name包含keypad字符串,鍵盤設備
event1:name包含ts字符串,觸摸屏設備
event2:name包含headset,耳機相關控制設備(猜的) - 通過單變量操作原則,多監聽幾個類似操作的event
- 通過多次回放捕獲到的event然后憑經驗剔除非關鍵event
-
提取”通用event”,”關鍵event“,類似以下內容
/dev/input/event1: 0001 014a 00000001
/dev/input/event1: 0003 0030 000000c8
/dev/input/event1: 0003 0035 000000f0
/dev/input/event1: 0003 0036 00000384
/dev/input/event1: 0003 0032 00000001
/dev/input/event1: 0000 0002 00000000
/dev/input/event1: 0000 0000 00000000
/dev/input/event1: 0001 014a 00000000
/dev/input/event1: 0000 0000 00000000關鍵event紅色部分,分別試驗出來對應的是X,Y坐標地址.可把16進制換算成10進制,得到具體數值.
最小事件集序列嘗試
經過實際真機測試,這個最小序列無法正確觸發.看來還是沒掌握底層原理.
下面是兩點觸摸支持的最小事件集序列:
ABS_MT_TOUCH_MAJOR 0x30
ABS_MT_POSITION_X 0x35
ABS_MT_POSITION_Y 0x36
SYN_MT_REPORT 0x02 //上報第一個點
ABS_MT_TOUCH_MAJOR
ABS_MT_POSITION_X
ABS_MT_POSITION_Y
SYN_MT_REPORT //上報第二個點
SYN_REPORT 0x00 //開始動作