android 模拟发送多点触摸事件

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'

 

你可能感兴趣的:(motionevent,InputManager)