android的输入事件处理, 大多跟InputReader, InputManager, InputManagerService有关,
对它们的理解,也只是皮毛.
本文也只涉及到Touch事件的DOWN, MOVE, UP;
如何发送或虚拟Touch事件?多点触摸的时候又应该如何处理?
注: 本文中的代码对于第三方应用来说可能不适用!
//用于发送事件
public void postMotionEvent(final InputManager imgr, final MotionEvent event, int delayed){
h.postDelayed(new Runnable(){
public void run(){
event.setSource(InputDevice.SOURCE_TOUCHSCREEN);//留意参数
imgr.injectInputEvent(event, InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);//同样, 留意参数, 如果参数错, 会不成功.
}
}, delayed);
}
/** double point ***********/
//用于模拟两点缩放事件.
/** AnsonCode 2013.4.27 **/
public void postScale(boolean zoomIn, Context cxt){
//计算坐标, 我选取的是屏幕中间的区域.
android.content.res.Resources res = cxt.getResources();
int width = res.getDisplayMetrics().widthPixels;
int height = res.getDisplayMetrics().heightPixels;
long downTime = SystemClock.uptimeMillis();
InputManager imgr = InputManager.getInstance();//APK开发可能访问不到.
int centerx = width /2;
int centery = height /2;
int x1 = centerx - 100, y1 = centery - 100;
int x2 = centerx + 100, y2 = centery + 100;
part 1
PointerCoords[] coords = new PointerCoords[2];//点1坐标.
PointerCoords pointerCoords = new PointerCoords();
pointerCoords.x = x1;
pointerCoords.y = y1;
coords[0] = pointerCoords;
MotionEvent event = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN,
1, new int[]{0}, coords, 0, 0, 0, 0, 0, 0, 0);//创建点1的DOWN事件
postMotionEvent(imgr, event, 0);//点1 DOWN了
pointerCoords = new PointerCoords();//创建点2
pointerCoords.x = x2;
pointerCoords.y = y2;
coords[1] = pointerCoords;
event = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_POINTER_2_DOWN,
2, new int[]{0,1}, coords, 0, 0, 0, 0, 0, 0, 0);//点2 DOWN 事件
postMotionEvent(imgr, event, 10);//点2也 DOWN 了
///part 2
//第2部分主要是 MOVE 事件.
pointerCoords = new PointerCoords();
pointerCoords.x = x1 - (zoomIn ? 1:-1) * 10;
pointerCoords.y = y1 - (zoomIn ? 1:-1) * 10;
coords[0] = pointerCoords;//更新点 1 坐标
event = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_MOVE,
1, new int[]{0}, coords, 0, 0, 0, 0, 0, 0, 0);//MOVE 事件
postMotionEvent(imgr, event, 110);//在DOWN 后, 推迟110ms再MOVE
pointerCoords = new PointerCoords();
pointerCoords.x = x2 + (zoomIn ? 1:-1) * 10;
pointerCoords.y = y2 + (zoomIn ? 1:-1) * 10;
coords[1] = pointerCoords;//同样更新点2坐标
event = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_MOVE,
2, new int[]{0,1}, coords, 0, 0, 0, 0, 0, 0, 0);
postMotionEvent(imgr, event, 110);//发送MOVE.
part 2-2
//重复MOVE, 有可能移得不够远
pointerCoords = new PointerCoords();
pointerCoords.x = x1 - (zoomIn ? 1:-1) * 40;
pointerCoords.y = y1 - (zoomIn ? 1:-1) * 40;
coords[0] = pointerCoords;
event = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_MOVE,
1, new int[]{0}, coords, 0, 0, 0, 0, 0, 0, 0);
postMotionEvent(imgr, event, 150);
pointerCoords = new PointerCoords();
pointerCoords.x = x2 + (zoomIn ? 1:-1) * 40;
pointerCoords.y = y2 + (zoomIn ? 1:-1) * 40;
coords[1] = pointerCoords;
event = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_MOVE,
2, new int[]{0,1}, coords, 0, 0, 0, 0, 0, 0, 0);
postMotionEvent(imgr, event, 150);
part 2-3
pointerCoords = new PointerCoords();
pointerCoords.x = x1 - (zoomIn ? 1:-1) * 100;
pointerCoords.y = y1 - (zoomIn ? 1:-1) * 100;
coords[0] = pointerCoords;
event = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_MOVE,
1, new int[]{0}, coords, 0, 0, 0, 0, 0, 0, 0);
postMotionEvent(imgr, event, 180);
pointerCoords = new PointerCoords();
pointerCoords.x = x2 + (zoomIn ? 1:-1) * 100;
pointerCoords.y = y2 + (zoomIn ? 1:-1) * 100;
coords[1] = pointerCoords;
event = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_MOVE,
2, new int[]{0,1}, coords, 0, 0, 0, 0, 0, 0, 0);
postMotionEvent(imgr, event, 180);
part 3
//有DOWN 必有 UP
//坐标不需要更新了, 直接创建EVENT, 并发送即可.
//第二个手指抬起MotionEvent
event = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_POINTER_2_UP, 2, new int[]{0,1}, coords, 0, 0, 0, 0, 0, 0, 0);
postMotionEvent(imgr, event, 300);
//第一个手指抬起MotionEvent
event = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, 1, new int[]{0}, coords, 0, 0, 0, 0, 0, 0, 0);
postMotionEvent(imgr, event, 300);
}
/** move from one location to another **/
public void postMove(int fx, int fy, int tx, int ty, int delayed){
long downTime = SystemClock.uptimeMillis();
InputManager imgr = InputManager.getInstance();
MotionEvent down = MotionEvent.obtain(downTime,SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN, fx, fy, 0);
postMotionEvent(imgr, down, delayed);
MotionEvent move = MotionEvent.obtain(downTime,SystemClock.uptimeMillis()+20, MotionEvent.ACTION_MOVE, tx, ty, 0);
postMotionEvent(imgr, move, delayed);
MotionEvent up = MotionEvent.obtain(downTime,SystemClock.uptimeMillis()+20, MotionEvent.ACTION_UP, tx, ty, 0);
postMotionEvent(imgr, up, delayed);
}
/** Click in special location **/
//发送点击事件, DOWN -> UP
public void postClick(int x, int y, int delayed){
long downTime = SystemClock.uptimeMillis();
InputManager imgr = InputManager.getInstance();
MotionEvent down = MotionEvent.obtain(downTime,SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN, x, y, 0);
postMotionEvent(imgr, down, delayed);
MotionEvent up = MotionEvent.obtain(downTime,SystemClock.uptimeMillis()+20, MotionEvent.ACTION_UP, x, y, 0);
postMotionEvent(imgr, up, delayed);
}
MotionEvent一般是什么?
一般是TouchEvent, KeyEvent, 这两个是十分常见的.
所以, 上面的代码,也可以用于发送按键值, 如BACK, POWER, 'A'