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'