您的位置:首页 > 移动开发 > Android开发

Android 向系统发送多点触摸事件总结

2012-03-13 12:02 393 查看
最近公司项目需求有个比较头疼的东西就是想系统发送多点触摸事件,我是问东问西又是Google有事百度的最后还是研究出来了,不废话了下面大概的说一下:

首先官方提供的SDK中已经为我们准备了这样

的MotionEvent事件,但是因为它的参数众多第一开始被我忽略了:

以上4.0处理多点的事件.



以上2.3处理多点的事件,可以看出来google提示我们已经过时了建议使用4.0的那个.这两个方法最大的不同点就是4.0中多了PointerProperties[]参数,它是替换了2.3中int[] pointerIds这个参数,具体的请参考sdk中 MotionEvent.PointerProperties
这个类.

这里我主要介绍一下2.3的事件下发:

第一个和第二个参数它们就是一个时间戳: 用 SystemClock.uptimeMillis() 获得即可.

第三个参数(int action):  这个参数是比较重要的,因为它对应这具体你发送到系统的是什么事件,下面介绍一下事件:

       普通的单点的事件无非就是 DOWN/UP/MOVE 三种,它们在SDK中都是常量可以通过 MotionEvent.ACTION_DOWN / ACTION_UP / ACTION_MOVE获取,

       但是多点的就有区别了,多点的在SDK中并没有指定对应的常量所以需要我们进行测试,最好的方法就是自己弄个工程实现onTouch方法,并且 获    取MotionEvent.ACTION_POINTER_DOWN这个事件它对应多个手指,从中调用getAction方法去找事件.

所以经过我的测试: 多点情况下 第一个手指按下action 为 0 第二个手指按下 action 为 261  第三个按下action为 517 等等.....所以我们组织MotionEvent事件的时候       需要注意这一点,然后就是抬起的事件,抬起事件是比较特殊的系统会根据抬起手指顺序的不同产生不同的action,我这里只是书按照最后按下的最先抬起介绍,如第三 
    个手指抬起 action为: 518 第二个抬起 action 为: 262  第一个抬起 action 为: 1.  为什么会出现这种现象可以参考  http://poolo.iteye.com/blog/1170010 的文章.

第四个参数(int pointerCount) : 这个参数也是比较重要的,它代表的是但前事件是哪一个手指,例如: 当前发送的事件是第一个手指那么 该参数就是 1 第二个就是2 第三个就是3 ....

第五个参数(int[] pointerIds): 这个参数是手指ID的数组,第一个手指的id为0 第二个为1 以此类推,所以当发送的事件是一个手指的时候这个参数需要是 new int[]{0} , 当有两个的时     候就是 new int[]{0,1} 三个的时候 new int[]{0,1,2} ....

第六个参数(PointerCoords[] pointerCoords) : 这个参数是描述某一个手指信息的一个数组,首先需要构造MotionEvent.PointerCoords类,它是描述这个手指的 x y 坐标,手指的按 压屏幕的压力,按压屏幕的范围等信息,当然我们如果自己构建的话x
y 坐标是最重要的数据,其他的可以忽略.

主要的就是这六个参数,剩下的几乎都是系统一些默认数据,我们可以通过代码去动态的取这些数据进行观察,它们一般都跟设备的不同有所不同,我这里全部赋值为 0 .

以上的参数确定了我们就可以自己组织一个MotionEvent然后用Instrumentation对象下发了.

下面是一段下发的代码:

private class MyTouchThread implements Runnable {
//第一个手指按下 action: 1 第二个按下 action: 261 第二个手指抬起 action: 262 第一个抬起 action : 1
@Override
public void run() {
while (true) {
String packageName = activityManager.getRunningTasks(1).get(0).topActivity.getPackageName();
PointerCoords[] coords = new PointerCoords[2];
PointerCoords pointerCoords = new PointerCoords();
pointerCoords.x = 357;
pointerCoords.y = 489;
coords[0] = pointerCoords;
//第一个手指按下MotionEvent
MotionEvent event = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN, 1, new int[]{0}, coords, 0, 0, 0, 0, 0, 0, 0);
//MotionEvent event = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(),MotionEvent.ACTION_DOWN,350, 450, 0);
if (getRunningServiceInfo(mContext, packageName) == getRunningServiceInfo(mContext, "com.andlisoft.motionEvent")) {
inst.sendPointerSync(event);
pointerCoords.x = 387;
pointerCoords.y = 589;
coords[1] = pointerCoords;
//第二个手指按下MotionEvent
event = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), 261, 2, new int[]{0,1}, coords, 0, 0, 0, 0, 0, 0, 0);
inst.sendPointerSync(event);

for(int x = 0; x < 10; x ++){
pointerCoords.x = 487 + x;
pointerCoords.y = 689 + x;
coords[1] = pointerCoords;
//第二个手指发送 10 次 Move事件
event = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_MOVE, 2, new int[]{0,1}, coords, 0, 0, 0, 0, 0, 0, 0);
inst.sendPointerSync(event);
}
//第二个手指抬起MotionEvent
event = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), 262, 2, new int[]{0,1}, coords, 0, 0, 0, 0, 0, 0, 0);
inst.sendPointerSync(event);
//第一个手指抬起MotionEvent
event = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, 1, new int[]{0}, coords, 0, 0, 0, 0, 0, 0, 0);
inst.sendPointerSync(event);
}
}
}
}


最后我会把我自己写的工程上传,请大家参考.  第一次在csdn上写东西,如有不满意的地方请提意见我会总结改正.谢谢大家...

源码地址  http://download.csdn.net/detail/liyi_cs_dn/4136290
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息