Android通過代碼模擬物理、屏幕點擊事件,adb 執行各種命令點擊事件;

本文講的是通過使用代碼,可以控制手機的屏幕和物理按鍵,也就是說不只是在某一個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:

 

/*
 * Absolute axes
 */
 
#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    /* Major axis of touching ellipse */
#define ABS_MT_TOUCH_MINOR  0x31    /* Minor axis (omit if circular) */
#define ABS_MT_WIDTH_MAJOR  0x32    /* Major axis of approaching ellipse */
#define ABS_MT_WIDTH_MINOR  0x33    /* Minor axis (omit if circular) */
#define ABS_MT_ORIENTATION  0x34    /* Ellipse orientation */
#define ABS_MT_POSITION_X   0x35    /* Center X ellipse position */
#define ABS_MT_POSITION_Y   0x36    /* Center Y ellipse position */
#define ABS_MT_TOOL_TYPE    0x37    /* Type of touching device */
#define ABS_MT_BLOB_ID      0x38    /* Group a set of packets as a blob */
#define ABS_MT_TRACKING_ID  0x39    /* Unique ID of initiated contact */
#define ABS_MT_PRESSURE     0x3a    /* Pressure on contact area */
 
#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下試驗了各種命令,可是代碼裏該怎麼做呢?看下面

  

 /**
     * 執行shell命令
     * 
     * @param cmd
     */
    private void execShellCmd(String cmd) {
 
        try {
            // 申請獲取root權限,這一步很重要,不然會沒有作用
            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");//home
        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


————————————————

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章