本文講的是通過使用代碼,可以控制手機的屏幕和物理按鍵,也就是說不只是在某一個APP里去操作,而是整個手機系統。
getevent/sendevent
getevent&sendevent 是Android系統下的一個工具,可以模擬多種按鍵和觸屏操作,產生的是raw event,raw event經過event hub處理產生最終的gesture事件。getevent用于獲取當前系統input設備的一些參數和實時事件的數據;sendevent用于發送input事件,這倆命令的作用就是相當于解放了手,可以通過命令直接調用Linux底層來控制手機,工具的源碼位于Android SDK的system/core/toolbox下(sendevent.c getevent.c)。
getevent
用法說明:
- #?getevent?-h??
- Usage:?getevent?[-t]?[-n]?[-s?switchmask]?[-S]?[-v?[mask]]?[-p]?[-q]?[-c?count]?[-r]?[device]??
- ????-t:?show?time?stamps??
- ????-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)??
- ????-p:?show?possible?events?(errs,?dev,?name,?pos.?events)??
- ????-q:?quiet?(clear?verbosity?mask)??
- ????-c:?print?given?number?of?events?then?exit??
- ????-r:?print?rate?events?are?received??
其中?[-t]?參數顯示事件的時間戳,[-n]?取消事件顯示時的換行符,[-s switchmask]?得到指定位的開關狀態,[-S]?得到所有開關的狀態,[-v [mask]]?根據mask的值顯示相關信息,后面詳細介紹mask的使用方法,[-p]?顯示每個設備支持的事件類型和編碼,[-q]?只顯示事件數據,[-c count]?只顯示count次事件的數據,[-r]?顯示事件接收頻率。
- shell@android:/?$?getevent?-p??
- getevent?-p??
- add?device?1:?/dev/input/event7??
- ??name:?????"gpio-keys"??
- ??events:??
- ????KEY?(0001):?0066??
- ??input?props:??
- ????<none>??
- add?device?2:?/dev/input/event2??
- ??name:?????"alps"??
- ??events:??
- ????ABS?(0003):?0000??:?value?12,?min?-4096,?max?4096,?fuzz?0,?flat?0,?resolution?0??
- ????????????????0001??:?value?-4,?min?-4096,?max?4096,?fuzz?0,?flat?0,?resolution?0??
- ????????????????0002??:?value?-252,?min?-4096,?max?4096,?fuzz?0,?flat?0,?resolution?0??
- ????????????????000a??:?value?0,?min?-4096,?max?4096,?fuzz?0,?flat?0,?resolution?0??
- ????????????????0010??:?value?0,?min?-4096,?max?4096,?fuzz?0,?flat?0,?resolution?0??
- ????????????????0011??:?value?0,?min?-4096,?max?4096,?fuzz?0,?flat?0,?resolution?0??
- ??input?props:??
- ????<none>??
- add?device?3:?/dev/input/event6??
- ??name:?????"7k_handset"??
- ??events:??
- ????KEY?(0001):?006b??0072??0073??0074??00e2??
- ??input?props:??
- ????<none>??
- add?device?4:?/dev/input/event5??
- ??name:?????"proximity_sensor"??
- ??events:??
- ????ABS?(0003):?0019??:?value?1,?min?0,?max?1,?fuzz?0,?flat?0,?resolution?0??
- ??input?props:??
- ????<none>??
- add?device?5:?/dev/input/event4??
- ??name:?????"accelerometer_sensor"??
- ??events:??
- ??input?props:??
- ????<none>??
- add?device?6:?/dev/input/event3??
- ??name:?????"magnetic_sensor"??
- ??events:??
- ??input?props:??
- ????<none>??
- add?device?7:?/dev/input/event1??
- ??name:?????"7x27a_kp"??
- ??events:??
- ????KEY?(0001):?0072??0073??
- ??input?props:??
- ????<none>??
- add?device?8:?/dev/input/event0??
- ??name:?????"sec_touchscreen"??
- ??events:??
- ????KEY?(0001):?0066??008b??009e??00d9??
- ????ABS?(0003):?002f??:?value?0,?min?0,?max?4,?fuzz?0,?flat?0,?resolution?0??
- ????????????????0030??:?value?0,?min?0,?max?255,?fuzz?0,?flat?0,?resolution?0??
- ????????????????0032??:?value?0,?min?0,?max?100,?fuzz?0,?flat?0,?resolution?0??
- ????????????????0035??:?value?0,?min?0,?max?480,?fuzz?0,?flat?0,?resolution?0??
- ????????????????0036??:?value?0,?min?0,?max?800,?fuzz?0,?flat?0,?resolution?0??
- ????????????????0039??:?value?0,?min?0,?max?4,?fuzz?0,?flat?0,?resolution?0??
- ????LED?(0011):?0008??
- ??input?props:??
- ????INPUT_PROP_DIRECT??
可以看到 [-p] 參數顯示出來當前系統存在的所有input設備,并且把每個設備支持的事件類型以及編碼都列舉了出來。
每一個device相當于手機所支持的input設備,每個device里面的events下:KEY(0001) 、ABS(0003)、SYN(0000)等表示該設備所支持的事件類型:EV_SYN?[0000] (同步事件),EV_KEY?[0001] (按鍵事件),EV_ABS?[0003] (絕對值事件)
舉例event0中的KEY類型:
- KEY?(0001):?0066??008b??009e??00d9????
表示sec_touchscreen支持的按鍵編碼有:KEY_HOME?[0066] (HOME鍵),KEY_MENU?[008b] (MENU鍵)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??KEY_BACK?[009e] (BACK鍵),KEY_SEARCH?[00d9] (SEARCH鍵)
舉例event0中的ABS類型:
- ABS?(0003):?002f??:?value?0,?min?0,?max?4,?fuzz?0,?flat?0,?resolution?0??
- ????????????0030??:?value?0,?min?0,?max?255,?fuzz?0,?flat?0,?resolution?0??
- ????????????0035??:?value?0,?min?0,?max?480,?fuzz?0,?flat?0,?resolution?0??
- ????????????0036??:?value?0,?min?0,?max?800,?fuzz?0,?flat?0,?resolution?0??
表示sec_touchscreen支持的絕對值編碼有:ABS_MT_TOUCH_MAJOR?[0030] (接觸面長軸值) {有效值范圍[0, 255]}
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??? ???ABS_MT_POSITION_X?[0035] (x軸坐標) {有效值范圍[0, 480]}
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ABS_MT_POSITION_Y?[0036] (y軸坐標) {有效值范圍[0, 800]}
實例:
連接真機,windows打開cmd命令:adb shell:

命令行直接:
- 127|shell@android:/?$?getevent??
cmd便會不斷的輸出log日志,等待輸入設備,我們觸摸屏幕或是手機物理按鍵,便會看到這里的變化,可以看到每一個事件所對應的type、code、value,同時也可知曉device所對應的event:

傳送門,通過getevent獲取點擊屏幕的位置坐標,你可以更好的理解getevent的工作流程:
http://blog.csdn.net/liu_zhen_wei/article/details/12559277
sendevent 用法說明:
- #?sendevent???
- use:?sendevent?device?type?code?value??
可以看到sendevent需要4個參數即:device,type,code,value。這些值可以由input子系統定義,也可以從getevent里面獲取。type其實就是和getevent中的支持事件類型所對應的,type, code, value的定義可參看kernel/include/linux/input.h
需要注意的是在getevent中code顯示的是十六進制,而sendevent時需要用十進制
我就copy一個EV_ABS類型所對應的code:
- ?
- ?
- ??
- ??
- #define?ABS_X???????????0x00??
- #define?ABS_Y???????????0x01??
- #define?ABS_Z???????????0x02??
- #define?ABS_RX??????????0x03??
- #define?ABS_RY??????????0x04??
- #define?ABS_RZ??????????0x05??
- #define?ABS_THROTTLE????????0x06??
- #define?ABS_RUDDER??????0x07??
- #define?ABS_WHEEL???????0x08??
- #define?ABS_GAS?????????0x09??
- #define?ABS_BRAKE???????0x0a??
- #define?ABS_HAT0X???????0x10??
- #define?ABS_HAT0Y???????0x11??
- #define?ABS_HAT1X???????0x12??
- #define?ABS_HAT1Y???????0x13??
- #define?ABS_HAT2X???????0x14??
- #define?ABS_HAT2Y???????0x15??
- #define?ABS_HAT3X???????0x16??
- #define?ABS_HAT3Y???????0x17??
- #define?ABS_PRESSURE????????0x18??
- #define?ABS_DISTANCE????????0x19??
- #define?ABS_TILT_X??????0x1a??
- #define?ABS_TILT_Y??????0x1b??
- #define?ABS_TOOL_WIDTH??????0x1c??
- #define?ABS_VOLUME??????0x20??
- #define?ABS_MISC????????0x28??
- ??
- #define?ABS_MT_TOUCH_MAJOR??0x30??????
- #define?ABS_MT_TOUCH_MINOR??0x31??????
- #define?ABS_MT_WIDTH_MAJOR??0x32??????
- #define?ABS_MT_WIDTH_MINOR??0x33??????
- #define?ABS_MT_ORIENTATION??0x34??????
- #define?ABS_MT_POSITION_X???0x35??????
- #define?ABS_MT_POSITION_Y???0x36??????
- #define?ABS_MT_TOOL_TYPE????0x37??????
- #define?ABS_MT_BLOB_ID??????0x38??????
- #define?ABS_MT_TRACKING_ID??0x39??????
- #define?ABS_MT_PRESSURE?????0x3a??????
- ??
- #define?ABS_MAX?????????0x3f??
- #define?ABS_CNT?????????(ABS_MAX+1)??
源碼中定義的0x35,0x36就對應我在上文說getevent所舉sec_touchscreen支持的絕對值編碼。
實例:
比如我們要模擬一次?BACK?事件,根據上面getevent中sec_touchscreen支持的信息可知BACK的編碼為 0x9e 轉換為十進制后即158,那我們輸入如下命令即可模擬一次BACK鍵的按下和彈起:
- #?sendevent?/dev/input/event0?1?158?1??
- #?sendevent?/dev/input/event0?1?158?0??
device需要是支持該按鍵的設備這里是sec_touchscreen;type為1表示是按鍵事件;value為1表示按下,為0表示彈起,一次按鍵事件由按下和彈起兩個操作組成。

----------------------------------------------------------------------------------------------------------------
附,這是網絡文章說的在某坐標點上touch,我試驗沒效果,大家可以試試:
如在屏幕的x坐標為40,y坐標為210的點上touch一下(六組命令必須配合使用,缺一不可)
adb shell sendevent /dev/input/event0 3 0 40
adb shell sendevent /dev/input/event0 3 1 210
adb shell sendevent /dev/input/event0 1 330 1 //touch
adb shell sendevent /dev/input/event0 0 0 0?????? //it must have
adb shell sendevent /dev/input/event0 1 330 0 //untouch
adb shell sendevent /dev/input/event0 0 0 0 //it must have
----------------------------------------------------------------------------------------------------------------
input keyevent
發送鍵盤事件
用法說明:
adb shell input keyevent “value”
usage: input ...
? ? ? ?input text <string>
? ? ? ?input keyevent <key code number or name>
? ? ? ?input tap <x> <y>
? ? ? ?input swipe <x1> <y1> <x2> <y2>
如上,input后可以跟很多參數, text相當于輸入內容,keyevent相當于手機物理或是屏幕按鍵,tap相當于touch事件,swipe相當于滑動~~是不是很贊?
先列舉 input keyevent 幾個比較常用的code值:
input keyevent 3??? // Home
input keyevent 4??? // Back
input keyevent 19? //Up
input keyevent 20? //Down
input keyevent 21? //Left
input keyevent 22? //Right
input keyevent 23? //Select/Ok
input keyevent 24? //Volume+
input keyevent 25? // Volume-
input keyevent 82? // Menu 菜單
我們來試驗一下:
- shell@android:/?$?input?keyevent?3??
看一下手機是不是真的返回到了主界面?
再來個輸入:
- shell@android:/?$?input?text?"helloworld!"??
- input?text?"helloworld!"??
再來個tap:
- shell@android:/?$?input?tap?168?252??
- input?tap?168?252??

最后試一下 swipe:
- shell@android:/?$?input?swipe?100?250?200?280??
- input?swipe?100?250?200?280??
- shell@android:/?$?input?swipe?100?250?220?320??
- input?swipe?100?250?220?320??
- shell@android:/?$?input?swipe?100?250?280?400??
- input?swipe?100?250?280?400??
- shell@android:/?$?input?swipe?100?250?300?480??
- input?swipe?100?250?300?480??
- shell@android:/?$?input?swipe?100?250?350?550??
- input?swipe?100?250?350?550??
- shell@android:/?$?input?swipe?100?250?400?650??
- input?swipe?100?250?400?650??
- shell@android:/?$?input?swipe?100?250?480?600??
- input?swipe?100?250?480?600??
效果圖:

我們在adb shell下試驗了各種命令,可是代碼里該怎么做呢?看下面
- ?
- ?
- ?
- ?
- ??
- private?void?execShellCmd(String?cmd)?{??
- ??
- ????try?{??
- ??????????
- ????????Process?process?=?Runtime.getRuntime().exec("su");??
- ??????????
- ????????OutputStream?outputStream?=?process.getOutputStream();??
- ????????DataOutputStream?dataOutputStream?=?new?DataOutputStream(??
- ????????????????outputStream);??
- ????????dataOutputStream.writeBytes(cmd);??
- ????????dataOutputStream.flush();??
- ????????dataOutputStream.close();??
- ????????outputStream.close();??
- ????}?catch?(Throwable?t)?{??
- ????????t.printStackTrace();??
- ????}??
- }??
在想要執行的地方:
- execShellCmd("getevent?-p");??
- execShellCmd("sendevent?/dev/input/event0?1?158?1");??
- execShellCmd("sendevent?/dev/input/event0?1?158?0");??
- execShellCmd("input?keyevent?3");??
- execShellCmd("input?text??'helloworld!'?");??
- execShellCmd("input?tap?168?252");??
- execShellCmd("input?swipe?100?250?200?280");??
至此結束,是不是感覺自己也能做出按鍵精靈了~~~
附:input keyevent所對應全部key值:
KeyCode ? ? ? ? ? ? Keyevent Value
KEYCODE_MENU 1
KEYCODE_SOFT_RIGHT 2
KEYCODE_HOME 3
KEYCODE_BACK 4
KEYCODE_CALL 5
KEYCODE_ENDCALL 6
KEYCODE_0 7
KEYCODE_1 8
KEYCODE_2 9
KEYCODE_3 10
KEYCODE_4 11
KEYCODE_5 12
KEYCODE_6 13
KEYCODE_7 14
KEYCODE_8 15
KEYCODE_9 16
KEYCODE_STAR 17
KEYCODE_POUND 18
KEYCODE_DPAD_UP 19
KEYCODE_DPAD_DOWN 20
KEYCODE_DPAD_LEFT 21
KEYCODE_DPAD_RIGHT 22
KEYCODE_DPAD_CENTER 23
KEYCODE_VOLUME_UP 24
KEYCODE_VOLUME_DOWN 25
KEYCODE_POWER 26
KEYCODE_CAMERA 27
KEYCODE_CLEAR 28
KEYCODE_A 29
KEYCODE_B 30
KEYCODE_C 31
KEYCODE_D 32
KEYCODE_E 33
KEYCODE_F 34
KEYCODE_G 35
KEYCODE_H 36
KEYCODE_I 37
KEYCODE_J 38
KEYCODE_K 39
KEYCODE_L 40
KEYCODE_M 41
KEYCODE_N 42
KEYCODE_O 43
KEYCODE_P 44
KEYCODE_Q 45
KEYCODE_R 46
KEYCODE_S 47
KEYCODE_T 48
KEYCODE_U 49
KEYCODE_V 50
KEYCODE_W 51
KEYCODE_X 52
KEYCODE_Y 53
KEYCODE_Z 54
KEYCODE_COMMA 55
KEYCODE_PERIOD 56
KEYCODE_ALT_LEFT 57
KEYCODE_ALT_RIGHT 58
KEYCODE_SHIFT_LEFT 59
KEYCODE_SHIFT_RIGHT 60
KEYCODE_TAB 61
KEYCODE_SPACE 62
KEYCODE_SYM 63
KEYCODE_EXPLORER 64
KEYCODE_ENVELOPE 65
KEYCODE_ENTER 66
KEYCODE_DEL 67
KEYCODE_GRAVE 68
KEYCODE_MINUS 69
KEYCODE_EQUALS 70
KEYCODE_LEFT_BRACKET 71
KEYCODE_RIGHT_BRACKET 72
KEYCODE_BACKSLASH 73
KEYCODE_SEMICOLON 74
KEYCODE_APOSTROPHE 75
KEYCODE_SLASH 76
KEYCODE_AT 77
KEYCODE_NUM 78
KEYCODE_HEADSETHOOK 79
KEYCODE_FOCUS 80
KEYCODE_PLUS 81
KEYCODE_MENU 82
KEYCODE_NOTIFICATION 83
KEYCODE_SEARCH 84
TAG_LAST_KEYCODE 85