Android下实现触摸屏上的按键

前段时间在电容触摸屏上实现了触摸按键的功能,刚接手的时候一点头绪都没有,后来看了韩超的文章才慢慢理清原理(韩超何许人物?买过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

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwjyyz.html