您的位置:首页 > 移动开发 > Android开发

Android通过代码模拟物理、屏幕点击事件

2018-01-12 15:44 579 查看
本文讲的是通过使用代码,可以控制手机的屏幕和物理按键,也就是说不只是在某一个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

用法说明:

[plain] view
plain copy

# 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] 显示事件接收频率。

[java] view
plain copy

shell@android:/ $ getevent -p

[java] view
plain copy

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类型:

[java] view
plain copy

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类型:

[java] view
plain copy

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:



命令行直接:

[java] view
plain copy

127|shell@android:/ $ getevent

cmd便会不断的输出log日志,等待输入设备,我们触摸屏幕或是手机物理按键,便会看到这里的变化,可以看到每一个事件所对应的type、code、value,同时也可知晓device所对应的event:



传送门,通过getevent获取点击屏幕的位置坐标,你可以更好的理解getevent的工作流程:

http://blog.csdn.net/liu_zhen_wei/article/details/12559277

sendevent

用法说明:

[java] view
plain copy

# 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:

[java] view
plain copy

/*

* 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键的按下和弹起:

[java] view
plain copy

# 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 菜单

我们来试验一下:

[java] view
plain copy

shell@android:/ $ input keyevent 3

看一下手机是不是真的返回到了主界面?

再来个输入:

[java] view
plain copy

shell@android:/ $ input text "helloworld!"

input text "helloworld!"

再来个tap:

[java] view
plain copy

shell@android:/ $ input tap 168 252

input tap 168 252



最后试一下 swipe:

[java] view
plain copy

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下试验了各种命令,可是代码里该怎么做呢?看下面

[java] view
plain copy

/**

* 执行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();

}

}

在想要执行的地方:

[java] view
plain copy

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: