Android2.3触摸屏功能详解

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

Android2.3触摸屏功能详解


手机设备上常用触摸屏进行用户操作,非常方便快捷,而且正好有个项目上用到这个设备,所以就花时间研究了一下。好了,还是老规则:大体了解概念先,细节线索找代码:

InputReader.cpp 中有针对单点触摸SingleTouchInputMapper及多点触摸MultiTouchInputMapper的处理代码,这两个类都继承自TouchInputMapper,由syncTouch处理最终的触摸屏动作的发送。

1、首先了解一下触摸屏中的几个参数概念:

“接触”一词用来描述一个物体直接碰到另一个物体的表面。

单点触摸的参数解析:

ABS_XABS_Y分别对应触摸屏的xy坐标

ABS_PRESSURE是压力值,一般触摸屏也只是分是否有按下去,按下去的话值会大于多少,没有按的话值小于多少

ABS_TOOL_WIDTH 触摸工具的宽度

多点触摸的参数解析:

ABS_MT_POSITION_X 接触面的形心的X坐标值 

ABS_MT_POSITION_Y 接触面的形心的Y坐标值 

 ABS_MT_TOUCH_MAJORABS_MT_WIDTH_MAJOR 分别被用来提供手指的大小和触摸面积大小 

TOUCH 和 WIDTH参数给出了个,想想如果一个手指按在玻璃上,透过玻璃你将看到两个区域,一个是手指与玻璃接触的区域,用 ABS_MT_TOUCH_MAJOR描述,一个是手指本身大小的区域,ABS_MT_WIDTH_MAJOR描述, 手指与玻璃接触的面积要小于手指本身的大小,通过这两个参数,可以换算出手指的压力。也可通过 ABS_MT_PRESSURE参数直接提供手指的压力。

  除了 MAJOR这个参数,还可以提供一个 MINOR参数,手指可以被认为是一个椭圆,MAJOR和 MINOR可以认为是这个椭圆的长轴和短轴,椭圆的中心可以被 ORIENTATION这个参数描述。

ABS_MT_PRESSURE

  接触工具对接触面的压力大小,可以用来代替上面的四个参数。

ABS_MT_ORIENTATION

  描述随圆的转动趋势,这是一个抽相值,O值表示接触面在平行与触摸屏的Y轴,向左是负值,向右是正值,如果完全平行于X轴,则上向返回最大值。如果接触面是圆形,则可以忽略这个参数。如果内核不能获得这个参数有有效值,但可以区分接触面的长短轴,这个功能还是可以被部份支持,在一些设备中, ABS_MT_ORIENTATION 的值只能是 0和1。

ABS_MT_TOOL_TYPE描述接触工具类型(手指,触控笔等 ),很多内核驱动无法区分此参数如手指及笔,如果是这样,该参数可以不用,协议目前支持MT_TOOL_FINGERMT_TOOL_PEN两种类型。
ABS_MT_BLOB_ID形状集ID,集合几个点以描述一个形状,很多驱动没有形状属性,此参数可以不用。

ABS_MT_TRACKING_ID描述了从接触开始到释放的整个过程的集合,如果设备不支持,此参数可是不用。

计算方法:

  一些设备将触摸面作为一个矩形上报,可以通过下面这些公式来计算出协议中所需要的信息。

ABS_MT_TOUCH_MAJOR := max(X, Y)

ABS_MT_TOUCH_MINOR := min(X, Y)

ABS_MT_ORIENTATION  := bool(X > Y)

ABS_MT_ORIENTATION的取值范围为0至1,用来标识矩形接触面偏向X轴或Y轴的程度。

触摸轨迹

仅有少数设备可以明触的标识真实的 trackingID,多数情况下 trackingID只能来标识一次触摸动作的过程。

手势

多点触摸指定的应用是创建手势动作, TOUCH和 WIDTH参数经常用来区别手指的压力和手指间的距离,另外 MINOR类的参数可以用来区别设备的接触面的大小(点接触还是面接触),ORIENTATION可以产生旋转事件。

以上的含义从http://www.kernel.org/doc/Documentation/input/multi-touch-protocol.txt 翻译而来,可以自行下载

2、代码入手

第一部分:直接写/dev/input/eventX接点实现

单点触摸事件发送序列:

EV_KEY (BTN_TOUCH) 发送是否在按下或弹出(0或者1

ABS_X 

ABS_Y

ABS_PRESSURE

ABS_TOOL_WIDTH

代码演示:

event.type  = EV_KEY;

event.code  = BTN_TOUCH;

mDown = (istEvent->pointers[0].abs_pressure > 0)?1:0 ;

Event.value  = mDown;

write(fd,&event,sizeof(event)) ;

/* 触摸屏键按下坐标定位  */

event.type  = EV_ABS;

    event.code  = ABS_X;

    event.value = istEvent->pointers[0].abs_x;

    write(fd,&event,sizeof(event)) ;

event.type  = EV_ABS;

    event.code  = ABS_Y;

    event.value = istEvent->pointers[0].abs_y;

    write(fd,&event,sizeof(event)) ;

    /* 触摸屏接触面的压力大小 */

event.type  = EV_ABS;

    event.code  = ABS_PRESSURE;

    event.value = istEvent->pointers[0].abs_pressure;

    write(fd,&event,sizeof(event)) ;

event.type   = EV_ABS;

event.code   = ABS_TOOL_WIDTH;

event.value  = istEvent->pointers[0].abs_touch_major;

/* 结束完整帧数据,发送同步信号 */

    event.type  = EV_SYN; 

    event.code  = SYN_REPORT;

    event.value = 0;

    write(fd, &event, sizeof(event));

    

    Ok,非常简单,对比inputreader.cpp中的代码,注意process代码:

void SingleTouchInputMapper::process(const RawEvent* rawEvent) {

    switch (rawEvent->type) {

    case EV_KEY:  //一定要注意发送这个event,否则触摸事件不会发送出去,直接丢弃

        switch (rawEvent->scanCode) {

        case BTN_TOUCH:

            mAccumulator.fields |= Accumulator::FIELD_BTN_TOUCH;

            mAccumulator.btnTouch = rawEvent->value != 0;

            // Don't sync immediately.  Wait until the next SYN_REPORT since we might

            // not have received valid position information yet.  This logic assumes that

            // BTN_TOUCH is always followed by SYN_REPORT as part of a complete 

            // packet.

            break;

        }

        break;

...

}

void SingleTouchInputMapper::sync(nsecs_t when) {

...

    if (mDown) {  // 这就是上面为何要发送的原因

        mCurrentTouch.pointerCount = 1;

        mCurrentTouch.pointers[0].id = 0;

        mCurrentTouch.pointers[0].x = mX;

        mCurrentTouch.pointers[0].y = mY;

        mCurrentTouch.pointers[0].pressure = mPressure;

        mCurrentTouch.pointers[0].touchMajor = 0;

        mCurrentTouch.pointers[0].touchMinor = 0;

        mCurrentTouch.pointers[0].toolMajor = mToolWidth;

        mCurrentTouch.pointers[0].toolMinor = mToolWidth;

        mCurrentTouch.pointers[0].orientation = 0;

        mCurrentTouch.idToIndex[0] = 0;

        mCurrentTouch.idBits.markBit(0);

}

...

}

多点触摸事件发送序列:

ABS_MT_TOUCH_MAJOR

ABS_MT_PRESSURE

ABS_MT_POSITION_X

ABS_MT_POSITION_Y

SYN_MT_REPORT      //上报第一个点

ABS_MT_TOUCH_MAJOR

ABS_MT_PRESSURE

ABS_MT_POSITION_X

ABS_MT_POSITION_Y

SYN_MT_REPORT      //上报第二个点

... //以上顺序组织多点touch event即可

SYN_REPORT         //最后发送的完整包动作

代码演示:

for(pointIndex=0;pointIndex<imtEvent->pointnums;pointIndex++)

{

/* 触摸屏键按下坐标定位  */

event.type  = EV_ABS;

event.code  = ABS_MT_POSITION_X;

event.value = imtEvent->pointers[pointIndex].abs_x;

write(fd,&event,sizeof(event)) ;

event.type  = EV_ABS;

event.code  = ABS_MT_POSITION_Y;

event.value = imtEvent->pointers[pointIndex].abs_y;

write(fd,&event,sizeof(event)) ;

    /* 触摸屏接触面的压力大小 */

event.type  = EV_ABS;

    event.code  = ABS_MT_PRESSURE;

    event.value = imtEvent->pointers[pointIndex].abs_pressure;

    write(fd,&event,sizeof(event)) ;

/* 触摸屏接触面积大小 */

event.type   = EV_ABS;

event.code   = ABS_MT_TOUCH_MAJOR;

event.value  = imtEvent->pointers[pointIndex].abs_touch_major;

event.type  = EV_SYN;

event.code  = SYN_MT_REPORT;

event.value = 0;

write(fd,&event,sizeof(event)) ;

}

/* 结束完整帧数据,发送同步信号 */

event.type  = EV_SYN;

event.code  = SYN_REPORT;

event.value = 0;

write(fd,&event,sizeof(event)) ;

Ok,只要深入研究下inputreader.cpp的代码即可轻松解决这些问题,更扩展的功能扩大及缩小,以及旋转的功能都可以搞定。

对于多点触摸的功能,首先在linux内核的input输入模型需要支持,这个在linux/input.h可以见到,多点触摸功能依赖于以下几个主要的软件位:

#define ABS_MT_TOUCH_MAJOR 0x30/* Major axis of touching ellipse */ 

#define ABS_MT_TOUCH_MINOR 0x31/* Minor axis (omit if circular) */ 

#define ABS_MT_WIDTH_MAJOR 0x32/* Major axis of approaching ellipse */ 

#define ABS_MT_WIDTH_MINOR 0x33/* Minor axis (omit if circular) */ 

#define ABS_MT_ORIENTATION 0x34/* Ellipse orientation */ 

#define ABS_MT_POSITION_X 0x35/* Center X ellipse position */ 

#define ABS_MT_POSITION_Y 0x36/* Center Y ellipse position */ 

#define ABS_MT_TOOL_TYPE 0x37/* Type of touching device */ 

#define ABS_MT_BLOB_ID 0x38/* Group a set of packets as a blob */

第二部分:利用linux input输入模型发送

主要函数介绍:

static inline void input_report_abs(struct input_dev *dev, unsigned int code, int value)

{

input_event(dev, EV_ABS, code, value);

}

static inline void input_mt_sync(struct input_dev *dev)

{

input_event(dev, EV_SYN, SYN_MT_REPORT, 0);

}

static inline void input_sync(struct input_dev *dev)

{

input_event(dev, EV_SYN, SYN_REPORT, 0);

}

代码示例:

设定初始参数(支持单点触摸及多点触摸):

    set_bit(EV_SYN, ts->input_dev->evbit);

    set_bit(EV_KEY, ts->input_dev->evbit);

    set_bit(EV_ABS, ts->input_dev->evbit);

    set_bit(BTN_TOUCH,ts->input_dev->keybit);

    

    max_x = 1280;

    max_y = 720;

    

    input_set_abs_params(ts->input_dev, ABS_X, 0, max_x, 0, 0);

    input_set_abs_params(ts->input_dev, ABS_Y, 0, max_y, 0, 0);

    input_set_abs_params(ts->input_dev, ABS_PRESSURE, 0, 255, 0, 0);

    input_set_abs_params(ts->input_dev, ABS_TOOL_WIDTH, 0, 15, 0, 0);

    input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 0, max_x, 0, 0);

    input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0, max_y, 0, 0);

    input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);

    input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 15, 0, 0);

    input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0); 

    input_register_device(ts->input_dev);    

按下时:

for(i=0;i<finger;i++){

    input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 1);

    input_report_abs(ts->input_dev, ABS_MT_PRESSURE, 100);

    input_report_abs(ts->input_dev, ABS_MT_POSITION_X, ts->x[i]);

    input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, ts->y[i]);

    input_mt_sync(ts->input_dev);

    ts->upsend=0;

}

input_sync(ts->input_dev);

弹起时:

    input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0);

    input_report_abs(ts->input_dev, ABS_MT_PRESSURE, 0);

    input_mt_sync(ts->input_dev);

    input_sync(ts->input_dev);


android 9】【input】【11.发送普通motion事件1——touch设备的加载——MultiTouchInputMapper】 从之前的篇幅我们知道了,事件分为设备增删事件和原始输入事件,而原始输入事件主要有两种,一种是key按键事件的派发,一种是触摸事件的派发。Key事件的派发我们已经分析过了,本篇主要针对motion事件的派发。想要了解motion事件的派发,首先需要了解到touch设备的是如何加载的,本篇和前文的input设备流程相同,只是对于触摸屏的配置进行了更详细的描述。如MultiTouchInputMapper的创建过程。 阅读详情

相关推荐

Android input

InputManagerService是Android系统中的一个重要服务,它负责管理和处理用户输入事件。它的主要功能包括接收和分发用户输入事件、处理触摸事件、键盘事件和其他输入事件,并将它们传递给相应的应用程序或系统组件。具体来说,InputManagerService通过以下几个方面实现了对用户输入事件的管理和处理:事件分发:InputManagerService接收到用户输入事件后,会根据事件的类型和目标应用程序的状态,将事件分发给合适的应用程序或系统组件进行处理。

liuning1985622的博客 1750

Android系统 添加动态控制USB TP触摸方向、触摸唤醒

本文介绍实现USB触摸屏(TP)的唤醒和旋转功能,对Android系统的三个模块进行了修改:inputflinger、surfaceflinger和Settings。inputflinger是负责处理输入事件的服务,它接收来自硬件设备的原始输入事件,并将它们转换为Android系统可以理解的事件,如触摸等。surfaceflinger是负责管理显示输出的服务,它接收来自应用程序和系统服务的图形缓冲区,并将它们合成为最终的显示帧,然后发送给硬件设备。 Settings应用程序,它提供了用户操作界面。

我其实什么都不会 2414

Android每周专题】触摸屏手势

本系列文章均为A2BGeek原创,转载务必在明显处注明: 转载自A2BGeek的【Android每周专题】系列,原文链接: 这篇专题来研究一下Android触摸屏手势Gesture,Android的手势有两种,一种是View和Activity的(基于触摸屏事件,所以Activity也能添加手势),一种是手写输入法或者一些手机浏览器的快捷手势那样的带笔迹的手势识别。这一点从API文档中就能

A2BGeek的专栏 1万+

linux 多点协议,Linux入门教程:Linux多点触控协议

上面的四个参数用来描术接触面的一些附加信息, ABS_MT_TOUCH_MAJOR / ABS_MT_WIDTH_MAJOR的比值可以用来反应接触时的压力值。ABS_MT_PRESSURE接触工具对接触面的压力大小,可以用来代替上面的四个参数。ABS_MT_ORIENTATION描述随圆的转动趋势,这是一个抽相值,O值表示接触面在平行与触摸屏的Y轴,向左是负值,向右是正值,如果完全平行于X轴,则上...

weixin_33416697的博客 583

安卓外挂红外触摸屏的软件设计

安卓外挂红外触摸屏的软件设计 许海燕, 黄贤立 (淮阴师范学院计算机科学与技术学院 江苏 淮安 223300) 【 摘 要】基于 Android 输入系统开发了 安卓外挂红外触摸屏的驱动软件。 USB 接口的红外触摸屏连接到 A83T 开 发板上,触摸点数据通过安卓 Input 子系统上报。 本文描述了 触摸系统的硬件架构和安卓输入系统的编程体系,给出了 触 屏驱动的主要设计和实现过程。 【关键词...

mzm2438975656的专栏 3092

android4.0与2.3版本的触摸屏驱动调试注意

转自搜索到的一篇blog,他没有注明转载出处,我也没法写出处了,对原创作者隔空说一声抱歉。 android4.0与2.3版本的TP代码区别 在android2.3上调试TP时,只需要把linux驱动调通,android就可以正常使用了,而到android4.0上又有些不同了,针对linux驱动,需添加如下内容:     1、在手指按下时需调用如下函数上报Key Down:

joard_yang的专栏 8443

android 禁用触摸屏,Touch Protector-安卓禁用手机触摸屏软件

Touch Protecto是一款安卓平台上用来临时禁用禁用手机触摸屏软件,意思就是开启App之后你即便疯狂触摸屏幕也不会产生任何交互,以防止某些特定场景的意外操作触摸屏,从此达到防误触的目的。Touch Protector虽然是英文的,但是操作起来还是非常简单的,开启软件之后在通知栏点击一下Touch Protector即可生效,按下音量键就能够恢复正常。除此之外,你可以结合使用喜欢去设定更多操...

weixin_39623350的博客 6141

android触摸屏坐标转换,(转)android触摸屏校正详解

最近一段时间在搞android触摸屏校正,想把心得记下来与大家分享,废话不多说,开始讲解.注:调试使用的是一、修改内核驱动修改触摸屏驱动(kernel/drivers/input/touchscreen/s3c-ts.c)-input_set_abs_params(ts->dev,ABS_X,X_COOR_MIN,X_COOR_MAX,X_COOR_FUZZ,0);-input_...

weixin_33101399的博客 1710

android触摸屏校正详解

最近一段时间在搞android触摸屏校正,想把心得记下来与大家分享,废话不多说,开始讲解.注:调试使用的是伟研科技(www.gzweiyan.com)210开发板,android版本 2.2 ,内核2.6.32一、修改内核驱动  修改触摸屏驱动(kernel/drivers/input/touchscreen/s3c-ts.c)      -input_set_abs_p

gzweiyan2的专栏 1万+

android 触摸屏部分失灵,触摸屏失灵修复小技巧

手机触摸屏失灵修复小技巧1、直接关闭手机,然后静置几分钟后再开机看看,如果手机支持拆卸电池,那么最好将电池也拆下来。2、使用USB数据线将手机与电脑连接,看看是否可以解决。3、针对屏幕出现飘逸的情况,我们可以使用电吹风开至中档,用热风吹手机屏幕,需要说明的是,使用电吹风时手机必须在关机的情况下,然后等到屏幕稍微有点热度后停止吹风,再开机看看是否解决问题。4、洗完手后,用湿润的手操作屏幕试试。5、在...

weixin_36218863的博客 1万+

Android系统USB触摸屏配置方法

一、确认触摸屏是否能够正常工作 一般的USB 接口免驱触摸屏均能免驱支持windows XP, windows 7, windows 8 等windows 家族的操作系统,所以在使用触摸屏搭建最终使用环境乊前可以使用windows家族系统测试触摸屏,确保触摸屏能够正常的工作(相当于来料检测)。 接下来测试触摸屏能否支持当前的android 操作系统,假设当前的操作系统是原生的Android

撒哈拉的绿洲 2万+

Android电阻触摸屏校准

首先电阻屏为什么需要校准,这是电气方面的知识,我也不懂,这里就不说了,这里主要讲讲自己在项目中是怎么通过应用程序来实现校准的,好记性不如烂笔头这里有一篇讲解触摸屏校准原理和优化的文章,道客巴巴上的,先看看了解怎么做触摸屏校准原理与优化 通过一系列文章的了解,认识到要想真正做到实现校准,就必须能够更新android系统中的转换参数文件,看一些文章的介绍,不知道是因为版本或者平台,总感觉和我的系统版

Stay hungry , Stay foolish 5564

android实现触摸屏校准

原文地址:http://wapwenku.baidu.com/view/63520a48e518964bcf847cb0?pn=1&ssid=0&from=514a_w1_1288324520&bd_page_type=1&uid=frontui_1288324520_9386&pu=sl@1,pw@1000,sz@224_220,pd@2,fz@2,lp@9,tpl@color,&st=1&bo

浩海天空 2942

GT911触摸屏调试与Android开发

触摸屏在现代移动设备和嵌入式系统中扮演着重要的角色,它是用户与设备之间的主要交互界面。GT911是一种常见的触摸屏控制器芯片,广泛应用于Android设备中。本文将介绍如何在Android开发中进行GT911触摸屏的调试,并提供相应的源代码示例。通过以上步骤,我们可以在Android开发中调试和使用GT911触摸屏。请根据实际情况进行适当的修改和调试,以确保触摸屏适当的修改和调试,以确保触摸屏功能正常工作。在上述示例中,我们使用了I2C总线(i2c1)与GT911触摸屏进行通信。在上述示例中,我们在。

CyberGenius的博客 2万+

安卓蓝牙HID TouchScreen协议详解:从‘绝对鼠标’的坑到‘真触摸屏’的实现

本文深入解析安卓蓝牙HID TouchScreen协议,从协议差异、权限适配到坐标映射算法,详细介绍了如何实现真触摸屏功能而非传统的绝对鼠标方案。通过实战案例和技术细节,帮助开发者避开常见陷阱,实现精准触控和多指操作,适用于绘图、手势等高级应用场景。

weixin_30402343的博客 4822

Android驱动04】触摸屏touchscreen驱动移植以及调试方法

getevent是Android系统中用于获取输入设备事件信息的工具,它可以捕获触摸屏、键盘等输入设备的原始事件数据。通过分析getevent输出的数据,可以了解触摸屏的响应情况,包括触摸点的坐标、压力值、事件类型等。数据处理:驱动程序将读取到的原始触摸数据进行处理,转换为标准的输入事件格式(如ABS_X、ABS_Y等),并准备将其上报给输入子系统。3,ADB 提供了一个更高级的 input 命令,用于模拟键盘和触摸屏输入,而不需要知道底层的设备文件和事件代码。这些事件包括触摸点的位置、压力等信息。

jiangchaobing_2017的博客 4708

linux android 电容 触摸屏驱动 差别,Android触摸屏驱动架分析

一、android framework相关1. 触摸屏架简介:系统启动后,android init程序将启动SystemServer,该程序又启动了WindowManagerService服务,该服务启动了InputManager,InpuManager中,启动了两个独立的线程:InputReader(通过Evhub获取kernel底层input事件,并转发给InputDispatcher)...

weixin_39906499的博客 267
上一篇: android 动态库死机调试方法
下一篇: 荒野生存 观后感
andyhuabing
博客等级 码龄19年 704粉丝 165原创
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值