Android Input子系统-含实例源码

前言

话说东哥

最近东哥应该是比较热门的,我每天吃饭前都会打开今天头条,跟同事交流一下我的大兄弟东哥事情的进展,我谋划着要去米国为东哥加油,东哥作为一个有道德心的企业家,从一个贫苦的农村出来,迎娶白富美,走上人生巅峰的励志故事一直是我等屌丝的楷模和榜样。

我认为诚信是一个人的基础,如果你去买鸡,老板给你说 10 块钱一斤,你准备拿手机扫码支付的时候,老板看见我用的是 IPhone X ,认为我是有钱人,然后坐地起价,变成 20 块钱一斤,这样的老板是非常不诚信,也是非常不道德的。

 

毕业季

最近是秋招季节,很多人都准备着找实习机会,想起来当时在校园招聘的时候面试了很多家企业,直到最后拿到 TCL offer 才让我心满意足停止了找工作的步伐。我觉得作为应届生,一定要想清楚自己以后的路子。

   

      1 、找准第一份工作,第一份工作决定你未来很多年,换行业需要很大的代价和努力。

    2 、找准企业,很多人需要一个好的企业背景来托起自己职业生涯的起点

 

 

有同学问是应该往底层 Linux 内核发展还是做应用开发,往底层发展,会接触到比较少的业务逻辑,可以让你在某个方面越来越突出,成为业界的专家,往上层发展比如 APP ,后台,互联网方面,会让你接触越来越多的业务,接触的面也会越来越大。没有说哪个更好,一定先从自己的兴趣出发,没有兴趣很难坚持。

   

 正文

现在说说 Android Input 子系统,因为发现在微信公众号上写文章有挺多不方便,我现在有些篇幅比较长,或者后期需要修改的文章,会写在 CSDN 上,大家可以点击阅读原文来阅读,这样也方便大家阅读和收藏。

 

 

1 Input 子系统作用

Android 很多外设都是用到输入输出设备,比如 touchscreen ,键盘,音量键等,输入

设备对应 Android  框架是 Android input 子系统,像我们定制类比较多的,很多  

需要用到输入子系统,比如一键打开相机,一键唤醒,实体按键等。

2 Android input 子系统框架

Android Input 框架讲解最好的一篇文章  

https://blog.csdn.net/mmmccc000/article/details/49756059 

Android input 框架主要分为三个部分,一个是 kernel ,一个是 kl 文件, kl 也可  

以划分为框架层, Framework 层主要做监听、过滤、分发的工作, Android App  

分主要是接收 Input 子系统发上来的键值做对应的操作。

3 kernel input 框架

Kernel 主要是涉及 Input 设备节点的生成, proc 文件系统的生成

有一个文章写 Kernel 框架非常好的,我就不再讲了,给几个链接  

https://blog.csdn.net/u013604527/article/details/53432623/ 

https://blog.csdn.net/jscese/article/details/42123673 

https://blog.csdn.net/xubin341719/article/details/7881735

如何在 kernel 添加一个新的键值

4.1  先在头文件里面添加

找个共用的头文件添加要的 key 值,正常是在 include 下面的,我的代码是在这个位  

diff --git a/include/uapi/linux/input- event -codes.h b/include/uapi/linux/input- event -codes.h

index  87 cf351. .45 a33ab  100644

--- a/include/uapi/linux/input- event -codes.h

+++ b/include/uapi/linux/input- event -codes.h

@@  -335 , 7  + 335 , 7  @@

  #define KEY_RFKILL             247     /* Key that controls all radios */

 

  #define KEY_MICMUTE            248     /* Mute / unmute the microphone */

-

+ #define KEY_WEIQIFA_TEST 249

  /* Code 255 is reserved for special needs of AT keyboard driver */

4.2  kernel 对应的位置注册和发送键值

注册的位置

 

  /* 包含头文件 */

     #include 

     /* 声明 input 设备 */

    struct input_dev *button_dev;

     /* 注册 input  子设备 */

 

    printk(KERN_ERR  " xxxx_wake_init\n" );

     if  (!(button_dev= input_allocate_device()))

    {   

        printk(KERN_ERR  "input_dev: not enough memory\n" );

         return  -ENOMEM;

    }   

    button_dev->name =  "xxxx" ;

    button_dev->phys =  "xxxx/event0" ;

    button_dev->id.bustype = BUS_HOST;

    button_dev->id.vendor  =  0x0001 ;

    button_dev->id.product =  0x0002 ;

    button_dev->id.version =  0x0100 ;

    button_dev->evbit[ ] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_SYN);

 

    set_bit(KEY_WEIQIFA_TEST,button_dev->keybit);

 

    err = input_register_device(button_dev);

     if  (err) {

        printk(KERN_ERR  " fail to input_register_device\n" );

        input_free_device(button_dev);

         return  err;

    }   

 

    printk(KERN_ERR  "xxxx_wake_init success!!!\n" );

 

     return   ;

 

发送键值的位置

 input_report_key(button_dev, KEY_WEIQIFA_TEST, 1);

 input_sync(button_dev);

 input_report_key(button_dev, KEY_WEIQIFA_TEST, 0);

 input_sync(button_dev);

4.3  写一个对应这个 kl 文件

kl 文件简单介绍

Kl 文件主要是起到了承上启下的作用, kernel 发过来的键值主要通过 kl 文件来映  

射,我们来看看 kl 文件里面的内容把。左边的是对应 kernel 上报上来的键值,后  

面是对应 Android Framework 上的键值。

  22   key   399    GRAVE

  23   key   2       1

 ...

  49   key   103    DPAD_UP

  50   key   102    HOME

  51   key   105    DPAD_LEFT

  52   key   106    DPAD_RIGHT

  53   key   115    VOLUME_UP

kl 文件哪里来的呢

我们看项目配置下面,有很多 kl 文件,那么是每个 input 子系统对应一个 kl 文件,  

还是所有的项目共用一个 kl 文件?  

kl 源码位置在

./frameworks/ base /data/keyboards/AVRCP.kl

./frameworks/ base /data/keyboards/G

./frameworks/ base /data/keyboards/Vendor_0079_Product_0011.kl

./frameworks/ base /data/keyboards/Vendor_045e_Product_028e.kl...

在运行的设备里,它的位置如下

rk3399_mid:/ # busybox find / -iname *.kl

/ system /usr/keylayout/Generic.kl

/ system /usr/keylayout/Vendor_0079_Product_0011.kl

/ system /usr/keylayout/qwerty.kl

/ system /usr/keylayout/rk29-keypad.kl

/ system /usr/keylayout/rtkbt_virtual_hid.kl...

rk3399_mid:/ #

kl 是跟 input 设备如何对应起来的呢

我们可以用这个命令来看看   cat /proc/bus/input/devices  

kl 文件里面的 vendor product 分别对应下面的 vendor product

rk3399_mid:/ # cat /proc/bus/input/devices

I: Bus=0019 Vendor=0001 Product=0002 Version=0100

N: Name="xxxx"

P: Phys=iflytek/event0

S: Sysfs=/devices/virtual/input/input0

U: Uniq=

H: Handlers=event0 cpufreq

B: PROP=0

B: EV=b

B: KEY=100000 0 0 0

B: ABS=0

添加我们对应的 kl 文件  

文件命名跟你申请的 vendor product 对应 上面的 input 设备对应的 kl 文件应该是: Vendor_0001_Product_0002.kl  

里面的内容如下,当然如果你没有配置 kl 文件,默认会去 Generic.kl 找键值映  

射,如果里面也没有,就会去其他 kl 文件继续找。

# OnLive, Inc. OnLive Wireless Controller

key   249  BUTTON_A

4.4 mtk 平台的一个 input  子系统驱动例子

上面写的是在 rockchip 平台做的例子,下面给出一个 mtk 平台的例子  

[mkt 平台的 input 子系统例子

(https://blog.csdn.net/weiqifa0/article/details/50387504)

5 Framework input 系统介绍

Framework 主要做的事情是监听底层的 input ,然后分发给上层  

下面的两个链接框架说的非常好,可以看看,我下面给出步骤如何添加一个新的 key 

到系统里面  

https://blog.csdn.net/wangkaiblog/article/details/12085183 

https://blog.csdn.net/mmmccc000/article/details/49756059

添加一个新的键值

主要涉及到几个文件位置  

下面列出需要修改的文件还有修改的差异点  

base/api/current.txt 

base/api/system-current.txt 

base/core/java/android/view/KeyEvent.java 

base/core/res/res/values/attrs.xml 

/ Generic.kl 这里也可以根据驱动添加

base/data/keyboards/Generic.kl 

base/policy/src/com/android/internal/policy/impl/PhoneFallbackEventHandler.java 

native/include/android/keycodes.h 

native/include/input/InputEventLabels.h

diff --git a/api/current.txt b/api/current.txt

index  63 fa997..a7a4a2b  100644

--- a/api/current.txt

+++ b/api/current.txt

@@  -41599 , 6  + 41599 , 7  @@ package android.view {

     field  public   static   final  int KEYCODE_ASSIST =  219 // 0xdb

     field  public   static   final  int KEYCODE_AT =  77 // 0x4d

     field  public   static   final  int KEYCODE_AUDIO =  314 // 0x13a

+    field  public   static   final  int KEYCODE_WEIQIFA =  315 // 0x13B

     field  public   static   final  int KEYCODE_AVR_INPUT =  182 // 0xb6

     field  public   static   final  int KEYCODE_AVR_POWER =  181 // 0xb5

     field  public   static   final  int KEYCODE_B =  30 // 0x1e

diff --git a/api/system-current.txt b/api/system-current.txt

index  19135 aa. .956 ea3e  100644

--- a/api/system-current.txt

+++ b/api/system-current.txt

@@  -44781 , 6  + 44781 , 7  @@ package android.view {

     field  public   static   final  int KEYCODE_ASSIST =  219 // 0xdb

     field  public   static   final  int KEYCODE_AT =  77 // 0x4d

     field  public   static   final  int KEYCODE_AUDIO =  314 // 0x13a

+    field  public   static   final  int KEYCODE_WEIQIFA =  315 // 0x13b

     field  public   static   final  int KEYCODE_AVR_INPUT =  182 // 0xb6

     field  public   static   final  int KEYCODE_AVR_POWER =  181 // 0xb5

     field  public   static   final  int KEYCODE_B =  30 // 0x1e

diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java

index  056 f2c9..f2d5235  100755

--- a/core/java/android/view/KeyEvent.java

+++ b/core/java/android/view/KeyEvent.java

@@  -832 , 6  + 832 , 7  @@  public   class   KeyEvent   extends   InputEvent   implements   Parcelable  {

      public   static   final  int KEYCODE_TV_MEDIA_PAUSE =  304 ;

      public   static   final  int KEYCODE_WLAN           =  313 ;

      public   static   final  int KEYCODE_AUDIO          =  314 ;

+     public   static   final  int KEYCODE_WEIQIFA          =  315 ;

  //$_rbox_$_modify_$ end

 

      private   static   final  int LAST_KEYCODE = KEYCODE_TV_MEDIA_PAUSE;

diff --git a/core/java/com/android/internal/policy/PhoneFallbackEventHandler.java b/core/java/com/android/internal/policy/PhoneFallbackEventHandler.java

index e6635a1. .366790 100755

--- a/core/java/com/android/internal/policy/PhoneFallbackEventHandler.java

+++ b/core/java/com/android/internal/policy/PhoneFallbackEventHandler.java

@@  -141 , 7  + 141 , 12  @@  public   class   PhoneFallbackEventHandler   implements   FallbackEventHandler  {

             }

              case  KeyEvent.KEYCODE_AUDIO: {

                 Log.i(TAG,  "---KEYCODE_AUDIO DOWN---" );

+       

             }

+             case  KeyEvent.KEYCODE_WEIQIFA: {

+                Log.i(TAG, "KEYCODE_WEIQIFA" );

+            }

+           

 

              case  KeyEvent.KEYCODE_CAMERA: {               

                  if  (getKeyguardManager().inKeyguardRestrictedInputMode() || dispatcher ==  null ) {

diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml

index  93743 df. .094e6 c2  100755

--- a/core/res/res/values/attrs.xml

+++ b/core/res/res/values/attrs.xml

@@  -1861 , 6  + 1861 , 7  @@ i

          "KEYCODE_MICMUTE"  value= "312"  />

          "KEYCODE_WLAN"  value= "313"  />

          "KEYCODE_AUDIO"  value= "314"  />

+         "KEYCODE_WEIQIFA"  value= "315"  />

     

 

     

 

 

 

diff --git a/ include /android/keycodes.h b/ include /android/keycodes.h

index e3586b2..b657424  100755

--- a/ include /android/keycodes.h

+++ b/ include /android/keycodes.h

@@  -777 , 6  + 777 , 7  @@ enum {

     AKEYCODE_MICMUTE            =  312 ,

     AKEYCODE_WLAN               =  313 ,

     AKEYCODE_AUDIO              =  314

+    AKEYCODE_WEIQIFA              =  315

 

      // NOTE: If you add a new keycode here you must also add it to several other files.

      //       Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list.

diff --git a/ include /input/InputEventLabels.h b/ include /input/InputEventLabels.h

index fabf912. .1 cd69a2  100755

--- a/ include /input/InputEventLabels.h

+++ b/ include /input/InputEventLabels.h

@@  -68 , 6  + 68 , 7  @@  static   const  InputEventLabel KEYCODES[] = {

     DEFINE_KEYCODE(POWER),

     DEFINE_KEYCODE(WLAN),

     DEFINE_KEYCODE(AUDIO),

+    DEFINE_KEYCODE(WEIQIFA),

     DEFINE_KEYCODE(CAMERA),

     DEFINE_KEYCODE(CLEAR),

     DEFINE_KEYCODE(A),

如果出现以下编译错误

out/target/common/obj/PACKAGING/test-api.txt:41961: error 5: Added public field android.view.KeyEvent.KEYCODE_WEIQIFA

 

******************************

You have tried to change the API from what has been previously approved.

To make these errors go away, you have two choices:

   1) You can add "@hide" javadoc comments to the methods, etc. listed in the

      errors above.

   2) You can update current.txt by executing the following command:

      make update-api

      To submit the revised current.txt to the main Android repository,

      you will need approval.

******************************

提示你运行 make update-api ,但是要先回退 current.txt  system-current.txt ,因为这两个文件就是 make update-api 生成出来的

git  checkout api/current.txt 

git checkout api/system-current.txt

make update-api

关于 make update-api 详细看这个 https://blog.csdn.net/u010229714/article/details/73840014

如果需要调试,可以打开下面的调试文件

--- a/services/core/java/com/android/server/input/InputManagerService.java

+++ b/services/core/java/com/android/server/input/InputManagerService.java

@@  -125 , 7  + 125 , 7  @@  import  libcore.util.Objects;

  public   class   InputManagerService   extends   IInputManager . Stub

          implements   Watchdog . Monitor  {

      static  final String TAG =  "InputManager" ;

-     static  final boolean DEBUG =  false ;

+     static  final boolean DEBUG =  true ;

 

      private   static  final String EXCLUDED_DEVICES_PATH =  "etc/excluded-input-devices.xml" ;

 

--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java

+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java

@@  -172 , 7  + 172 , 7  @@  public   class   PhoneWindowManager   implements   WindowManagerPolicy  {

      static  final String TAG =  "WindowManager" ;

      static  final boolean DEBUG =  false ;

      static  final boolean localLOGV =  false ;

-     static  final boolean DEBUG_INPUT =  false ;

+     static  final boolean DEBUG_INPUT =  true ;

      static  final boolean DEBUG_KEYGUARD =  false ;

      static  final boolean DEBUG_LAYOUT =  false ;

      static  final boolean DEBUG_STARTING_WINDOW =  false ;

--- a/services/inputflinger/InputDispatcher.cpp

+++ b/services/inputflinger/InputDispatcher.cpp

@@  -17 , 31  + 17 , 31  @@

  #define LOG_TAG "InputDispatcher"

  #define ATRACE_TAG ATRACE_TAG_INPUT

 

- //#define LOG_NDEBUG 0

+ #define LOG_NDEBUG 1

 

  // Log detailed debug messages about each inbound event notification to the dispatcher.

- #define DEBUG_INBOUND_EVENT_DETAILS 0

+ #define DEBUG_INBOUND_EVENT_DETAILS 1

 

  // Log detailed debug messages about each outbound event processed by the dispatcher.

- #define DEBUG_OUTBOUND_EVENT_DETAILS 0

+ #define DEBUG_OUTBOUND_EVENT_DETAILS 1

 

  // Log debug messages about the dispatch cycle.

- #define DEBUG_DISPATCH_CYCLE 0

+ #define DEBUG_DISPATCH_CYCLE 1

 

  // Log debug messages about registrations.

- #define DEBUG_REGISTRATION 0

+ #define DEBUG_REGISTRATION 1

 

  // Log debug messages about input event injection.

- #define DEBUG_INJECTION 0

+ #define DEBUG_INJECTION 1

 

  // Log debug messages about input focus tracking.

- #define DEBUG_FOCUS 0

+ #define DEBUG_FOCUS 1

 

  // Log debug messages about the app switch latency optimization.

- #define DEBUG_APP_SWITCH 0

+ #define DEBUG_APP_SWITCH 1

 

  // Log debug messages about hover events.

- #define DEBUG_HOVER 0

+ #define DEBUG_HOVER 1

 

  #include "InputDispatcher.h"

 

diff --git a/services/inputflinger/InputReader.cpp b/services/inputflinger/InputReader.cpp

index c8dc454. .3 a622fc  100644

--- a/services/inputflinger/InputReader.cpp

+++ b/services/inputflinger/InputReader.cpp

@@  -16 , 10  + 16 , 10  @@

 

  #define LOG_TAG "InputReader"

 

- //#define LOG_NDEBUG 0

+ #define LOG_NDEBUG 1

 

  // Log debug messages for each raw event received from the EventHub.

- #define DEBUG_RAW_EVENTS 0

+ #define DEBUG_RAW_EVENTS 1

 

  // Log debug messages about touch screen filtering hacks.

  #define DEBUG_HACKS 0

 

diff --git a/libs/input/InputTransport.cpp b/libs/input/InputTransport.cpp

index  2 dff4e0. .977 aa22  100644

--- a/libs/input/InputTransport.cpp

+++ b/libs/input/InputTransport.cpp

@@  -5 , 19  + 5 , 19  @@

  //

  #define LOG_TAG "InputTransport"

 

- //#define LOG_NDEBUG 0

+ #define LOG_NDEBUG 1

 

  // Log debug messages about channel messages (send message, receive message)

- #define DEBUG_CHANNEL_MESSAGES 0

+ #define DEBUG_CHANNEL_MESSAGES 1

 

  // Log debug messages whenever InputChannel objects are created/destroyed

- #define DEBUG_CHANNEL_LIFECYCLE 0

+ #define DEBUG_CHANNEL_LIFECYCLE 1

 

  // Log debug messages about transport actions

- #define DEBUG_TRANSPORT_ACTIONS 0

+ #define DEBUG_TRANSPORT_ACTIONS 1

 

  // Log debug messages about touch event resampling

- #define DEBUG_RESAMPLING 0

+ #define DEBUG_RESAMPLING 1

7 App 接收键值

主要参照这个链接来写  

https://www.cnblogs.com/zhujiabin/p/5915802.html 

例程 Android studio 源码  

链接: https://pan.baidu.com/s/1hzhQ-dLSRnAbg2Q8w5qKPw  密码: 944g

@Override

     public  boolean dispatchKeyEvent(KeyEvent event) {

         if (event.getKeyCode() == KeyEvent.KEYCODE_ENTER){

             /* 隐藏软键盘 */

            InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);

             if (inputMethodManager.isActive()){

                inputMethodManager.hideSoftInputFromWindow(MainActivity. this .getCurrentFocus().getWindowToken(),  );

            }

 

            edittext.setText( "success" );

            webview.loadUrl(URL);

             return   true ;

        }

         return   super .dispatchKeyEvent(event);

    }

命令调试

8.1  测试上报时间

触发 Input 上报的时间点

rk3399_mid:/ $ logcat -s  "CAE_LOG" |grep -E  CAEIvwCb

09-06   14 : 10 : 13.502     327     436  D  CAE_LOG  :  CAEIvwCb  angle =  23  ,beam =    CMScore  =  1643

APK 接收到键值的时间点

09-06 14:10:13.518 5693-5693/com.hu.audiotest D/audiotest_MainActivity: KeyEvent.KEYCODE_ENTER KeyCode0

09-06 14:10:13.522 5693-5693/com.hu.audiotest D/audiotest_MainActivity: KeyEvent.KEYCODE_ENTER KeyCode0

消耗的时间大概需要 16MS ,但是触发是通过 HAL 层触发的,如果从 Kerne 触发事间会更短一些

8.2  设备文件调试

我们 kernel 下面正常用 getevent  来调试  

getevent -l  

cat /proc/bus/input/devices

rk3399_mid:/ # getevent -l

add device  1 : /dev/ input /event2

  name:      "rk29-keypad"

add device  2 : /dev/ input /event1

  name:      "as9102 Touchscreen"

add device  3 : /dev/ input /event0

  name:      "iflytek"

/dev/ input /event0: EV_KEY        00 f9                 DOWN

/dev/ input /event0: EV_SYN       SYN_REPORT            00000000

/dev/ input /event0: EV_KEY        00 f9                 UP

/dev/ input /event0: EV_SYN       SYN_REPORT            00000000

8.3 adb  上报键值调试

我们正常用 adb shell input keyevent xx xx 代表键值  

可以用 input 来触发 touchscreen 也是可以的  

有个比较好的文章  

https://blog.csdn.net/jlminghui/article/details/39268419 

大部分支持的键值如下

 -->   "KEYCODE_UNKNOWN"

1  -->   "KEYCODE_MENU"

2  -->   "KEYCODE_SOFT_RIGHT"

3  -->   "KEYCODE_HOME"

4  -->   "KEYCODE_BACK"

5  -->   "KEYCODE_CALL"

6  -->   "KEYCODE_ENDCALL"

7  -->   "KEYCODE_0"

8  -->   "KEYCODE_1"

9  -->   "KEYCODE_2"

10  -->   "KEYCODE_3"

11  -->   "KEYCODE_4"

12  -->   "KEYCODE_5"

13  -->   "KEYCODE_6"

14  -->   "KEYCODE_7"

15  -->   "KEYCODE_8"

16  -->   "KEYCODE_9"

17  -->   "KEYCODE_STAR"

18  -->   "KEYCODE_POUND"

19  -->   "KEYCODE_DPAD_UP"

20  -->   "KEYCODE_DPAD_DOWN"

21  -->   "KEYCODE_DPAD_LEFT"

22  -->   "KEYCODE_DPAD_RIGHT"

23  -->   "KEYCODE_DPAD_CENTER"

24  -->   "KEYCODE_VOLUME_UP"

25  -->   "KEYCODE_VOLUME_DOWN"

26  -->   "KEYCODE_POWER"

27  -->   "KEYCODE_CAMERA"

28  -->   "KEYCODE_CLEAR"

29  -->   "KEYCODE_A"

30  -->   "KEYCODE_B"

31  -->   "KEYCODE_C"

32  -->   "KEYCODE_D"

33  -->   "KEYCODE_E"

34  -->   "KEYCODE_F"

35  -->   "KEYCODE_G"

36  -->   "KEYCODE_H"

37  -->   "KEYCODE_I"

38  -->   "KEYCODE_J"

39  -->   "KEYCODE_K"

40  -->   "KEYCODE_L"

41  -->   "KEYCODE_M"

42  -->   "KEYCODE_N"

43  -->   "KEYCODE_O"

44  -->   "KEYCODE_P"

45  -->   "KEYCODE_Q"

46  -->   "KEYCODE_R"

47  -->   "KEYCODE_S"

48  -->   "KEYCODE_T"

49  -->   "KEYCODE_U"

50  -->   "KEYCODE_V"

51  -->   "KEYCODE_W"

52  -->   "KEYCODE_X"

53  -->   "KEYCODE_Y"

54  -->   "KEYCODE_Z"

55  -->   "KEYCODE_COMMA"

56  -->   "KEYCODE_PERIOD"

57  -->   "KEYCODE_ALT_LEFT"

58  -->   "KEYCODE_ALT_RIGHT"

59  -->   "KEYCODE_SHIFT_LEFT"

60  -->   "KEYCODE_SHIFT_RIGHT"

61  -->   "KEYCODE_TAB"

62  -->   "KEYCODE_SPACE"

63  -->   "KEYCODE_SYM"

64  -->   "KEYCODE_EXPLORER"

65  -->   "KEYCODE_ENVELOPE"

66  -->   "KEYCODE_ENTER"

67  -->   "KEYCODE_DEL"

68  -->   "KEYCODE_GRAVE"

69  -->   "KEYCODE_MINUS"

70  -->   "KEYCODE_EQUALS"

71  -->   "KEYCODE_LEFT_BRACKET"

72  -->   "KEYCODE_RIGHT_BRACKET"

73  -->   "KEYCODE_BACKSLASH"

74  -->   "KEYCODE_SEMICOLON"

75  -->   "KEYCODE_APOSTROPHE"

76  -->   "KEYCODE_SLASH"

77  -->   "KEYCODE_AT"

78  -->   "KEYCODE_NUM"

79  -->   "KEYCODE_HEADSETHOOK"

80  -->   "KEYCODE_FOCUS"

81  -->   "KEYCODE_PLUS"

82  -->   "KEYCODE_MENU"

83  -->   "KEYCODE_NOTIFICATION"

84  -->   "KEYCODE_SEARCH"

85  -->   "TAG_LAST_KEYCODE"

 


请使用浏览器的分享功能分享到微信等