阅读:11511回复:11

安卓遥控配置

楼主#
更多 发布于:2019-07-26 10:10
安卓遥控最常用的是红外遥控和2.4G无线飞鼠,原理都是差不多的。
红外遥控发射红外码值比如:0x32,通过kernel里面配置的dtsi文件映射到一个linux code
然后通过device目录下面的某个kl文件映射到一个具体的android keycode
这样就可以在应用层通过onKeyDown()监听到这个按键
红外码值 --> linux层 --> android层--> 监听按键
红外码值和linux的映射:<0xbf KEY_BACK>,在kernel的dts文件中添加一组 ir_key{}
0xbf是红外码值,
KEY_BACK是linux的keycode,
在文件
kernel/include/uapi/linux/input.h 中定义
有的平台可能是别的文件名,大概都是在这个位置
linux和安卓层的映射文件在device目录的配置文件xxxx.kl
key 89    RO
key 87    F11
F11是安卓keycode
在frameworks/native/include/input/InputEventLabels.h文件中
还有这个文件定义是Android Keycode

frameworks/base/core/java/android/view/KeyEvent.java
假如我们现在接到一个任务需要适配一个新的遥控器,首先我们测试一下遥控的客户码和所有的按键红外码值,具体的测试方法各个方案平台都有对应,通过串口打印信息可以看到。
将红外码配置到对应的dtsi文件里面:(文章后面有RK和全志打印码值方法)
ir_key3 {
 usercode = <0x1dcc>;
 key_table =
 <0xee KEY_REPLY>,
 <0xf0   KEY_BACK>,
 <0xf8   KEY_UP>,
 <0xbb  KEY_DOWN>,
 <0xef   KEY_LEFT>,
 <0xed  KEY_RIGHT>,
 <0xfc   KEY_HOME>,
 <0xf1   KEY_VOLUMEUP>,
 <0xfd   KEY_VOLUMEDOWN>,
 <0xb7  KEY_SEARCH>,
 <0xff    KEY_POWER>,
 <0xf3   KEY_MUTE>,
 <0xbf  KEY_MENU>,
 <0xf9  KEY_ENTER>,
 <0xb3  388>,
 <0xb5  KEY_BACKSPACE>;
 };
编译kernel烧录之后,adb shell 输入 getevent 可以看到类似如下打印:
U5X:/ # getevent                                                              
add device 1: /dev/input/event2
  name:     "cec_input"
could not get driver version for /dev/input/mice, Not a typewriter
add device 2: /dev/input/event1
  name:     "gpio_keypad"
could not get driver version for /dev/input/mouse0, Not a typewriter
add device 3: /dev/input/event0
  name:     "aml_keypad"
随便按一个按键可以看到如下打印:
/dev/input/event0: 0001 0069 00000001
/dev/input/event0: 0000 0000 00000000
/dev/input/event0: 0001 0069 00000000
/dev/input/event0: 0000 0000 00000000
这串打印表示了一个完整的按键按下和抬起,码值是0x69转换为十进制为105 这个105就是dtsi文件里映射的linux码值。
可以看到遥控的按键事件是/dev/input/event0  对应的输入设备是aml_keypad
add device 3: /dev/input/event0
  name:     "aml_keypad"
adb shell 下 输入 dumpsys input 可以看到这样的一段打印
3: aml_keypad
      Classes: 0x0000082b
      Path: /dev/input/event0
      Descriptor: d2c52ff0f656fac4cd7b7a118d575e0109a9fe1c
      Location: keypad/input0
      ControllerNumber: 0
      UniqueId:
      Identifier: bus=0x0010, vendor=0x0001, product=0x0001, version=0x0100
      KeyLayoutFile: /system/usr/keylayout/Vendor_0001_Product_0001.kl
      KeyCharacterMapFile: /system/usr/keychars/Generic.kcm
      ConfigurationFile:
      HaveKeyboardLayoutOverlay: false

说明遥控器对应的kl文件是KeyLayoutFile: /system/usr/keylayout/Vendor_0001_Product_0001.kl
我们这个是已经匹配好了kl文件,关于系统匹配kl文件有个优先级的规则(见最后面的插图),具体的代码流程有时间可以去研究一下,系统如果没有匹配到任何kl文件或者匹配你的kl文件出错,就会调用默认的Generic.kl  如果你还没有配置自己的kl文件,dumpsys input 打印信息可以看看这一段:
Identifier: bus=0x0010, vendor=0x0001, product=0x0001,version=0x0100
你可以通过vendor product的值来创建kl文件。
你也可以通过这个设备名aml_keypad来创建kl文件,优先级比VID,PID命名的kl文件低一点。
设备名kl的命名规则是:设备名称中除"0-9"、“a-z”、“A-Z”、"-“或”_“之外的所有字符将替换为下划线,所以这里可以创建一个/system/usr/keylayout/aml_keypad.kl文件。


有时候在添加的时候会发现,明明已经创建好了kl文件,但是发现遥控按键还是有问题,看打印信息dumpsys input,匹配的kl文件竟然是Generic.kl这个系统的默认文件,这时候看打印通常会提示kl文件里面某个keycode没有定义。
所以kl文件里面配置的安卓Keycode一定要在这几个文件里有定义好,否则kl匹配会报错就会自动匹配到默认的Generic.kl文件了
frameworks/base/core/java/android/view/KeyEvent.java
frameworks/native/include/android/keycodes.h
frameworks/native/include/input/InputEventLabels.h

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


kl文件创建好后,可以参照系统自带的kl文件来配置linux code和 android keycode的映射。
key 28    ENTER
比如这个key 28 里面的 28就是linux code 对应dtsi文件里面的 KEY_ENTER,为啥我知道KEY_ENTER=28呢?这个当然不是瞎蒙的,是看这个文件 kernel/include/uapi/linux/input.h 知道的:
#define KEY_ENTER 28

当然你可能说我这个文件里面根本没有,那有可能你的是在别的文件里面,大概都是在这个目录下,去找一下,很容易找到的。
那后面的ENTER是怎么回事呢,其实就是frameworks/base/core/java/android/view/KeyEvent.java这个文件里面的,可以打开看一下,很容易就找到了这个定义:
public static final int KEYCODE_ENTER           = 66;  
明明是KEYCODE_ENTER 为什么kl里面写成ENTER呢,其实这个我也不知道,我就知道kl里面都是这样配置的,把KEYCODE_ 这一段去掉,保留下划线后面这一段。依葫芦画瓢这样配置好之后就完成了 ‘红外码-->linux code--->android keycode’完整的映射。
这个时候你可以看一下这个frameworks\base\services\core\java\com\android\server\policyPhoneWindowManager.java文件,把里面这个static final boolean DEBUG_INPUT = false;改成true之后,按键按下的时候,就有keycode打印出来,这个就是android keycode了。

可以看到KeyEvent.java里面定义了很多个按键,有几百个,你在键盘上看到的所有按键,基本上都有定义,但是你说我还嫌不够,我想定义几个自己的按键玩玩也是可以的。接下来是时候展示真正的技术了
1.在你的kl文件里面添加
key 252   HEADSET_PTT
2.input.h(kernel/include/uapi/linux/input.h)
#define KEY_HEADSET_PTT 252
3./frameworks/native/include/android/KeyCodes.h
enum {      
    AKEYCODE_HEADSET_PTT         = 276, //276跟其他不能重复 };
4./frameworks/native/include/input/InputEventLabels.h
DEFINE_KEYCODE(HEADSET_PTT),
5.frameworks/base/core/res/res/values/attrs.xml
<attr name="keycode"> ... <enum name="KEYCODE_HEADSET_PTT" value="276" /> ... </attr>
6.frameworks/base/core/java/android/view/KeyEvent.java
/**
* @hide

*/
public static final int KEYCODE_HEADSET_PTT     = 276; //这个值和attrs.xml  InputEventLabels.h值相同
private static final int LAST_KEYCODE = KEYCODE_HEADSET_PTT;
public static final boolean isSystemKey(int keyCode) {
 ... switch (keyCode) {
           case KeyEvent.KEYCODE_HEADSET_PTT: //
                     return true;
          }
 ...
  }
... public static final boolean isMediaKey(int keyCode) { //这个也可以加 也可以不加
    switch (keyCode) {
             case KeyEvent.KEYCODE_HEADSET_PTT:
                    return true;
          }
}
7.接下来就可以在这个文件里监听你的按键了
frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
... @Override
public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {
      ... case KeyEvent.KEYCODE_HEADSET_PTT:{
              if(down){
                   ...
                }else{
                   ...
                } break;
            }        
      ...
    }
...

RK打印红外码值
adb shell环境下输入
echo 1 > /sys/module/rockchip_pwm_remotectl/parameters/code_print
cat /proc/kmsg

按遥控按键就会有码值打印
全志打印红外码值
echo 0xff > /sys/module/sunxi_ir_rx/parameters/debug_mask


最新喜欢:

s_noopys_noop... yamyam VastStarGamesVastSt...
[url]http://190.lsal.cn/195/1329.gif?0728100424873[/url]
沙发#
发布于:2019-07-26 12:19
上班中抽空匆匆忙忙整理的,难免有些表达不清晰,和一些理解有误,欢迎大家一起完善。后面我有时间会慢慢整理完善
[url]http://190.lsal.cn/195/1329.gif?0728100424873[/url]
板凳#
发布于:2019-07-26 13:55
非常好。
If you have nothing to lose, then you can do anything.
地板#
发布于:2019-12-18 14:00
请教下 遥控器输入法中,字符输入上下左右选中后要用按键确认输入, 这个确认enter键没作用,不会输入字符可以怎么处理呢
4楼#
发布于:2019-12-18 15:05
阿赞88:请教下 遥控器输入法中,字符输入上下左右选中后要用按键确认输入, 这个确认enter键没作用,不会输入字符可以怎么处理呢回到原帖
难受 原来是按键映射没有搞对
--- a/device/amlogic/u211/files/Vendor_0001_Product_0001.kl
+++ b/device/amlogic/u211/files/Vendor_0001_Product_0001.kl
@@ -14,7 +14,7 @@ key 15    BACK
 key 158   BACK
 key 58    SOFT_RIGHT
 key 107   ENDCALL
-key 62    ENDCALL
+#key 62    ENDCALL
 key 139    MENU
 key 125    MENU
 key 60    NOTIFICATION
@@ -23,8 +23,8 @@ key 217   SEARCH
 key 228   POUND
 key 227   STAR
 key 231   CALL
-key 61    CALL
-key 97    DPAD_CENTER
+#key 61    CALL
+key 28    DPAD_CENTER
 key 232   DPAD_CENTER
 key 108   DPAD_DOWN
 key 103   DPAD_UP
@@ -74,7 +74,7 @@ key 50    M
 key 51    COMMA
 key 52    PERIOD
 key 53    SLASH
-key 28    ENTER
+key 97    ENTER
5楼#
发布于:2020-05-13 09:18
zhaoyf13:上班中抽空匆匆忙忙整理的,难免有些表达不清晰,和一些理解有误,欢迎大家一起完善。后面我有时间会慢慢整理完善回到原帖
请教楼主,如果遥控上的数字键盘,做成可切换模式:比如 1@,.
6楼#
发布于:2020-05-13 09:20
请教楼主,如果遥控上的数字键盘,做成可切换模式:比如
1@,. 2ABC 3DEF
 ....
1/A/a  0空格 Del

这种需要怎么配?
7楼#
发布于:2020-05-13 10:46
Pazival:请教楼主,如果遥控上的数字键盘,做成可切换模式:比如
1@,. 2ABC 3DEF
 ....
1/A/a  0空格 Del

这种需要怎么配?
回到原帖
这个可能有点麻烦,就像以前的键盘手机9宫格输入法那样吗?我没有做过,看看网上有没有人搞过,
[url]http://190.lsal.cn/195/1329.gif?0728100424873[/url]
8楼#
发布于:2020-05-13 10:49
zhaoyf13:这个可能有点麻烦,就像以前的键盘手机9宫格输入法那样吗?我没有做过,看看网上有没有人搞过,回到原帖
我们公司做的飞鼠键盘是全键盘的,字母键是可以输入拉丁字母或者韩语元音字符的,有一个切换键来决定是输入拉丁字母或者是韩语元音,这个是配合google 韩语输入法软键盘使用的。你说的那种9宫格输入法,配合软键盘输入法应该是可以做到的。按键的键值都是一一对应的,具体输入什么字符让软键盘去处理。
[url]http://190.lsal.cn/195/1329.gif?0728100424873[/url]
9楼#
发布于:2021-03-03 11:34
这两天在调试遥控,这个帖子很有用

dtsi里面改custom_maps, 发现有几个键值映射错了,查include\uapi\linux目录,发现在input-event-codes.h文件里,错的key与Vendor_0001_Product_0001.kl映射错误,改成正确的key就好了
10楼#
发布于:2021-03-03 16:58
补充一点,空中飞鼠属于USB协议里的HID设备,驱动目录: kernel\drivers\hid\,键值好和kernel\drivers\hid\hid-input.c里有个数组有关,还没来得及细看,后面慢慢研究。
11楼#
发布于:2023-12-29 01:39
再补充一点,amlogic平台,
echo 1 > /sys/class/remote/amremote/debug_enable
就可以在kernel日志中查看红外遥控的NEC码值了
比如:
meson-remote ff808040.rc: framecode=0xee11ff00
游客

返回顶部