好久没更新博客了,之前工作比较忙,现在要把研究过的东西逐一记录下来。前段时间在电容触摸屏上实现了触摸按键的功能,刚接手的时候一点头绪都没有,后来看了韩超的文章才慢慢理清原理(韩超何许人物?买过Android开发书籍的人应该不会陌生吧),原来从Android 2.1版本后框架层代码就提供了虚拟按键机制。
下面将介绍如何实现触摸式按键:
1.硬件分析
我所使用的触摸屏分辨率是1158*768,可视区域大小是1024*768(这也是LCD屏的大小),在触摸屏两侧总有5个按键。
2.触摸屏按键驱动的修改
既然可视区域在触摸屏中间部位,因此需要在触摸屏驱动中修改input_set_abs_params()函数中的参数
- input_set_abs_params(input_dev, ABS_MT_POSITION_X, 61, 1085, 0, 0);
- input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, SCREEN_MAX_Y, 0, 0);
其中61是可视区域左侧x轴左边坐标,1085是右侧的。
3.Android框架层
Android上层通过读取触摸屏坐标并经过转算后来识别定义好的虚拟按键,代码位于frameworks/base/services/java/com/android/server/KeyInputQueue.java中:
static class Virtualkey{}是负责按键定位的方法;
private void readVirtualKeys(String deviceName)负责读取sys文件,这是最重要的代码,也是与底层sys文件系统沟通的桥梁,它会读取/sys/board_properties/virtualkeys.{deviceName}文件,deviceName一定要与触摸屏设备名称一致,不然会找不到指定的sys文件。
4.sys文件系统
前面讲到了readVirtualKeys会读取sys文件,这个sys文件就是定义虚拟按键的坐标以及键值,它的协议格式是一段字符串,每个按键有六项分别用冒号分割,按键按键之间也是用冒号分割,标准格式是:
键类型:键值:按键区域中心x坐标:按键区域中心y坐标:按键区域宽:按键区域高
创建sys文件的代码:
- #ifdef VIRTUAL_KEYS
- static ssize_t virtual_keys_show(struct kobject *kobj,
- struct kobj_attribute *attr, char *buf)
- {
- if (1) {
-
- return sprintf(buf,
- __stringify(EV_KEY) ":" __stringify(KEY_VOLUMEUP) ":1030:370:30:30"
- ":" __stringify(EV_KEY) ":" __stringify(KEY_VOLUMEDOWN) ":1030:470:30:30"
- ":" __stringify(EV_KEY) ":" __stringify(KEY_BACK) ":1030:18:30:30"
- ":" __stringify(EV_KEY) ":" __stringify(KEY_HOME) ":1030:136:30:30"
- ":" __stringify(EV_KEY) ":" __stringify(KEY_MENU) ":1030:236:30:30"
- "\n");
- } else {
- }
- }
- static struct kobj_attribute virtual_keys_attr = {
- .attr = {
- .name = "virtualkeys.xxxx",
- .mode = S_IRUGO,
- },
- .show = &virtual_keys_show,
- };
- static struct attribute *properties_attrs[] = {
- &virtual_keys_attr.attr,
- NULL
- };
- static struct attribute_group properties_attr_group = {
- .attrs = properties_attrs,
- };
- static void virtual_keys_init(void)
- {
- int ret;
- struct kobject *properties_kobj;
-
- properties_kobj = kobject_create_and_add("board_properties", NULL);
- if (properties_kobj)
- ret = sysfs_create_group(properties_kobj,
- &properties_attr_group);
- if (!properties_kobj || ret)
- pr_err("failed to create board_properties\n");
- }
- #endif
其中.name = "virtualkeys.xxxx"的xxxx就是触摸屏设备名称,也就是前面说到的{deviceName},virtual_keys_init()函数可以在触摸屏probe函数中调用。另外,我将可视区域左侧的两侧按键移到了右侧实现,因此五个按键区域中心x坐标都是一样,这部分要在触摸屏驱动增加x轴坐标调整,这部分我就不再说明。
以上步骤完成后可以使用 cat /sys/board_properties/virtualkeys.{deviceName}查看虚拟按键的配置文件,并试试按下触摸屏上按键是否有反应,如果坐标不正确还要进行耐心地校准。
阅读(2177) | 评论(0) | 转发(0) |