Android多点触摸_第1页
Android多点触摸_第2页
Android多点触摸_第3页
Android多点触摸_第4页
Android多点触摸_第5页
免费预览已结束,剩余4页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第一章摘要在Linux内核支持的基础上,Android在其2.0源码中加入多点触摸功能。由此触摸屏在Android的frameworks被完全分为2种实现途径:单点触摸屏的单点方式,多点触摸屏的单点和多点方式。第二章软件位在Linux的input.h中,多点触摸功能依赖于以下几个主要的软件位:#defineSYN_REPORT0#defineSYN_CONFIG1#defineSYN_MT_REPORT2# defineABS_MT_TOUCH_MAJOR0x30/*Majoraxisoftouchingellipse*/# defineABS_MT_TOUCH_MINOR0x31/*Mino

2、raxis(omitifcircular)*/# defineABS_MT_WIDTH_MAJOR0x32/*Majoraxisofapproachingellipse*/# defineABS_MT_WIDTH_MINOR0x33/*Minoraxis(omitifcircular)*/# defineABS_MT_ORIENTATION0x34/*Ellipseorientation*/# defineABS_MT_POSITION_X0x35/*CenterXellipseposition*/# defineABS_MT_POSITION_Y0x36/*CenterYellipsepos

3、ition*/# defineABS_MT_TOOL_TYPE0x37/*Typeoftouchingdevice*/# defineABS_MT_BLOB_ID0x38/*Groupasetofpacketsasablob*/在Android中对应的软件位定义在RawInputEvent.java中:publicclassRawInputEventpublicstaticfinalintCLASS_TOUCHSCREEN_MT=0x00000010;publicstaticfinalintABS_MT_TOUCH_MAJOR=0x30;publicstaticfinalintABS_MT_T

4、OUCH_MINOR=0x31;publicstaticfinalintABS_MT_WIDTH_MAJOR=0x32;publicstaticfinalintABS_MT_WIDTH_MINOR=0x33;publicstaticfinalintABS_MT_ORIENTATION=0x34;publicstaticfinalintABS_MT_POSITION_X=0x35;publicstaticfinalintABS_MT_POSITION_Y=0x36;publicstaticfinalintABS_MT_TOOL_TYPE=0x37;publicstaticfinalintABS_

5、MT_BLOB_ID=0x38;publicstaticfinalintSYN_REPORT=0;publicstaticfinalintSYN_CONFIG=1;publicstaticfinalintSYN_MT_REPORT=2;在Android在Android中,多点触摸的实现方法在具体的代码实现中和单点是完全区分开的。代码的EventHub.cpp中,单点屏和多点屏由如下代码段来判定:intEventHub:open_device(constchar*deviceName)(if(test_bit(ABS_MT_TOUCH_MAJOR,abs_bitmask)&test_bit(AB

6、S_MT_POSITION_X,abs_bitmask)&test_bit(ABS_MT_POSITION_Y,abs_bitmask)device-classes|=CLASS_TOUCHSCREEN|CLASS_TOUCHSCREEN_MT;/LOGI(Itisamulti-touchscreen!);/single-touch?elseif(test_bit(BTN_TOUCH,key_bitmask)&test_bit(ABS_X,abs_bitmask)&test_bit(ABS_Y,abs_bitmask)device-classes|=CLASS_TOUCHSCREEN;/LOG

7、I(Itisasingle-touchscreen!);我们知道,在触摸屏驱动中,通常在probe函数中会调用input_set_abs_params给设备的input_dev结构体初始化,这些input_dev的参数会在Android的EventHub.cpp中被读取。如上可知,如果我们的触摸屏想被当成多点屏被处理,只需要在驱动中给input_dev额外增加以下几个参数即可:input_set_abs_params(mcs_data.input,ABS_MT_POSITION_X,pdata-abs_x_min,pdata-abs_x_max,0,0);input_set_abs_param

8、s(mcs_data.input,ABS_MT_POSITION_Y,pdata-abs_y_min,pdata-abs_y_max,0,0);input_set_abs_params(mcs_data.input,ABS_MT_TOUCH_MAJOR,0,15,0,0);相当于单点屏的ABX_PRESSUREinput_set_abs_params(mcs_data.input,ABS_MT_WIDTH_MAJOR,0,15,0,0);相当于单点屏的ABS_TOOL_WIDTH为了让我们的驱动代码支持所有的Android版本,无论是多点屏还是单点屏,一般都会保留单点屏的事件,如ABS_TOU

9、CH,ABS_PRESSURE,ABS_X,ABS_Y等。另外,由于在Android2.0前支持多点的frameworks大多是用HAT0X,HAT0Y来实现的,所以一般也会上报这2个事件。第三章同步方式由于多点触摸技术需要采集到多个点,然后再一起处理这些点,所以在软件实现中需要保证每一波点的准确性和完整性。因此,Linux内核提供了input_mt_sync(structinput_dev*input)函数。在每波的每个点上报后需要紧跟一句input_mt_sync(),当这波所有点上报后再使用input_sync()进行同步。例如一波要上报3个点:/*上报点1*/input_mt_sync

10、(input);/*上报点2*/input_mt_sync(input);/*上报点3*/input_mt_sync(input);input_sync(input);注:即使是仅上报一个点的单点事件,也需要一次input_my_sync。文章出处:飞诺网():在Android的KeyInputQueue.java中,系统创建了一个线程,然后把所有的Input事件放入一个队列:publicabstractclassKeyInputQueueThreadmThread=newThread(InputDeviceReader)publicvoidrun()android.os.Process.se

11、tThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_DISPLAY);tryRawInputEventev=newRawInputEvent();while(true)InputDevicedi;/block,doesntreleasethemonitorreadEvent(ev);if(ev.type=RawInputEvent.EV_DEVICE_ADDED)synchronized(mFirst)di=newInputDevice(ev.deviceId);mDevices.put(ev.deviceId,di);confi

12、gChanged=true;)elseif(ev.type=RawInputEvent.EV_DEVICE_REMOVED)synchronized(mFirst)Log.i(TAG,Deviceremoved:id=0x+Integer.toHexString(ev.deviceId);di=mDevices.get(ev.deviceId);if(di!=null)mDevices.delete(ev.deviceId);configChanged=true;elseLog.w(TAG,Baddeviceid:+ev.deviceId);elsedi=getInputDevice(ev.d

13、eviceId);/firstcrackatitsend=preprocessEvent(di,ev);if(ev.type=RawInputEvent.EV_KEY)di.mMetaKeysState=makeMetaState(ev.keycode,ev.value!=0,di.mMetaKeysState);mHaveGlobalMetaState=false;if(di=null)continue;if(configChanged)synchronized(mFirst)addLocked(di,SystemClock.uptimeMillis(),0,RawInputEvent.CL

14、ASS_CONFIGURATION_CHANGED,null);if(!send)continue;synchronized(mFirst)if(type=RawInputEvent.EV_KEY&(classes&RawInputEvent.CLASS_KEYBOARD)!=0&(scancodeRawInputEvent.BTN_LAST)/*键盘按键事件*/elseif(ev.type=RawInputEvent.EV_KEY)/*下面是EV_KEY事件分支,只支持单点的触摸屏有按键事件,*而支持多点的触摸屏没有按键事件,只有绝对坐标事件*/if(ev.scancode=RawInput

15、Event.BTN_TOUCH&(classes&(RawInputEvent.CLASS_TOUCHSCREEN|RawInputEvent.CLASS_TOUCHSCREEN_MT)RawInputEvent.CLASS_TOUCHSCREEN)/*只支持单点的触摸屏的按键事件*/elseif(ev.scancode=RawInputEvent.BTN_MOUSE&(classes&RawInputEvent.CLASS_TRACKBALL)!=0)/*鼠标和轨迹球*/elseif(ev.type=RawInputEvent.EV_ABS&(classes&RawInputEvent.CL

16、ASS_TOUCHSCREEN_MT)!=0)/*下面才是多点触摸屏上报的事件*/if(ev.scancode=RawInputEvent.ABS_MT_TOUCH_MAJOR)di.mAbs.changed=true;di.mAbs.mNextDatadi.mAbs.mAddingPointerOffset+MotionEvent.SAMPLE_PRESSUREev.value;elseif(ev.scancodeRawInputEvent.ABS_MT_POSITION_X)di.mAbs.changed=true;di.mAbs.mNextDatadi.mAbs.mAddingPoint

17、erOffset+MotionEvent.SAMPLE_X=ev.value;elseif(ev.scancodeRawInputEvent.ABS_MT_POSITION_Y)di.mAbs.changed=true;di.mAbs.mNextDatadi.mAbs.mAddingPointerOffset+MotionEvent.SAMPLE_Y=ev.value;elseif(ev.scancode=RawInputEvent.ABS_MT_WIDTH_MAJOR)di.mAbs.changed=true;di.mAbs.mNextDatadi.mAbs.mAddingPointerOf

18、fset+MotionEvent.SAMPLE_SIZE=ev.value;/*上面这段就是多点触摸屏要用到的事件上报部分;* 使用一个数组mNextData来保存,其中di.mAbs.mAddingPointerOffset* 是当前点的偏移量,在每个点中还在MotionEvent中定义了X,Y,PRESSURE* SIZE等偏移量,多点触摸屏的压力值由绝对坐标事件ABS_MT_TOUCH_MAJOR确定。*/elseif(ev.type=RawInputEvent.EV_ABS&(classes&RawInputEvent.CLASS_TOUCHSCREEN)!=0)/*这里是对单点触摸屏

19、上报坐标事件的新的处理方法,同样使用了数组来保存*/if(ev.scancode=RawInputEvent.ABS_X)di.mAbs.changed=true;di.curTouchValsMotionEvent.SAMPLE_X=ev.value;elseif(ev.scancode=RawInputEvent.ABS_Y)di.mAbs.changed=true;di.curTouchValsMotionEvent.SAMPLE_Y=ev.value;elseif(ev.scancode=RawInputEvent.ABS_PRESSURE)di.mAbs.changed=true;d

20、i.curTouchValsMotionEvent.SAMPLE_PRESSURE=ev.value;di.curTouchValsMotionEvent.NUM_SAMPLE_DATA+MotionEvent.SAMPLE_PRESSURE=ev.value;elseif(ev.scancode=RawInputEvent.ABS_TOOL_WIDTH)di.mAbs.changed=true;di.curTouchValsMotionEvent.SAMPLE_SIZE=ev.value;di.curTouchValsMotionEvent.NUM_SAMPLE_DATA+MotionEve

21、nt.SAMPLE_SIZE=ev.value;./*下面是关键的同步处理方法*/if(ev.type=RawInputEvent.EV_SYN&ev.scancode=RawInputEvent.SYN_MT_REPORT&di.mAbs!=null)/*在这里实现了对SYN_MT_REPORT事件的处理,*改变了di.mAbs.mAddingPointerOffset的值,从而将*新增的点的参数保存到下一组偏移量的位置。*/finalInputDevice.MAX_POINTERS)MotionEvent.NUM_SAMPLE_DATA)intnewOffset=(numlastNumPo

22、inters)if(lastNumPointers=0)/上次触屏上没有按键,新值又大,说明有按键按下action=MotionEvent.ACTION_DOWN;mDownTime=curTime;else/有新点按下,分配给新点ID号action=MotionEvent.ACTION_POINTER_DOWN|(upOrDownPointerMotionEvent.ACTION_POINTER_ID_SHIFT);)else/新动作比原来pointer数量少if(numPointers=1)/原来只有1个点按下,所以现在的动作是全部按键upaction=MotionEvent.ACTION_UP;else原来有多点按下,现在是ACTION_POINTER_UP动作,action=MotionEvent.ACTION_POINTER_UP|(upOrDownPointerMotionEvent.ACTION_POINTER_ID_SHIFT);currentMove=null;else前后触屏pointer个数相同,所以是移动动作ACTION_MOVEaction=MotionEv

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论