1.处理的内容和流程触摸屏和轨迹球上报的是坐标、按下、抬起等信息,信息量比较少。按键处理的过程稍微复杂,从驱动程序到Android的Java层受到的信息,键表示方式经过了两次转化,按键扫描码Scancode-->按键标签KeycodeLabel-->按键码Keycode键扫描码Scancode是由Linux的Input驱动框架定义的整数类型。键扫描码Scancode经过一次转化后,形成按键的标签KeycodeLabel,是一个字符串的表示形式。按键的标签KeycodeLabel经过转换后,再次形成整数型的按键码keycode。在Android应用程序层,主要使用按键码keycode来区分。
在本地框架层libui的头文件中KeycodeLabels.h,按键码为整数值的格式,其定义KeyCode(枚举值)如下所示:1.   typedef enum KeyCode { 2.       kKeyCodeUnknown = 0, 3.       kKeyCodeSoftLeft = 1, 4.       kKeyCodeSoftRight = 2, 5.       kKeyCodeHome = 3, 6.       kKeyCodeBack = 4, 7.   // ...... 省略中间按键码 8.   } KeyCode; 进而在定义了KeycodeLabels.h中定义了从字符串到整数的映射关系,数组KEYCODES,定义如下所示:1.   static const KeycodeLabel KEYCODES[] = {    // {字符串,整数} 2.       { "SOFT_LEFT", 1 }, 3.       { "SOFT_RIGHT", 2 }, 4.       { "HOME", 3 }, 5.       { "BACK", 4 }, 6.       { "CALL", 5 }, 7.       { "ENDCALL", 6 }, 8.       { "0", 7 },                              // ...... 数字按键 9.       { "1", 8 }, 10.      { "2", 9 }, 11.      { "3", 10 }, 12.      { "4", 11 }, 13.      { "5", 12 }, 14.      { "6", 13 }, 15.      { "7", 14 }, 16.      { "8", 15 }, 17.      { "9", 16 }, 18.      { "STAR", 17 }, 19.  // ...... 省略中间按键映射 20.      { "MENU", 82 }, 21.  // ...... 省略中间按键映射 22.      { NULL, 0 } 23.  }; 数组KEYCODES表示的映射关系,左列的内容即表示按键标签KeyCodeLabel,右列的内容为按键码KeyCode(与KeyCode的数值对应)。实际上,在按键信息第二次转化的时候就是将字符串类型KeyCodeLabel转化成整数的KeyCode。KeycodeLabel的Flags的定义如下所示:1.   static const KeycodeLabel FLAGS[] = { 2.       { "WAKE", 0x00000001 },                  // 可以唤醒睡眠,并通知应用层 3.       { "WAKE_DROPPED", 0x00000002 },          // 可以唤醒睡眠,不通知应用层 4.       { "SHIFT", 0x00000004 },                 // 自动附加SHIFT 5.       { "CAPS_LOCK", 0x00000008 },             // 自动附加CAPS_LOCK 6.       { "ALT", 0x00000010 },                   // 自动附加ALT 7.       { "ALT_GR", 0x00000020 }, 8.       { "MENU", 0x00000040 }, 9.       { "LAUNCHER", 0x00000080 }, 10.      { NULL, 0 } 11.  }; KeycodeLabel表示按键的附属标识。 提示:frameworks/base/core/Java/android/view/KeyEvent.Java中定义了类android.view. KeyEvent类,其中定义整数类型的数值与KeycodeLabels.h中定义的KeyCode枚举值是对应的。在本地框架层libui的头文件中KeyCharacterMap.h,定义了按键的字符映射关系,KeyCharacterMap类的定义如下所示:1.   class KeyCharacterMap 2.   { 3.   public: 4.       ~KeyCharacterMap(); 5.       unsigned short get(int keycode, int meta); 6.       unsigned short getNumber(int keycode); 7.       unsigned short getMatch(int keycode, const unsigned short* chars, 8.                               int charsize, uint32_t modifiers); 9.       unsigned short getDisplayLabel(int keycode); 10.      bool getKeyData(int keycode, unsigned short *displayLabel, 11.                      unsigned short *number, unsigned short* results); 12.      inline unsigned int getKeyboardType() { return m_type; } 13.      bool getEvents(uint16_t* chars, size_t len, 14.                     Vector<int32_t>* keys, Vector<uint32_t>* modifiers); 15.      static KeyCharacterMap* load(int id); 16.      enum { 17.          NUMERIC = 1, 18.          Q14 = 2, 19.          QWERTY = 3              // or AZERTY or whatever 20.      }; 21.  } KeyCharacterMap用于将按键的码映射为文本可识别的字符串(例如,显示的标签等)。KeyCharacterMap是一个辅助的功能:由于按键码只是一个与UI无关整数,通常用程序对其进行捕获处理,然而如果将按键事件转换为用户可见的内容,就需要经过这个层次的转换了。KeyCharacterMap需要从本地层传送到Java层,JNI的代码路径如下所示:frameworks/base/core/jni/android_text_KeyCharacterMap.cppKeyCharacterMap Java框架层次的代码如下所示:frameworks/base/core/Java/android/view/KeyCharacterMap.Javaandroid.view.KeyCharacterMap类是Android平台的API可以在应用程序中使用这个类。android.text.method中有各种Linstener,可以之间监听KeyCharacterMap相关的信息。DigitsKeyListener NumberKeyListener TextKeyListener。以上关于按键码和按键字符映射的内容是在代码中实现的内容,还需要配合动态的配置文件来使用。在实现Android系统的时候,有可能需要更改这两种文件。动态的配置文件包括:  KL(Keycode Layout):后缀名为kl的配置文件
  KCM(KeyCharacterMap):后缀名为kcm的配置文件
Donut及其之前配置文件的路径为:development/emulator/keymaps/Eclair及其之后配置文件的路径为:sdk/emulator/keymaps/这些配置文件经过系统生成后,将被放置在目标文件系统的/system/usr/keylayout/目录或者/system/usr/keychars/目录中。 提示:kl文件将被直接复职到目标文件系统中;由于尺寸较大,kcm文件放置在目标文件系统中之前,需要经过压缩处理。KeyLayoutMap.cpp负责解析处理kl文件,KeyCharacterMap.cpp负责解析kcm文件。