Android平台开发-Android keypad map-Android按键识别及映射过程

一、Android底层按键事件处理过程    在系统启动后,在文件。。。中,android 会通过    static const char *device_path = "/dev/input"; 
    bool EventHub::penPlatformInput(void) 
    res = scan_dir(device_path);    通过下面的函数打开设备。
    int EventHub::pen_device(const char *deviceName) 
    { 
      ... 
      fd = open(deviceName, O_RDWR); 
      ...  
      mFDs[mFDCount].fd = fd; 
      mFDs[mFDCount].events = POLLIN; 
      ... 
      ioctl(mFDs[mFDCount].fd, EVIOCGNAME(sizeof(devname)-1), devname); 
      ... 
      const char* root = getenv("ANDROID_ROOT"); 
      snprintf(keylayoutFilename, sizeof(keylayoutFilename), 
                 "%s/usr/keylayout/%s.kl", root, tmpfn); 
      ... 
      device->layoutMap->load(keylayoutFilename); 
      ... 
  }  打开设备的时候,如果 device->classes&CLASS_KEYBOARD 不等于 0 表明是键盘。 
  常用输入设备的定义有: 
  enum { 
        CLASS_KEYBOARD      = 0x00000001, //键盘 
        CLASS_ALPHAKEY      = 0x00000002, // 
        CLASS_TOUCHSCREEN   = 0x00000004, //触摸屏 
        CLASS_TRACKBALL     = 0x00000008  //轨迹球 
  };  打开键盘设备的时候通过上面的 ioctl 获得设备名称,命令字 EVIOCGNAME 的定义在文件:    kernel/include/linux/input.h 中。
  对于按键事件,调用mDevices->layoutMap->map进行映射,调用的是文件 KeyLayoutMap.cpp  (frameworks\base\libs\ui)中的函数:
  status_t KeyLayoutMap::load(const char* filename)通过解析 <Driver name>.kl 把按键的  映射关系保存在 :KeyedVector<int32_t,Key> m_keys; 中。  当获得按键事件以后调用: status_t KeyLayoutMap::map(int32_t scancode, int32_t  *keycode, uint32_t *flags)
  由映射关系 KeyedVector<int32_t,Key> m_keys 把扫描码转换成andorid上层可以识别的按键。
二、按键映射   Key layout maps的路径是 /system/usr/keylayout,第一个查找的名字是按键驱动的名字,例如  mxckpd.kl。如果没有的话,默认为qwerty.kl。
  Key character maps的路径是 /system/usr/keychars,第一个查找的名字是按键驱动的名字,例如  mxckpd.kcm。如果没有的话,默认为qwerty.kl。
  
  qwerty.kl是 UTF-8类型的,格式为:key SCANCODE KEYCODE [FLAGS...]。
  
  SCANCODE表示按键扫描码;
  KEYCODE表示键值,例如HOME,BACK,1,2,3...
  FLAGS有如下定义:
    SHIFT: While pressed, the shift key modifier is set 
    ALT: While pressed, the alt key modifier is set 
    CAPS: While pressed, the caps lock key modifier is set 
    WAKE: When this key is pressed while the device is asleep, the device will                  wake up and the key event gets sent to the app. 
    WAKE_DROPPED: When this key is pressed while the device is asleep, the device                  will wake up and the key event does not get sent to the app
  
  qwerty.kcm文件为了节省空间,在编译过程中会用工具makekcharmap转化为二进制文件qwerty.bin。三、按键分发   1、输入事件分发线程
  
    在frameworks/base/services/java/com/android/server/WindowManagerService.java里创    建了一个输入事件分发线程,它负责把事件分发到相应的窗口上去。
    
    在WindowManagerService类的构造函数WindowManagerService()中:
        mQueue = new KeyQ(); //读取按键
        mInputThread = new InputDispatcherThread();  //创建分发线程     
        ...     
        mInputThread.start();
      
    在启动的线程InputDispatcherThread中:
        run() 
        process(); 
        QueuedEvent ev = mQueue.getEvent(...) 
      
      在process() 方法中进行处理事件:
        switch (ev.classType) 
          case RawInputEvent.CLASS_KEYBOARD: 
             ... 
             dispatchKey((KeyEvent)ev.event, 0, 0); 
             mQueue.recycleEvent(ev); 
             break; 
          case Raw
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhengmeifu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值