android 模拟发送多点触摸事件

简介: 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'


相关文章
|
3月前
|
Android开发
Android面试高频知识点(1) 图解Android事件分发机制
Android面试高频知识点(1) 图解Android事件分发机制
|
3月前
|
Android开发
Android面试高频知识点(1) 图解 Android 事件分发机制
Android面试高频知识点(1) 图解 Android 事件分发机制
55 1
|
3月前
|
XML 前端开发 Android开发
Android面试高频知识点(1) 图解Android事件分发机制
Android面试高频知识点(1) 图解Android事件分发机制
Android面试高频知识点(1) 图解Android事件分发机制
|
3月前
|
Android开发
Android 事件分发机制详细解读
Android 事件分发机制详细解读
48 5
|
5月前
|
图形学 Android开发
小功能⭐️Unity调用Android常用事件
小功能⭐️Unity调用Android常用事件
|
5月前
|
Android开发
Android面试高频知识点(1) 图解 Android 事件分发机制
在Android开发中,事件分发机制是一块Android比较重要的知识体系,了解并熟悉整套的分发机制有助于更好的分析各种点击滑动失效问题,更好去扩展控件的事件功能和开发自定义控件,同时事件分发机制也是Android面试必问考点之一,如果你能把下面的一些事件分发图当场画出来肯定加分不少。废话不多说,总结一句:事件分发机制很重要。
208 9
|
5月前
|
开发工具 Android开发
Android项目架构设计问题之组件A通知组件B某个事件的发生如何解决
Android项目架构设计问题之组件A通知组件B某个事件的发生如何解决
47 0
|
7月前
|
Android开发
39. 【Android教程】触摸事件分发
39. 【Android教程】触摸事件分发
54 2
|
7月前
|
XML Android开发 数据格式
37. 【Android教程】基于监听的事件处理机制
37. 【Android教程】基于监听的事件处理机制
106 2
|
8月前
|
存储 Java Linux
Android系统获取event事件回调等几种实现和原理分析
Android系统获取event事件回调等几种实现和原理分析
526 0