简介

Android系统提供了getevent与sendevent两个工具供开发者从设备节点中直接读取输入事件或写入输入事件.提供了input用于快捷模拟输入事件

  • getevent:监听输入设备节点的内容,当输入事件被写入到节点中时,getevent会将其读出并打印在屏幕上.由于getevent不会对事件数据做任何加工,因此其输出的内容是由内核提供的最原始的事件.
  • sendevent:输入设备的节点不仅在用户空间可读,而且是可写的,因此可以将将原始事件写入到节点中,从而实现模拟用户输入的功能.sendevent的作用即为发送input事件模拟输入事件.
  • input:是Android系统中的一个特殊的命令,用于模拟遥控器、键盘、鼠标的各种按键操作.使用input模拟事件比sendevent更为方便.

getevent

getevent -h:查看 getevent 帮助信息

Usage: getevent [-t] [-n] [-s switchmask] [-S] [-v [mask]] [-d] [-p] [-i] [-l] [-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, props=64) //根据mask的值显示相关信息,后面详细介绍mask的使用方法
-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 //显示指定行数的event事件信息
-r: print rate events are received // 显示事件接收频率

getevent :输出所有event设备的基本信息和输入上报事件

$ getevent
add device 1: /dev/input/event6
name: “accel”
add device 2: /dev/input/event5
name: “goodix_ts”
add device 3: /dev/input/event0
name: “Power Button”
add device 4: /dev/input/event1
name: “Video Bus”
add device 5: /dev/input/event4
name: “baytrailaudio Intel MID Audio Jack”
add device 6: /dev/input/event2
name: “gpio-lesskey”
add device 7: /dev/input/event3
name: “dollar_cove_power_button”
//输入设备 事件类型 键码类别 具体的数值 转义后
/dev/input/event0: 0001 0066 00000001 -> EV_KEY   KEY_HOME   DOWN
/dev/input/event0: 0000 0000 00000000 -> EV_SYN   SYN_REPORT   00000000
/dev/input/event0: 0001 0066 00000000 -> EV_KEY   KEY_HOME   UP
/dev/input/event0: 0000 0000 00000000 -> EV_SYN   SYN_REPORT  00000000

上报数据格式说明

root@android:/ # getevent
/dev/input/event5: 0005 0002 00000001
device name:事件类型type 键码类别code 具体的数值value
/dev/input/event0: 0001 0066 00000001

  • type : 输入设备类型
  • code: 按键扫描码
  • value: 附加码

type,code, value的定义可参看kernel/include/linux/input.h(rk为kernel/include/dt-bindings/input/rk-input.h),通过input.h中查看转换为文字标签即为

/dev/input/event0: EV_KEY  KEY_HOME  DOWN

其中Event Types

/*
 * Event types
 */

#define EV_SYN			0x00 //同步事件
#define EV_KEY			0x01 //按键事件,如KEY_VOLUMEDOWN
#define EV_REL			0x02 //相对坐标(如:鼠标移动,报告相对最后一次位置的偏移)
#define EV_ABS			0x03//绝对坐标(如:触摸屏或操作杆,报告绝对的坐标位置)
#define EV_MSC			0x04//其它
#define EV_SW			0x05  //开关
#define EV_LED			0x11//按键/设备灯
#define EV_SND			0x12//声音/警报
#define EV_REP			0x14 //Repeat
#define EV_FF			0x15 //力反馈 
#define EV_PWR			0x16 //电源
#define EV_FF_STATUS		0x17 //力反馈状态
#define EV_MAX			0x1f  //事件类型最大个数和提供位掩码支持
#define EV_CNT			(EV_MAX+1)

常用的为EV_KEY,EV_REL,EV_REL,EV_ABS.
EV_KEY,EV_REL,EV_REL分别对应按键事件,相对坐标,绝对坐标
EV_SYN则为同步事件,表示一组完整事件已经完成,需要处理,EV_SYN的code定义事件分发的类型。
具体的定义请查看input.h,这里就不详述了.

需要注意的是使用getevent获取的数值都是16进制的,而使用sendevent发送的值为10进制,要注意区分

getevent [device]:使用getevent获得指定设备汇报的事件

$ getevent /dev/input/event0

0001 0066 00000001
0000 0000 00000000
0001 0066 00000000
0000 0000 00000000

-t:显示时间戳

// 读取 event0 数据红外遥控
$ getevent -t /dev/input/event0
[ 1861.245784] 0001 006c 00000001
[ 1861.245784] 0000 0000 00000000
[ 1861.329944] 0001 006c 00000000
[ 1861.329944] 0000 0000 00000000

-n:不换行打印

//event6为无线鼠标,奇怪的时加-n参数时红外遥控按键无上报信息显示
getevent -n /dev/input/event6
0002 0000 000000010002 0001 ffffffff0000 0000 000000000002 0000 000000010002 0001 ffffffff0000 0000 000000000002 0001 ffffffff0000 0000 000000000002 0000 000000010000 0000 000000000002 0001 ffffffff0000 0000 000000000002 0000 000000010002 0001 000000010000 0000

-v:根据mask的值显示相关信息 (errs=1, dev=2, name=4, info=8, vers=16, pos. events=32, props=64)

//默认显示 dev| name| info| vers = 30;
getevent -v /dev/input/event0 等同 getevent -v30 /dev/input/event0
add device 1: /dev/input/event0
bus: 0019
vendor 0001
product 0001
version 0100
name: “ff420030.pwm”
location: “gpio-keys/remotectl”
id: “”
version: 1.0.1

0001 006c 00000001
0000 0000 00000000
0001 006c 00000000
0000 0000 00000000

//events
getevent -v32 /dev/input/event0
events:
KEY (0001): 0002 0003 0004 0005 0006 0007 0008 0009
000a 000b 000e 0066 0067 0069 006a 006c
0071 0072 0073 0074 008b 008f 0096 009e
00e8 0184
0001 006c 00000001
0000 0000 00000000
0001 006c 00000000
0000 0000 00000000

-p:显示设备支持的事件类型和编码方式

$getevent -p /dev/input/event0
add device 1: /dev/input/event0
name: “ff420030.pwm”
events:
KEY (0001): 0002 0003 0004 0005 0006 0007 0008 0009
000a 000b 000e 0066 0067 0069 006a 006c
0071 0072 0073 0074 008b 008f 0096 009e
00e8 0184
input props:
<none>

-i:显示设备的所有信息和支持的事件,比 -p 显示更多信息

$ getevent -i /dev/input/event0
add device 1: /dev/input/event0
bus: 0019
vendor 0001
product 0001
version 0100
name: “ff420030.pwm”
location: “gpio-keys/remotectl”
id: “”
version: 1.0.1
events:
KEY (0001): 0002 0003 0004 0005 0006 0007 0008 0009
000a 000b 000e 0066 0067 0069 006a 006c
0071 0072 0073 0074 008b 008f 0096 009e
00e8 0184
input props:
<none>

-l 可显示所有事件代码的文字标签,比默认显示更直(注意备注1说明)

getevent -l /dev/input/event0
EV_KEY   KEY_HOME    DOWN
EV_SYN   SYN_REPORT   00000000
EV_KEY   KEY_HOME     UP
EV_SYN  SYN_REPORT   00000000

-c:打印固定行数的事件并退出

$ getevent -c 10 /dev/input/event0
0001 006c 00000001
0000 0000 00000000
0001 006c 00000000
0000 0000 00000000
0001 006c 00000001
0000 0000 00000000
0001 006c 00000000
0000 0000 00000000
0001 006c 00000001
0000 0000 00000000
$:

-r:显示事件上报速率

// 检测鼠标报点速率
$ getevent -r /dev/input/event6
0002 0000 fffffffd
0002 0001 00000002
0000 0000 00000000
0002 0000 fffffffe
0002 0001 00000001
0000 0000 00000000 rate 112

以上命令可以按照需要自由组合使用

//事件戳+标签显示
getevent -lt /dev/input/event0
[ 5215.812229] EV_KEY KEY_DOWN DOWN
[ 5215.812229] EV_SYN SYN_REPORT 00000000
[ 5215.992859] EV_KEY KEY_DOWN UP
[ 5215.992859] EV_SYN SYN_REPORT 00000000

备注1:
-l 可显示所有事件代码的文字标签
为 kernel/include/dt-bindings/input/rk-input.h定义的EV_KEY值标签,而不是当前按键实际映射的按键键值标签

例:修改红外遥控的HOME键为POWER键
ff420030_pwm.kl 中key 102 HOME -> key 102 POWER
重启后测试按键响应的为POWER键
此时102映射的上层按键为KEY_POWER,但是由于rk-input.h中定义的#define KEY_HOME 102 标签为KEY_HOME
所以当用getevent -l时打印的仍然是
/dev/input/event0: EV_KEY KEY_HOME DOWN
/dev/input/event0: EV_SYN SYN_REPORT 00000000
/dev/input/event0: EV_KEY KEY_HOME UP
/dev/input/event0: EV_SYN SYN_REPORT 00000000

sendevent

sendevent -h:查看帮助信息

sendevent -h
use: sendevent device type code value

模拟电源键:

sendevent /dev/input/event0 1 102 1
sendevent /dev/input/event0 0 0 0
sendevent /dev/input/event0 1 102 0
sendevent /dev/input/event0 0 0 0

需要注意的是getevent输出的为16进制,而通过sendevent发送时时使用10进制.

通过sendevent模拟输入,其实就是把getevent的数值模拟发送出去.但是使用sendevent模拟比较复杂,一般不建议使用.模拟事件的话还是建议使用input命令,会方便很多

input

input -h:查看帮助信息

$input -h //不同系统版本提供的input功能不一定相同,我测试是的Android7.1.1
Error: Unknown command: -h
Usage: input [] […]

The sources are:
keyboard //键盘
mouse //鼠标
joystick //操纵杆
touchnavigation //
touchpad //触摸板
trackball //轨迹球
dpad //
stylus //触控笔
gamepad //游戏手柄
touchscreen //触摸屏

The commands and default sources are:
text (Default: touchscreen)
keyevent [–longpress] … (Default: keyboard)
tap (Default: touchscreen)
swipe [duration(ms)] (Default: touchscreen)
press (Default: trackball)
roll (Default: trackball)

模拟按键事件:

input keyevent keycode/keycode_name

keycode为上层的键值和getevent的EV_KEY不同.具体值定义见frameworks/base/core/java/android/view/KeyEvent.java或frameworks/native/include/android/keycodes.h

模拟power键,查表可知AKEYCODE_POWER = 26,

input keyevent 26 或 input keyevent KEYCODE_POWER

模拟点击事件:

input tap 200 200 //点击(200,200)

模拟滑动事件:

input swipe 20 240 400 420 1000 //从坐标(20,240)滑动到(400,420),滑动时长为1000ms

模拟文本输入:

input text 123456