本文着重介绍了Android 多点触控协议的相关知识及
adb
命令
getevent
的数据解析方法。具体的程序实现并不是本文的重点。
关于 需求1 的示例说明:例如,用户点击了桌面上的“日历” App,在我们自己的 App 中需要获取到用户所点击的坐标,并且用户的点击操作不能受到影响,“日历” App 是可以正常启动的。又比如用户正在玩游戏,我们需要获取到用户所有操作的触控信息。
那么,可行的方案我们很自然会想到
adb
命令
getevent
可以实现获取全局点击坐标的要求,但是该命令是无法直接在 App 里调用的。原因显而易见,这种危险级操作
App 级权限
当然是不够的,至少需要
shell 级
的权限。
这里的关键是我们需要有一个
Android 可执行程序
。实现
Android 可执行程序
的方法也有很多,可以是
dex
也可以是其它在 Android 上编译的 C 或 C++ 程序。当然还可以使用像 Go 语言这样的编程语言,直接将程序编译成可以在 Android 上执行的程序。
此外,我们可以在该可执行程序中创建一个守护进程,让程序一直执行,这样程序就不会随着
adb
终端的断开而停止,因此就不需要手机一直连接电脑了,从而满足
需求3
的要求。
PS:本人是使用 Go 来实现这个 Android 可执行程序 的。
具体的实现代码,不是本文要讲的重点。因为程序实现的思路才是最重要的,有了思路程序自然就好写了。
先说一个结论:
从 Android 内核 4.14 开始,仅支持多点触控协议“类型 B”。内核驱动程序会将多点触控协议“类型 A”转换成“类型 B”。[^12][^13]
PS:部分 Android 9,10 支持内核
4.14
。Android 11 及之后版本,均支持内核
4.14
。后文会有进一步的说明。
至于什么是多点触控协议,可以查看后文关于 多点触控协议 的说明。如何查看内核版本,以及内核版本与 Android 版本的对应关系,详见后文的 关于内核版本 。
1 |
Usage: getevent [-t] [-n] [-s switchmask] [-S] [-v [mask]] [-d] [-p] [-i] [-l] [-q] [-c count] [-r] [-R] [device] |
1 |
$ getevent -lp /dev/input/event4 |
查看所有输入设备支持的事件信息
通过此命令,我们可以知道哪个输入设备是负责处理屏幕事件的。
通过下面的示例,我们得知
/dev/input/event4
是负责处理屏幕事件的。
1 |
add device 5: /dev/input/event4 |
说明:也可以使用
getevent -li
,
-i
比
-p
显示更多信息。
1 |
$ getevent -lp # Sony Xperia 1 III(SO-51B) Android 11 |
其它真机测试结果详见“附录”中的“ 处理屏幕事件的输入设备 ”。
这回终于说到我们要讲的重点了。该示例是我们程序中要重点处理的部分,通过该示例,我们就可以持续获取用户在屏幕上的全局触控事件。
说明:
getevent
命令虽然也可以指明具体使用哪个输入设备,例如,
getevent -lt /dev/input/event4
。不过在程序中不太容易准确的识别出到底哪个输入设备是处理屏幕事件的。所以建议使用该命令时,不要指明具体的输入设备。因为同一时间,我们通常只会使用一种输入设备,比如手指触控是最常见的。因此
getevent -l
产生的数据通常都是手指触控产生的。所以使用该命令时,可以不指明输入设备。
虽然感觉通过输入设备的
name
应该也可以确认哪个是处理屏幕事件的,但是这个
name
也不固定,所以程序不太好判断。比如,我遇到过值的有:
sec_touchscreen
、
touchscreen
、
touchpanel
、
elan-touchscreen
、
huawei,ts_kit
、
input_mt_wrapper
、
fts_ts
。
1 |
$ getevent -lt # Sony Xperia 1 III(SO-51B) Android 11 |
注意,触控事件的值是 16 进制的。
理论上,我们只要解析出上面那个示例的结果,就可以得到用户所点击的屏幕坐标了。不过在解析执行结果之前,我们要先了解一个概念,那就是“多点触控协议”[^14][^15]。
Android 设备的“多点触控协议”一共有两种类型,分别是“类型 A”和“类型 B”。强烈建议大家完整的看一下 Linux kernel 官方文档关于 多点触控协议 的讲解,以及 Android 官方文档关于 触控设备 的说明。
需要注意前面“ 正文 ”中讲到的:
从 Android 内核 4.14 开始,仅支持多点触控协议“类型 B”。内核驱动程序会将多点触控协议“类型 A”转换成“类型 B”。[^12][^13]
多点触控协议类型 A (stateless type A protocol),是无状态的。
大多数手机中,使用“类型 A”的设备并不多。目前我测试过的手机中,在部分“华为”手机上遇到过此种协议。大多数手机还是使用“类型 B”的。
关于“类型 A”官网介绍[^14]如下:
For devices handling anonymous contacts (type A), the protocol
describes how to send the raw data for all contacts to the receiver.
简单理解就是发生多点触控时,“类型 A”无法区分及跟踪是哪个手指产生的触控信息,它只知道触控产生的坐标,并将这些原始触控信息发送给所有接收者。
例如:
手指1
按在了屏幕
(x1, y1)
的位置,
手指2
按在了屏幕
(x1, y2)
的位置,“类型 A”会将
(x1, y1)
,
(x1, y2)
发送给所有接收者。
关于“类型 A”,这里有几点需要注意的地方:
手指2
的触控坐标
x1
,与
手指1
的触控坐标
x1
相同,未发生变化,但是“类型 A”在发送数据时,会将
手指2
的完整触控点信息,也就是
(x1, y2)
发送给所有接收者,并不会忽略未变化的数据。
接下来让我们看一下“类型 A”的实例:
1 |
$ getevent -lt |
多点触控协议类型 B (stateful type B slot protocol),是有状态的。
目前我测试过的手机中,大多数还是使用“类型 B”的。
关于“类型 B”官网介绍[^14]如下:
For devices capable of tracking identifiable contacts (type B), the protocol describes how to send updates for individual contacts via event slots.
简单理解就是,与“类型 A”相比,发生多点触控时,“类型 B”除了发送坐标外,还会额外发送“手指信息”,用于跟踪是哪个手指产生的数据。而且 “类型 B”只发送变化的数据 。
例如,如果
手指1
点击了
(x1,y1)
,
手指2
点击了
(x1, y2)
,那么
手指2
的触控坐标
(x1, y2)
中,只有
y2
的信息会被发送,因为
x1
并没有发生变化。这么做的好处是显而易见的,那就是减少了发送的数据量。
对于“类型 B”,内核驱动程序会为每个被识别的触控点分配一个
slot
,并且使用这个
slot
上报发生变化的数据。通过修改
slot
的
ABS_MT_TRACKING_ID
,就可以实现触控点信息的新增,替换,删除。
ABS_MT_TRACKING_ID
的值含义,详见后文“常用的触控事件”中关于“
ABS_MT_TRACKING_ID
”的部分。
对于“类型 B”,由于只有变化的数据会被上报,因此每一个触摸点的完整信息必须由接收端来维护。接收端收到一条 MT(Multi-touch) 消息,我们就应该更新当前
slot
的相关触控信息。
根据我的个人经验(目前还没有阅读相关源代码),在程序中有以下几种方法可以较为方便的区分“类型 A”与“类型 B”:
执行
getevent -lp
命令时:
ABS
中若
出现
ABS_MT_SLOT
,则为 “类型 B”,否则为“类型 A”。
ABS
中若
出现
ABS_MT_BLOB_ID
,则为 “类型 A”,否则无法断定协议类型。
执行
getevent -l
持续获取触控信息时:
SYN_MT_REPORT
事件。
ABS_MT_BLOB_ID
事件,则为 “类型 A”,否则无法断定协议类型。
注意
:“类型 A”中
不一定
包含
ABS_MT_BLOB_ID
,但若包含,则一定是 “类型 A”。
具体测试结果详见“附录”中的“ 处理屏幕事件的输入设备 ”。
1 |
$ getevent -ltr /dev/input/event5 |
组合官方文档[^14],我们将上述示例做最小化处理:
1 |
EV_ABS ABS_MT_POSITION_X 00000494 # 16进制(1172) 触控区域(touching region)中心位置的 X 轴坐标 |
每一组事件数据包的结尾都会有一个
SYN_MT_REPORT
事件,该事件
仅出现
在“类型 A”中。代表接收者可以接收当前的触控信息并准备开始接收下一组信息。
如果驱动程序除了上报
ABS_MT
事件外,还上报了
BTN_TOUCH
或
ABS_PRESSURE
事件,那么最后一个
SYN_MT_REPORT
可能会被忽略掉。否则,最后的
SYN_REPORT
事件会被
input 核心系统
丢掉,从而导致
0 触控点事件
(zero-contact event)发送给用户。
编者注: 后半句中的“zero-contact event”不是很理解,不知道“zero-contact”是一个术语啊,还是代表“没有触控”的意思。所以附上原文,请高手解答吧。
If the driver reports one of BTN_TOUCH or ABS_PRESSURE in addition to the
ABS_MT events, the last SYN_MT_REPORT event may be omitted. Otherwise, the
last SYN_REPORT will be dropped by the input core, resulting in no
zero-contact event reaching userland.
其它事件含义,后文会有详细讲解。
1 |
$ getevent -ltr /dev/input/event5 # 两点触控 |
对其做最小化处理:
1 |
EV_ABS ABS_MT_POSITION_X 00000385 # 16进制(901) 触控区域(touching region)中心位置的 X 轴坐标 |
接下来让我们看一下“类型 B”的单点触控完整实例[^19]:
1 |
$ getevent -l /dev/input/event4 # Sony Xperia 1 III(SO-51B) Android 11 - kernel 5.4.61 |
我们结合官方文档[^14],将上面“类型 B”的实例做最小化处理并加以说明:
1 |
ABS_MT_SLOT 00000000 # 为新触控点分配 slot 其值为 0 |
注意:
ABS_MT_POSITION_X
与
ABS_MT_POSITION_Y
的值是16进制的,它们分别代表的是“**
触控区域(touching region)
”中心位置的坐标值。注意,
该值
不一定**是真实的屏幕坐标值,有可能需要进行一次转换,具体转换方法详见
事件计算
。
整个触控过程当中,
SYN_REPORT
通常会出现多次,每出现一次
SYN_REPORT
就代表一组触控事件已经处理结束。
另外,什么是“** 触控区域(touching region) **”,后文会详细讲解。
我们再来看一个“类型 B”的多点触控实例[^19](两点触控):
1 |
$ getevent -l /dev/input/event4 # Sony Xperia 1 III(SO-51B) Android 11 - kernel 5.4.61 |
我们再将其做最小化处理:
1 |
ABS_MT_SLOT 00000001 # 为新触控点分配 slot 值为 1 |
假设单点屏幕时,首次出现的
ABS_MT_SLOT
值为
0
。那么之后再次单点的话,由于触控点并没有出现两个或更多的情况,因此
ABS_MT_SLOT
的值并不会发生变化,其值始终为
0
。由于“
‘类型 B’仅发送变化的数据
”,因此在这种情况下,自然就不会再发送
ABS_MT_SLOT
。
那单点触控时又怎样才会再出现
ABS_MT_SLOT
呢?如果你明白了上面的道理,那么你可能已经猜到方法了。方法其实很简单,利用“
‘类型 B’仅发送变化的数据
这一特点。
举例说明:假设
手指0
点击屏幕时出现的
ABS_MT_SLOT
值为
0
,保持
手指0
处于按下的状态,再按下
手指1
。由于出现了新的触控点,因此会产生一个新的
ABS_MT_SLOT
,假设其值为
1
。保持
手指0
和
手指1
同时处于按下的状态,先抬起
手指0
(注意,先抬起的是
手指0
),之后再抬起
手指1
。完成这些操作后,此后再次进行单点操作时,
ABS_MT_SLOT
就会出现了。
让我们用下面的模拟事件来看一下整个过程:
1 |
# 按下 “手指0” |
切记:“ ‘类型 B’仅发送变化的数据。 ”
关于这两个概念,官网[^14]用了一个形象的例子来讲解,用来说明什么是
ABS_MT_POSITION_X/Y
,
ABS_MT_TOOL_X/Y
,
ABS_MT_TOUCH_MAJOR
和
ABS_MT_WIDTH_MAJOR
。进而解释了什么是“触控区域”和“触控面”。
官网举了这样一个例子:想象一下,当你透过玻璃观察一个人将一根手指按在玻璃上某个特定点的过程。当手指与玻璃完全接触时,在整个接触过程,我们会看到两个区域:
一个是内部区域,也就是手指真正想按压的那个点的区域(下图中 a 区域)。这部分区域我们叫做“**触控区域(touch region)**”。
别一个是外部区域,也就整个手指接触玻璃的区域(下图中 b 区域),也可以理解成整个“触控工具”的接触区域。这部分区域我们叫做“**触控面(approaching finger/finger region)**”。
“触控区域(touch region)”的中心点坐标就是
ABS_MT_POSITION_X/Y
,也就是下图中
a
的坐标。
“触控面(approaching finger/finger region)”的中心点坐标就是
ABS_MT_TOOL_X/Y
,也就是下图中
b
的坐标。
“触控区域”的直径就是
ABS_MT_TOUCH_MAJOR
。
“触控面”(或称作“触控工具”)的直径就是
ABS_MT_WIDTH_MAJOR
。
再接着试想下:那个人现在开始在那个点上用力按压了。这个过程中,“
触控区域
”
a
变大了,而且变大的幅度相比“
触控面
”
b
也更大。因此,通常情况下,
ABS_MT_TOUCH_MAJOR / ABS_MT_WIDTH_MAJOR
的值也会变大,并且该值通常小于
1
。我们可以将该比值理解成
“
触控压力(contact pressure)
”
。当然,对于支持压力检测的设备来说,可以使用
ABS_MT_PRESSURE
作为“触控压力”。
对于支持“**触控悬停(contact hovering)**”的设备来说,可以使用
ABS_MT_DISTANCE
来表明触摸工具与触摸屏表面之间的距离。
1 |
Linux MT Win8 |
除了上述提到的那些与
MAJOR
有关的事件外,在描述“**触控区域(touch region)
”
a
与“
触控面(approaching finger/finger region)**”
b
时,还可以使用一些与
MINOR
有关的事件。并且使用
ORIENTATION
事件表示“触控区域”的方向,“触控面”方向用向量
(a-b)
来表示。
要想了解完整的触控事件,大家可以参考 官网 的 “Event Semantics” 这一部分。下面仅列出一些手机设备上经常遇到的触控事件。
“
触控区域(touching region)
”中心位置的
X
轴坐标。
该值是16进制的, 其值 不一定 是真实的屏幕坐标值 ,有可能需要进行一次转换,具体转换方法详见 事件计算 。
“
触控区域(touching region)
”中心位置的
Y
轴坐标。
该值是16进制的, 其值 不一定 是真实的屏幕坐标值 。有可能需要进行一次转换,具体转换方法详见 事件计算 。
TRACKING_ID
用来标识一个触摸点,追踪其从被按下开始直到抬起的整个过程。该值的取值范围应该足够大,以确保在足够长的时间内,能唯一标识一个触摸点。(通过
getevent -lp
可以知道
TRACKING_ID
的最大值。)
其值含义如下:
Tracking ID
代表一个触控点。
-1(0xFFFF FFFF)
代表未使用的
slot
。
Tracking ID
表示这是一个新的触控点。
Tracking ID
不存在了,表示一个被删除的触控点。
表示“触控区域”
a
短轴
的长度(也就是椭圆形最短的那个方向的长度),同样用“**表面单位(surface unit)**”作为单位。如果触控形状是圆形,则可以忽略该事件。
表示“触控面”
b
短轴
的长度,同样用“**表面单位(surface unit)**”作为单位。如果触控形状是圆形,同样忽略该事件。
用来表示“触控区域(touch region)”的方向。该值表示以触摸中心为轴,顺时针为正方向并以 90˚ 为单位的方向值。
该值是有符号的,其范围可以任意定。但
0
应该表示“触控区域(touch region)”的方向是
Y
轴方向。负值代表方向向左旋转了(逆时针旋转),正值代表方向向右旋转了(顺时针旋转)。如果方向刚好是
X
轴方向,那么该值应该返回范围内的最大值。
默认情况下,“触控区域(touch region)”是对称的。对于能够真正进行 360˚ 定位的设备,上报的方向值必须超过最大范围,用来表示超过了 1/4 圈( 也就是 90˚)。 对于倒置的手指(即手指向下),应返回 最大范围值 * 2 。
编者注: 总感觉这段翻译的不太好,虽然能理解它的意思,但是奈何语文功底不行,感觉表达的不太好。毕竟能理解和能说明白是两回事儿。所以赋上原文:
Touch ellipsis are symmetrical by default. For devices capable of true 360 degree orientation, the reported orientation must exceed the range max to indicate more than a quarter of a revolution. For an upside-down finger, range max * 2 should be returned.
如果触控形状是圆形,或者内核驱动程序无法获取触控形状,那么可以忽略该事件。部分设备只能识别两个方向(即水平或者垂直),那么
ABS_MT_ORIENTATION
的值应该是
0
或
1
。
触摸区域压力值。单位:任意单位(arbitrary unit)。用于支持压力检测的设备或任何带有空间压力分布感应信号的设备,用来取代
前文
提到的使用
TOUCH
和
WIDTH
模拟压力值的情况。
表示触摸工具与触摸屏表面之间的距离,用“**表面单位(surface unit)**”作为单位。
数值
0
代表触摸工具已经接触屏幕。
正数
代表触摸工具正悬浮于触摸屏表面之上。
出现在“类型 B”中,“类型 A”中也有可能会出现。每一组事件数据包的结尾都会有一个
SYN_REPORT
事件,代表一组触控事件已经处理结束。前文已经讲解过。
仅出现在 “类型 A”中。每一组事件数据包的结尾都会有一个
SYN_MT_REPORT
事件,代表接收者可以接收当前的触控信息并准备开始接收下一组信息。
前文 已经详细讲解过。
如果设备上报了一个矩形形状的触控点,那么我们是无法获得它的水平方向信息的。假设
X
和
Y
代表这个触控矩形的两条边的长度,那么我们可以通过下面的公式,得到最主要的信息:
1 |
ABS_MT_TOUCH_MAJOR := max(X, Y) |
其中
ABS_MT_ORIENTATION
的值应该是
0(垂直)
或者
1(水平)
,用来表明手指是指向
Y轴(0:垂直)
还是
X轴(1:水平)
。
前文已经提到了,
ABS_MT_POSITION_X
和
ABS_MT_POSITION_Y
的值有可能不是真实的屏幕坐标值(这种情况还不少,详见“附录”中“
处理屏幕事件的输入设备
”的实测结果)。这是为什么呢?
总体来说有以下三种情况:
adb shell wm size
手动设置过手机分辨率。
以我手中的 Sony Xperia 1 III(SO-51B)[^19] 为例,该手机是 4K 屏幕,分辨率 1644 × 3840。据说分辨率是动态调整的,且系统应用都支持 4K 分辨率。但实际使用时,我发现手机都工作在 1096 × 2560 模式下,而且也没有找到设置分辨率的地方(除非使用
adb
命令强制设置成 4K)。使用
adb
命令查看该屏幕分辨率:
1 |
$ wm size |
在该手机上使用
getevent
查看输入设备信息的部分结果如下(完整结果请查看
这里
):
1 |
$ getevent -lp # Sony Xperia 1 III(SO-51B) Android 11 |
大家注意看结果里的
ABS_MT_POSITION_X
和
ABS_MT_POSITION_Y
,它们的
max
值分别是
1643
和
3839
,
min
值都是
0
,也就是
X
最大范围是 [0,1643],
Y
的最大范围是 [0,3839],刚好等于屏幕的真实分辨率 1644 × 3840,而不是实际显示用的分辨率 1096 × 2560。
当我们点击屏幕右下角时,
getevent
的运行结果如下:
1 |
$ getevent -l /dev/input/event4 # Sony Xperia 1 III(SO-51B) Android 11 |
同样的,
getevent -l
结果里的
ABS_MT_POSITION_X
和
ABS_MT_POSITION_Y
的值也是基于屏幕真实分辨率 1644 × 3840 的。例如该例中,点击屏幕右下角后,得到的
ABS_MT_POSITION_X
和
ABS_MT_POSITION_Y
坐标对应的十进制值坐标值是 (1407,3395)。
然而我们在开发 APP 时,使用的坐标值恰恰是基于实际显示时的分辨率即 1096 × 2560 的。因此这种情况下,通过
getevent
获取到的
ABS_MT_POSITION_X
和
ABS_MT_POSITION_Y
坐标值我们是不能直接使用的,需要进行一次转换。有了上述知识的了解,那么转换公式自然就好写了:
1 |
X=ABS_MT_POSITION_X*(screen width /(ABS_MT_POSITION_X(max-min+1)) |
PS:
screen width
和
screen height
代表使用 Android API 或
adb shell wm size
获取到的屏幕分辨率。例如上例中的 1096 × 2560。
将上例中
getevent
返回的 (1407,3395) 转换成程序用到的有效坐标是 (938,2263):
1 |
x=1407*(1096/1644)=938 |
3.4.0
3.16.1
[^7][^9]
Android Marshmallow
3.4.67
3.10.9
[^17]
3.10.49
[^16]
3.18.10
[^8][^9]
Android Nougat
3.18.48
4.1
4.4.0
[^9][^10]
Android Oreo
3.18.0
4.4.0
4.9.0
[^2][^3]
Android Pie
4.4.107
4.9.84
4.14.42
[^1][^2]
Android Q
android-4.9-q
android-4.14-q
android-4.19-q
[^4]
2023 年 1 月
Android R
android-4.14-stable
android-4.19-stable
android11-5.4
[^4]
2024 年 1 月
Android S/Sv2
android-4.19-stable
android11-5.4
android12-5.4
android12-5.10
[^5]
Android Tiramisu
android12-5.4
android12-5.10
android13-5.10
android13-5.15
[^5]
1 |
$ uname -r # Ubuntu 18.04.6 LTS |
1 |
$ uname -r # Android 11 |
下表是 Linux 内核 长期支持(LTS)版 的版本与发布日期。数据来自官网 The Linux Kernel Archives 。[^11]
Version Maintainer Released Projected EOL Greg Kroah-Hartman & Sasha Levin 2021-10-31 Oct, 2023 Greg Kroah-Hartman & Sasha Levin 2020-12-13 Dec, 2026 Greg Kroah-Hartman & Sasha Levin 2019-11-24 Dec, 2025 Greg Kroah-Hartman & Sasha Levin 2018-10-22 Dec, 2024 Greg Kroah-Hartman & Sasha Levin 2017-11-12 Jan, 2024
1 |
$ wm size |
下面这个示例中,
/dev/input/event4
是负责处理屏幕事件的。
1 |
$ getevent -lp # Google Pixel 7 (Pixel 7) Android 13 - kernel 5.10.107-android13-4-00003 |
1 |
$ getevent -ltr /dev/input/event4 # 单点触控 |
1 |
$ getevent -ltr /dev/input/event4 # 两点触控 |
1 |
$ wm size |
下面这个示例中,
/dev/input/event1
是负责处理屏幕事件的。
1 |
$ getevent -lp # Realme GT Neo2 (RMX3370) Android 13 - kernel 4.19.157-perf+ |
1 |
$ getevent -ltr /dev/input/event1 # 单点触控 |
1 |
$ getevent -ltr /dev/input/event1 # 两点触控 |
1 |
$ wm size |
下面这个示例中,
/dev/input/event3
是负责处理屏幕事件的。
1 |
$ getevent -lp # Google Pixel 2 XL (Pixel 2 XL) Android 11 - kernel 4.4.223 |
1 |
$ getevent -ltr /dev/input/event3 # 单点触控 |
1 |
$ wm size |
下面这个示例中,
/dev/input/event4
是负责处理屏幕事件的。
1 |
$ getevent -lp # Sony Xperia 1 III(SO-51B) Android 11 - kernel 5.4.61 |
1 |
$ getevent -ltr /dev/input/event4 # 单点触控 |
1 |
$ getevent -ltr /dev/input/event4 # 两点触控 |
1 |
$ wm size |
下面这个示例中,
/dev/input/event2
是负责处理屏幕事件的。
1 |
$ getevent -lp # OPPO Reno7 A (A201OP) Android 11 - kernel 5.4.147-qgki-g63506622819a |
1 |
$ getevent -ltr /dev/input/event2 # 单点触控 |
1 |
$ getevent -ltr /dev/input/event2 # 两点触控 |
该手机采用的是“多点触控协议 - 类型 A”。且支持“智能分辨率”:1440x3120, 1080x2340, 720x1560。
1 |
$ wm size |
下面这个示例中,
/dev/input/event5
是负责处理屏幕事件的。
注意
其执行结果中的
ABS
事件一栏,其中是没有 “
ABS_MT_SLOT
” 的。
1 |
$ getevent -lp # HuaWei Mate 20 Pro (LYA-L29) Android 10 - kernel 4.14.116 |
1 |
$ getevent -ltr /dev/input/event5 # 单点触控 |
1 |
$ getevent -ltr /dev/input/event5 # 两点触控 |
1 |
$ wm size |
下面这个示例中,
/dev/input/event3
是负责处理屏幕事件的。
注意
其执行结果中的
ABS
事件一栏,其中是没有 “
ABS_MT_SLOT
” 的。
1 |
$ getevent -lp # HuaWei Nova Lite 3 (POT-LX2J) Android 9 - 4.9.148 |
1 |
$ getevent -ltr /dev/input/event3 # 单点触控 |
1 |
$ getevent -ltr /dev/input/event3 # 两点触控 |
1 |
$ wm size |
下面这个示例中,
/dev/input/event1
是负责处理屏幕事件的。
1 |
$ getevent -lp # Samsung Galaxy S7 edge (SM-935F) Android 8.0 - kernel 3.18.91 |
1 |
$ getevent -ltr /dev/input/event1 # 单点触控 |
1 |
$ getevent -ltr /dev/input/event1 # 两点触控 |
1 |
$ wm size |
下面这个示例中,
/dev/input/event2
是负责处理屏幕事件的。
1 |
$ getevent -lp # Samsung Galaxy Note 4 S-LTE (SM-N916K) Android 6.0.1 - 3.10.9 |
1 |
$ wm size |
下面这个示例中,
/dev/input/event1
是负责处理屏幕事件的。
1 |
$ getevent -lp # OPPO A71 (2018) (CPH1801) Android 7.1.1 - 3.18.31 |
1 |
$ wm size |
下面这个示例中,
/dev/input/event1
是负责处理屏幕事件的。
1 |
$ getevent -lp # Asus ZenPad 8 (P024) Android 6.0.1 - kernel 3.10.49 |
[^1]:
Core Kernel Requirements
[^2]:
https://android.googlesource.com/platform/test/vts-testcase/kernel/+/refs/heads/pie-vts-release/lib/version.py
[^3]:
https://android.googlesource.com/platform/test/vts-testcase/kernel/+/refs/heads/oreo-vts-release/config/data/
[^4]:
Android Common Kernels
[^5]:
Feature and launch kernels
[^6]:
Android version history
[^7]:
https://forum.xda-developers.com/t/kernel-matr1x-v14-5-lollipop-5-0-5-0-1.2007231/
[^8]:
https://forum.xda-developers.com/t/rom-kernel-may-16-2020-aosp-direct-marshmallow-6-0-new-kernel-version-3-4-99.4044253/
[^9]:
https://android.stackexchange.com/a/51656
[^10]:
https://en.wikipedia.org/wiki/Android_Nougat
[^11]:
The Linux Kernel Archives
[^12]:
Android kernel 4.9 Multi-touch (MT) Protocol
[^13]:
Android kernel 4.14 Multi-touch (MT) Protocol
[^14]:
Multi-touch (MT) Protocol 英文版
,
中文版
,
中文版
[^15]: Android 官方文档
触控设备
[^16]: Asus ZenPad 8 (P024) Android 6.0.1 - kernel 3.10.49
[^17]: Samsung Galaxy Note 4 S-LTE (SM-N916K) Android 6.0.1 - kernel 3.10.9
[^18]: The mtdev project:
http://bitmath.org/code/mtdev/
[^19]: Sony Xperia 1 III(SO-51B) Android 11 - kernel 5.4.61