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

一、应用中模拟物理和屏幕点击事件

例如,模拟对某个view的点击事件

private void simulateClick(View view, float x, float y) {
long downTime = SystemClock.uptimeMillis();
final MotionEvent downEvent = MotionEvent.obtain(downTime, downTime,MotionEvent.ACTION_DOWN, x, y, );
downTime += ;
final MotionEvent upEvent = MotionEvent.obtain(downTime, downTime,MotionEvent.ACTION_UP, x, y, );
view.onTouchEvent(downEvent);
view.onTouchEvent(upEvent);
downEvent.recycle();
upEvent.recycle();
} public void setMouseClick(int x, int y){
MotionEvent evenDownt = MotionEvent.obtain(System.currentTimeMillis(),
System.currentTimeMillis() + , MotionEvent.ACTION_DOWN, x, y, );
dispatchTouchEvent(evenDownt);
MotionEvent eventUp = MotionEvent.obtain(System.currentTimeMillis(),
System.currentTimeMillis() + , MotionEvent.ACTION_UP, x, y, );
dispatchTouchEvent(eventUp);
evenDownt.recycle();
eventUp.recycle();
}

这实现原理就是模拟两个MotionEvent (按下和提起) 然后用一个View 来处理这个Event 。

二、Instrumentation实现模拟键盘鼠标事件

// 可以不用在 Activity 中增加任何处理,各 Activity 都可以响应
Instrumentation inst = new Instrumentation();
inst.sendPointerSync(MotionEvent.obtain(SystemClock.uptimeMillis(),SystemClock.uptimeMillis(),
MotionEvent.ACTION_DOWN, , , ));
inst.sendPointerSync(MotionEvent.obtain(SystemClock.uptimeMillis(),SystemClock.uptimeMillis(),
MotionEvent.ACTION_UP, , , ));

三、系统中模拟物理和屏幕点击事件

1、adb shell 进入手机命令行 
2、getevent -h 用法说明

shell@hwH60:/ $ getevent -h  

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=, dev=, name=, info=, vers=, pos. events=, props=)
-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
-r: print rate events are received

[-t] 参数显示事件的时间戳 
[-n] 取消事件显示时的换行符 
[-s switchmask] 得到指定位的开关状态 
[-S] 得到所有开关的状态 
[-v [mask]] 根据mask的值显示相关信息 
[-p] 显示每个设备支持的事件类型和编码 
[-q] 只显示事件数据 
[-c count] 只显示count次事件的数据 
[-r] 显示事件接收频率

3、getevent -p 显示出来当前系统存在的所有input设备,并且把每个设备支持的事件类型以及编码

shell@hwH60:/ $ getevent -p

add device : /dev/input/event2
name: "hi6421_on"
events:
KEY ():
input props:
<none>
could not get driver version for /dev/input/mouse0, Not a typewriter
add device : /dev/input/event4
name: "huawei,touchscreen"
events:
KEY (): 003b 003c 003d 003e 003f
00bd 00be 00bf 00c0 00c1
014a
ABS (): : value , min , max , fuzz , flat , resolution
: value , min , max , fuzz , flat , resolution
: value , min , max , fuzz , flat , resolution
: value , min , max , fuzz , flat , resolution
: value , min , max , fuzz , flat , resolution
: value , min , max , fuzz , flat , resolution
: value , min , max , fuzz , flat , resolution
003a : value , min , max , fuzz , flat , resolution
input props:
INPUT_PROP_DIRECT
add device : /dev/input/event0
name: "mhl_rcp_dev"
events:
KEY ():
000a 000b 000e 001c 003b 003c 003d
003e 003f 006a 006c
008b 009e 009f 00a1 00a4
00a5 00a7 00a8 00ae 00c8 00c9 00cf 00d0
00d5 00e8 019c
input props:
<none>
could not get driver version for /dev/input/mice, Not a typewriter
add device : /dev/input/event1
name: "hisi_gpio_key.14"
events:
KEY ():
input props:
<none>
add device : /dev/input/event3
name: "hi3630_hi6401_CARD Headset Jack"
events:
KEY (): 00e2
SW ():
input props:
<none>

4、getevent 查看输入设备和查看事件 
打印输出log日志,等待输入设备,我们触摸屏幕或是手机物理按键,便会看到这里的变化

shell@hwH60:/ $ getevent

例如:
/dev/input/event0: 014a
/dev/input/event0: 000000f6
/dev/input/event0: 000002ed
/dev/input/event0: 000000f6
/dev/input/event0: 000002ed
/dev/input/event0:
/dev/input/event0:
/dev/input/event0: 003a
/dev/input/event0:

他们四个参数对应的是device type code value 
device:指的是处理触摸和按键的输入设备。 
type:指的是事件类型,EV_SYN [0000] (同步事件),EV_KEY [0001] (按键事件),EV_ABS [0003] (绝对值事件) 
code 指的是前面type代表的事件中支持的编码。 
value 指的是值。

例如:需要模拟一次点击BACK键,模拟点击的功能通常都是使用 /dev/input/event0 这个输入设备,back键的类型为 0001(按键事件),BACK的编码为 0x9e 转换为十进制后即158

注意的是在getevent中code显示的是十六进制,而sendevent时需要用十进制

那我们输入如下命令即可模拟一次BACK键的按下和弹起:

adb shell sendevent /dev/input/event0
adb shell sendevent /dev/input/event0

5、input keyevent 命令

先列举 input keyevent 几个比较常用的code值:

input keyevent     // Home

input keyevent     // Back

input keyevent   //Up

input keyevent   //Down

input keyevent   //Left

input keyevent   //Right

input keyevent   //Select/Ok

input keyevent   //Volume+

input keyevent   // Volume-

input keyevent   // Menu 菜单

例如: 
点击back键

shell@hwH60:/ $ input keyevent  

input text 命令 
输入框输入内容的。后面参数为 “字符串”,例如输入”helloworld”字符串

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

input tap 命令 
模拟单击事件 后面参数为: x y ,例如点击(168,252)位置

shell@hwH60:/ $ input tap    

input swipe 命令 
此命令为滑动事件。例如:从 30 10 滑动到 30 100

shell@hwH60:/ $ input swipe    

Android代码实现,注意需要root

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");
<uses-permission android:name = "android.permission.INJECT_EVENTS"/>
上一篇:springJDBC 中JdbcTemplate 类方法使用


下一篇:thymeleaf(一)