android键盘输出增加按键码

开发过程中免不得需要增加或减少按键码值,在android2.3系统事件处理部分,主要向上层提供统一的按键码(KeyCode),这个按键码是一个整数,在上层的JAVA程序中主要通过这个值来判断系统的实现。

关于输入事件的处理前面已经讲过,请参考:http://blog.csdn.net/andyhuabing/article/details/7006688

       这里主要讲android事件的处理过程,需要经过两个转换步骤: 

  1、键扫描码ScanCode是由linux的Input驱动框架定义的整数类型,可参考input.h头文件 

         在步骤一中将其值转换成表示按键的字符串

        键盘布局文件(*.kl)将完成第一步的转换,放在/system/usr/keylayout/下面

        举例如下:

        input.h 中字母键定义:

        #define KEY_Q 16
#define KEY_W 17
#define KEY_E 18
#define KEY_R 19
#define KEY_T 20
#define KEY_Y 21
#define KEY_U 22
#define KEY_I 23
#define KEY_O 24
#define KEY_P 25        

       而qwert.kl中定义如下:

       ScanCode + 字符串值       

      key 16    Q
key 17    W
key 18    E
key 19    R
key 20    T
key 21    Y
key 22    U
key 23    I
key 24    O
key 25    P     

   2、通过查找KEYCODES数组,将literal字符串转换成value的整型值,即转换到KeyCode值了

       片段如下,右边的值是android系统中使用的KeyCode值:(文件路径:frameworks/base/include/ui/KeycodeLabels.h)

static const KeycodeLabel KEYCODES[] = {

    ...

    { "A", 29 },
    { "B", 30 },
    { "C", 31 },
    { "D", 32 },
    { "E", 33 },
    { "F", 34 },
    { "G", 35 },
    { "H", 36 },
    { "I", 37 },
    { "J", 38 },
    { "K", 39 },
    { "L", 40 },
    { "M", 41 },
    { "N", 42 },
    { "O", 43 },
    { "P", 44 },
    { "Q", 45 },
    { "R", 46 },
    { "S", 47 },
    { "T", 48 },
    { "U", 49 },
    { "V", 50 },
    { "W", 51 },
    { "X", 52 },
    { "Y", 53 },
    { "Z", 54 },

    ...

};

   右边的值在android中定义如下:(文件路径:frameworks/base/include/android/keycodes.h

  /*
 * Key codes.
 */
enum {

     AKEYCODE_A               = 29,
    AKEYCODE_B               = 30,
    AKEYCODE_C               = 31,
    AKEYCODE_D               = 32,
    AKEYCODE_E               = 33,
    AKEYCODE_F               = 34,
    AKEYCODE_G               = 35,
    AKEYCODE_H               = 36,
    AKEYCODE_I               = 37,
    AKEYCODE_J               = 38,
    AKEYCODE_K               = 39,
    AKEYCODE_L               = 40,
    AKEYCODE_M               = 41,
    AKEYCODE_N               = 42,
    AKEYCODE_O               = 43,
    AKEYCODE_P               = 44,
    AKEYCODE_Q               = 45,
    AKEYCODE_R               = 46,
    AKEYCODE_S               = 47,
    AKEYCODE_T               = 48,
    AKEYCODE_U               = 49,
    AKEYCODE_V               = 50,
    AKEYCODE_W               = 51,
    AKEYCODE_X               = 52,
    AKEYCODE_Y               = 53,
    AKEYCODE_Z               = 54,

   ..

};

   这里的键值与KeyEvent.java中的值是对应的:(文件路径:frameworks/base/core/java/android/view/KeyEvent.java)

      /** Key code constant: 'A' key. */
    public static final int KEYCODE_A               = 29;
    /** Key code constant: 'B' key. */
    public static final int KEYCODE_B               = 30;
    /** Key code constant: 'C' key. */
    public static final int KEYCODE_C               = 31;
    /** Key code constant: 'D' key. */
    public static final int KEYCODE_D               = 32;
    /** Key code constant: 'E' key. */
    public static final int KEYCODE_E               = 33;
    /** Key code constant: 'F' key. */
    public static final int KEYCODE_F               = 34;
    /** Key code constant: 'G' key. */
    public static final int KEYCODE_G               = 35;
    /** Key code constant: 'H' key. */
    public static final int KEYCODE_H               = 36;
    /** Key code constant: 'I' key. */
    public static final int KEYCODE_I               = 37;
    /** Key code constant: 'J' key. */
    public static final int KEYCODE_J               = 38;
    /** Key code constant: 'K' key. */
    public static final int KEYCODE_K               = 39;
    /** Key code constant: 'L' key. */
    public static final int KEYCODE_L               = 40;
    /** Key code constant: 'M' key. */
    public static final int KEYCODE_M               = 41;
    /** Key code constant: 'N' key. */
    public static final int KEYCODE_N               = 42;
    /** Key code constant: 'O' key. */
    public static final int KEYCODE_O               = 43;
    /** Key code constant: 'P' key. */
    public static final int KEYCODE_P               = 44;
    /** Key code constant: 'Q' key. */
    public static final int KEYCODE_Q               = 45;
    /** Key code constant: 'R' key. */
    public static final int KEYCODE_R               = 46;
    /** Key code constant: 'S' key. */
    public static final int KEYCODE_S               = 47;
    /** Key code constant: 'T' key. */
    public static final int KEYCODE_T               = 48;
    /** Key code constant: 'U' key. */
    public static final int KEYCODE_U               = 49;
    /** Key code constant: 'V' key. */
    public static final int KEYCODE_V               = 50;
    /** Key code constant: 'W' key. */
    public static final int KEYCODE_W               = 51;
    /** Key code constant: 'X' key. */
    public static final int KEYCODE_X               = 52;
    /** Key code constant: 'Y' key. */
    public static final int KEYCODE_Y               = 53;
    /** Key code constant: 'Z' key. */
    public static final int KEYCODE_Z               = 54;

    ...

      如果改动了这里,影响到API则需要调用make update-api

ok,理清楚了以上的转换关系,下面就说一下如何增加按键,以增加gamekey为例:

1 、键盘布局文件中增加键,一般是qwery.kl (一定是以*.kl结尾的文件):

  key 304 BUTTON_A 

  key 305 BUTTON_B

  key 306 BUTTON_C

  key 307 BUTTON_X

  key 308 BUTTON_Y

  key 309 BUTTON_Z

  key 315 BUTTON_START

  key 316 BUTTON_MODE


2、在frameworks/base/include/ui/KeycodeLabels.h中增加KeycodeLabel类型的Code数组

    { "BUTTON_A", 96 },
    { "BUTTON_B", 97 },
    { "BUTTON_C", 98 },
    { "BUTTON_X", 99 },
    { "BUTTON_Y", 100 },
    { "BUTTON_Z", 101 },

    { "BUTTON_START", 108 },

    { "BUTTON_MODE", 110 },      

    目前的2.3系统已经添加


  3、在frameworks/base/include/android/keycodes.h中增加KeyCode的枚举值

    AKEYCODE_BUTTON_A        = 96,
    AKEYCODE_BUTTON_B        = 97,
    AKEYCODE_BUTTON_C        = 98,
    AKEYCODE_BUTTON_X        = 99,
    AKEYCODE_BUTTON_Y        = 100,
    AKEYCODE_BUTTON_Z        = 101,

    AKEYCODE_BUTTON_START    = 108,
    AKEYCODE_BUTTON_MODE     = 110,   

     目前的2.3系统已经添加


4、JAVA层的keyEvent.java中增加用于java应用程序使用

     略,目前的2.3系统已经添加


5、在frameworks\base\core\res\res\values\attrs.xml中增加表示属性的资源文件,添加相应用name="keycode"的attr

        

        

        

        

        

        

        

        


ok,完成以上步骤应该就可以使用了。


查找key是否有没有被过滤掉重点确认的地方:

1、EventHub.cpp 文件中的getEvent函数

    if (iev.type == EV_KEY) {
               status_t err = device->layoutMap->map(iev.code,
                         & outEvent->keyCode, & outEvent->flags);
               LOGV("iev.code=%d keyCode=%d flags=0x%08x err=%d\n",
                          iev.code, outEvent->keyCode, outEvent->flags, err);
               if (err != 0) {
                      outEvent->keyCode = AKEYCODE_UNKNOWN;
                       outEvent->flags = 0;
               }

       }

    确认这里转换是否ok了,如果没有则可能*.kl文件中没有添加进去这个键值 


2、InputReader.cpp文件中的KeyboardInputMapper处理函数process

    void KeyboardInputMapper::process(const RawEvent* rawEvent) {
    switch (rawEvent->type) {
    case EV_KEY: {
        int32_t scanCode = rawEvent->scanCode;
        if (isKeyboardOrGamepadKey(scanCode)) {
            processKey(rawEvent->when, rawEvent->value != 0, rawEvent->keyCode, scanCode,
                    rawEvent->flags);
        }
        break;
    }
    }
}

bool KeyboardInputMapper::isKeyboardOrGamepadKey(int32_t scanCode) {
    return scanCode < BTN_MOUSE
        || scanCode >= KEY_OK
        || (scanCode >= BTN_GAMEPAD && scanCode < BTN_DIGI);
}


可以在processKey中加打印,确认已通过notifyKey上报键值给android系统了。

 

附加,如何编译生成qwerty.kcm.bin 文件:

android为了减少载入时间,并没有使用原始按键表文件,而是将其转换成二进制文件
转换的工具源代码在android源代码build/tools/kcm目录下,android在编译过程中会
首先编译转换工具,然后利用转换工具将qwerty.kcm文件转换成qwerty.kcm.bin

转换后的二进制文件复制到out/target/product//system/usr/keychars
目录下,也就是目标平台的/system/usr/keychars目录中。

用法:

static int usage()
{
    fprintf(stderr,
            "usage: kcm INPUT OUTPUT\n"
            "\n"
            "INPUT   keycharmap file\n"
            "OUTPUT  compiled keycharmap file\n"
        );
    return 1;
}

 

你可能感兴趣的:(Android系统框架学习)