引用:http://blog.163.com/fenglang_2006/blog/static/13366231820108205274325/

第一章摘要

在Linux内核支持的基础上,Android在其2.0源码中加入多点触摸功能。由此触摸屏在Android的frameworks被完全分为2种实现途径:单点触摸屏的单点方式,多点触摸屏的单点和多点方式。

第二章软件位

在Linux的input.h中,多点触摸功能依赖于以下几个主要的软件位:

………………………..

#define SYN_REPORT0

#define SYN_CONFIG1

#define SYN_MT_REPORT2

………………………...

#define ABS_MT_TOUCH_MAJOR0x30/* Major axis of touching ellipse */

#define ABS_MT_TOUCH_MINOR0x31/* Minor axis (omit if circular) */

#define ABS_MT_WIDTH_MAJOR0x32/* Major axis of approaching ellipse */

#define ABS_MT_WIDTH_MINOR0x33/* Minor axis (omit if circular) */

#define ABS_MT_ORIENTATION0x34/* Ellipse orientation */

#define ABS_MT_POSITION_X0x35/* Center X ellipse position */

#define ABS_MT_POSITION_Y0x36/* Center Y ellipse position */

#define ABS_MT_TOOL_TYPE0x37/* Type of touching device */

#define ABS_MT_BLOB_ID0x38/* Group a set of packets as a blob */

…………………………

在Android中对应的软件位定义在RawInputEvent.java中:

…………………..

public class RawInputEvent {

……………….

public static final int CLASS_TOUCHSCREEN_MT = 0x00000010;

………………..

public static final int ABS_MT_TOUCH_MAJOR = 0x30;

public static final int ABS_MT_TOUCH_MINOR = 0x31;

public static final int ABS_MT_WIDTH_MAJOR = 0x32;

public static final int ABS_MT_WIDTH_MINOR = 0x33;

public static final int ABS_MT_ORIENTATION = 0x34;

public static final int ABS_MT_POSITION_X = 0x35;

public static final int ABS_MT_POSITION_Y = 0x36;

public static final int ABS_MT_TOOL_TYPE = 0x37;

public static final int ABS_MT_BLOB_ID = 0x38;

………………….

public static final int SYN_REPORT = 0;

public static final int SYN_CONFIG = 1;

public static final int SYN_MT_REPORT = 2;

………………..

在Android中,多点触摸的实现方法在具体的代码实现中和单点是完全区分开的。在Android代码的EventHub.cpp中,单点屏和多点屏由如下代码段来判定:

int EventHub::open_device(const char *deviceName)

{

………………………

if (test_bit(ABS_MT_TOUCH_MAJOR, abs_bitmask)

&& test_bit(ABS_MT_POSITION_X, abs_bitmask)

&& test_bit(ABS_MT_POSITION_Y, abs_bitmask)) {

device->classes |= CLASS_TOUCHSCREEN | CLASS_TOUCHSCREEN_MT;

//LOGI("It is a multi-touch screen!");

}

//single-touch?

else if (test_bit(BTN_TOUCH, key_bitmask)

&& test_bit(ABS_X, abs_bitmask)

&& test_bit(ABS_Y, abs_bitmask)) {

device->classes |= CLASS_TOUCHSCREEN;

//LOGI("It is a single-touch screen!");

}

………………..

}

我们知道,在触摸屏驱动中,通常在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_params(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_PRESSURE

input_set_abs_params(mcs_data.input, ABS_MT_WIDTH_MAJOR, 0, 15, 0, 0);

//相当于单点屏的ABS_TOOL_WIDTH

注:

为了让我们的驱动代码支持所有的Android版本,无论是多点屏还是单点屏,一般都会保留单点屏的事件,如ABS_TOUCH, ABS_PRESSURE, ABS_X, ABS_Y等。另外,由于在Android2.0前支持多点的frameworks大多是用HAT0X,HAT0Y来实现的,所以一般也会上报这2个事件。

第三章同步方式

由于多点触摸技术需要采集到多个点,然后再一起处理这些点,所以在软件实现中需要保证每一波点的准确性和完整性。因此,Linux内核提供了input_mt_sync(struct input_dev * input)函数。在每波的每个点上报后需要紧跟一句input_mt_sync(), 当这波所有点上报后再使用input_sync()进行同步。例如一波要上报3个点:

/* 上报点1*/

……………..

input_mt_sync(input);

/* 上报点2*/

……………..

input_mt_sync(input);

/* 上报点3*/

……………..

input_mt_sync(input);

input_sync(input);

注:即使是仅上报一个点的单点事件,也需要一次input_my_sync。

第四章触摸事件数组的处理

上面我们曾说到generateAbsMotion这个方法,它们在InputDevice类的内部类MotionState中实现,该类被定义为InputDevice类的静态成员类(static class),调用它们可以直接使用:

InputDeviceClass.MotionStateClass.generateAbsMotion()。

public class InputDevice {

……………………………

static class MotionState {//下面是这个内部类的几个函数

……………………………….

/* mLastNumPointers 为上一个动作在触屏上按键的个数 */

int mLastNumPointers = 0;

final int[] mLastData = new int[MotionEvent.NUM_SAMPLE_DATA * MAX_POINTERS];

/* mNextNumPointers 为下一个动作在触屏上按键的个数 */

/* 通过对这2个值大小的判断,可以确认新的动作方式 */

int mNextNumPointers = 0;

final int[] mNextData = new int[(MotionEvent.NUM_SAMPLE_DATA * MAX_POINTERS)

+ MotionEvent.NUM_SAMPLE_DATA];

………………………………….

int[] generateAveragedData(int upOrDownPointer, int lastNumPointers,

int nextNumPointers) { //平滑处理

…………………………………….

}

private boolean assignPointer(int nextIndex, boolean allowOverlap) {//指派按键

……………………………………

}

private int updatePointerIdentifiers() {//更新按键ID

………………………………….

}

void removeOldPointer(int index) {

……………………………………

}

MotionEvent generateAbsMotion(InputDevice device, long curTime,

long curTimeNano, Display display, int orientation,

int metaState) {

……………………………………

int upOrDownPointer = updatePointerIdentifiers();

final int numPointers = mLastNumPointers;

………………………………………

/* 对行为的判断 */

if (nextNumPointers != lastNumPointers) { //前后在触屏上点个数不同,说明有手指up或down

if (nextNumPointers > lastNumPointers) {

if (lastNumPointers == 0) { //上次触屏上没有按键,新值又大,说明有按键按下

action = MotionEvent.ACTION_DOWN;

mDownTime = curTime;

} else {//有新点按下,分配给新点ID号

action = MotionEvent.ACTION_POINTER_DOWN

| (upOrDownPointer << MotionEvent.ACTION_POINTER_ID_SHIFT);

}

} else {//新动作比原来pointer数量少

if (numPointers == 1) { //原来只有1个点按下,所以现在的动作是全部按键up

action = MotionEvent.ACTION_UP;

} else { //原来有多点按下,现在是ACTION_POINTER_UP动作,

action = MotionEvent.ACTION_POINTER_UP

| (upOrDownPointer << MotionEvent.ACTION_POINTER_ID_SHIFT);

}

}

currentMove = null;

} else { //前后触屏pointer个数相同,所以是移动动作ACTION_MOVE

action = MotionEvent.ACTION_MOVE;

}

/* 后面则是根据屏幕的height和width以及屏幕方向orientation对这些点进行二次处理 */

……………………………………

}

MotionEvent generateRelMotion(InputDevice device, long curTime,

long curTimeNano, int orientation, int metaState) {

/* 轨迹球等的处理方式 */

…………………………………………..

}

void finish() {      //结束这轮动作

mNextNumPointers = mAddingPointerOffset = 0;

mNextData[MotionEvent.SAMPLE_PRESSURE] = 0;

}

…………………………………….

}

……………………………….

……………………………………

}

第五章接口

我们平时所看到的用2个手指对图片放大缩小、旋转等手势都是由应用程序编写浏览器实现的。这些应用程序大多会使用Android2.0以上的在MotionEvent.java中实现的新的接口。所以,我们还需要给MotionEvent类补充尽量全的接口。这里可以完全参照google新的android代码。

第六章总结

综上,在硬件支持基础上,Android1.6如果要实现多点触摸功能,主要工作可简述为以下几个方面:

1、 驱动中,除了增加多点的事件上报方式,还要完全更改单点的事件上报方式。

2、 Android的Frameworks层需要修改的文件有:EventHub.cpp,RawInputEvent.java,KeyInputQueue.java,InputDevice.java,MotionEvent.java。

3、 编写新的支持多点触摸功能的多媒体浏览器。

4、 为了代码简练,android2.0在轨迹球和单点屏事件方式中也全使用了新的变量名,以方便多点屏事件同样能使用这些变量,所以修改时还需要注意许多细节方面。

android 多点的更多相关文章

  1. Linux与Android 多点触摸协议【转】

    本文转载自:http://blog.csdn.net/xubin341719/article/details/7833277 一.Linux与Android 多点触摸协议 为了使用功能强大的多点触控设 ...

  2. Linux & Android 多点触摸协议

    Linux & Android 多点触摸协议 Android4.0多点触摸入门 1 KERNEL 对于触摸屏的驱动我们简单的划分为两个主要的部分,一个是注册,另一个是上报. 1.1 注册 单点 ...

  3. Android多点触控技术

    1 简介 Android多点触控在本质上需要LCD驱动和程序本身设计上支持,目前市面上HTC.Motorola和Samsung等知名厂商只要使用电容屏触控原理的手机均可以支持多点触控Multitouc ...

  4. [yueqian_scut]Android多点触控技术和应用框架

    Android多点触控技术跟Linux输入子系统紧密相关.本文将从应用的角度说明Android多点触控技术的接口和应用. 一.多点触控场景分析 网络上有关Android多点触控技术的文章多见于两点拉伸 ...

  5. Android 多点触控与简单手势(一)

    现在一般的Android手机都会使用电容触摸屏最少可以支持两点触摸,多的可能是七八个,所以基本上都会支持多点触控, android系统中应用程序可以使用多点触控的事件来完成各种手势和场景需求. And ...

  6. Android多点触控技术实战,自由地对图片进行缩放和移动

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/11100327 在上一篇文章中我带着大家一起实现了Android瀑布流照片墙的效果, ...

  7. Android 多点触控错误处理(java.lang.IllegalArgumentException: pointerIndex out of range)

    最近做View的多点触控时,每次第一次触控事件完美运行,第二次就直接崩了,错误信息如下: 01-03 00:05:44.220 4377-4410/system_process E/AndroidRu ...

  8. Android 多点手势识别详解

    google 提供的API中,有个类,大家都很熟悉,GestureDetector.使用它,我们可以识别用户通常会用的手势.但是,这个类不支持多点触摸(可能 google认为没有人会在几个手指都在屏幕 ...

  9. scaleform mobile sdk for android 多点触摸 修正

    修正 scaleform 的多点触控 (随手一记 给后来的人做个参考) scaleform 版本号 4.2.24 (估计这就是最后一个 移动版的版本了,万年没有更新了) 开始 一直以为 scalefo ...

随机推荐

  1. Server Tomcat v7.0 Server at localhost was unable to start within 45 seconds 解决方法

    Server Tomcat v6.0 Server at localhost was unable to start within 45 seconds. If the server requires ...

  2. Hibernate调用存储过程和函数

    操作大批量数据或复杂逻辑,考虑到执行效率和代码量的时候,存储过程和函数在数据库中是预编译好的,调用执行效率高 // 调用过程 {call 过程名称(?,?,?)} public static void ...

  3. childNodes 和children

    childNodes 兼容性不是很好,一般用children 元素.childNodes : 只读 属性 子节点列表集合标准下:包含了空白换行和元素类型的节点,也会包含非法嵌套的子节点非标准下:只包含 ...

  4. Oracle手工建库

    环境准备 手工建库的前提是ORACLE软件已经正确安装到操作系统中,只是需要我们利用ORACLE软件提供的一些工具和脚本来创建一个数据库,创建这个数据库可以运行DBCA工具图形化创建,也可以使用CRE ...

  5. IOS第二天多线程-03对列组合并图片

    ********* // 2D绘图 Quartz2D // 合并图片 -- 水印 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *) ...

  6. Sharepoint 2013 回收站知识整理

    回收站机制可有利于防止内容的永久删除与误删除. 一.SharePoint 2013 回收站包括两种:第一回收站(End user Recycle Bin items)与 第二回收站(Deleted f ...

  7. ajax+ashx

    eg: $('.setIsEnableClosed').click(function(){ var id=$(id).attr("name"); var isChecked=$(t ...

  8. C#winform调用外部程序,等待外部程序执行完毕才执行下面代码

    1.简单调用外部程序文件(exe文件,批处理等),只需下面一行代码即可 System.Diagnostics.Process.Start(“应用程序文件全路径”); 2.如果要等待调用外部程序执行完毕 ...

  9. NEC学习 ---- 模块 -水平文字链接列表

    HTML代码: <div class="container"> <div class="m-list1"> <ul class=& ...

  10. 无法启动Mysql服务,错误InnoDB: Attempted to open a previously opened tablespace.

    2013-08-04 13:48:22 760 [ERROR] InnoDB: Attempted to open a previously opened tablespace. Previous t ...