转载请注明出处:https://www.cnblogs.com/lialong1st/p/10066673.html
CPU:RK3288
系统:Android 5.1
1、查看遥控器的用户码和键值,供应商给的可能是反码,也有可能不正确。
打开红外打印功能有以下两种方式,内核打印可以用串口,也可以在adb中使用指令 # cat proc/kmsg
(1)通过指令打开红外接收的打印功能,然后按遥控器按键,就可以在内核打印中看到用户码和键值。
$ adb shell root@rk3288:/ # cd sys/module/rockchip_pwm_remotectl/parameters cd sys/module/rockchip_pwm_remotectl/parameters root@rk3288:/sys/module/rockchip_pwm_remotectl/parameters # ls ls code_print dbg_level root@rk3288:/sys/module/rockchip_pwm_remotectl/parameters # cat code_print cat code_print 0 root@rk3288:/sys/module/rockchip_pwm_remotectl/parameters # echo 1 > code_print echo 1 > code_print
(2)在红外接收的源码中,给下面变量赋值,也可以打印用户码和键值,但需要重新编译烧录内核
path:kernel/drivers/input/remotectl/rockchip_pwm_remotectl.c
static int rk_remote_print_code = 1;
2、在dts文件中增加键值,绝大部分键值系统中已经定义,如果没有的就需要自己添加。
path:kernel/arch/arm/boot/dts/rk3288.dtsi
remotectl: pwm@ff680000 { compatible = "rockchip,remotectl-pwm"; reg = <0xff680000 0x10>; #pwm-cells = <2>; pinctrl-names = "default"; pinctrl-0 = <&pwm0_pin>; clocks = <&clk_gates11 11>; clock-names = "pclk_pwm"; remote_pwm_id = <0>; interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; };
remote_pwm_id:使用pwm0
path:kernel/arch/arm/boot/dts/rk3288-tb_8846.dts
&remotectl { status = "okay"; handle_cpu_id = <2>; ir_key0{ rockchip,usercode = <0xff00>; rockchip,key_table = <0xf0 KEY_POWER>, // Power <0xad KEY_HOME>, // Home <0xef KEY_MENU>, // Menu <0xa7 KEY_MUTE>, // mute <0xa1 388>, // Mouse <0xb2 KEY_UP>, // Up <0xee KEY_PAGEUP>, // PageUp <0xa3 KEY_VOLUMEUP>, // Vol+ <0xa8 KEY_LEFT>, // Left <0xa4 KEY_ENTER>, // Ok/ENTER <0xa0 KEY_RIGHT>, // Right <0xab KEY_VOLUMEDOWN>, // Vol- <0xa9 KEY_TAB>, // Tab <0xa5 KEY_DOWN>, // Down <0xed KEY_PAGEDOWN>, // PageDown <0xac KEY_BACK>, // Back <0xe8 KEY_1>, // 1 <0xe4 KEY_2>, // 2 <0xe0 KEY_3>, // 3 <0xe9 KEY_4>, // 4 <0xe5 KEY_5>, // 5 <0xe1 KEY_6>, // 6 <0xea KEY_7>, // 7 <0xe6 KEY_8>, // 8 <0xe2 KEY_9>, // 9 <0xe7 KEY_0>, // 0 <0xeb KEY_DOT>, // . <0xe3 KEY_DELETE>, // Del <0xa6 KEY_PAUSE>, // Pause <0xaa KEY_PLAY>; // Play }; };
usercode:用户码
key_table:左侧为遥控器键值,右侧为按键对应的功能码
绝大部分功能码可以在下面文件中查找到,写宏或者对应的数字都可以(例如mouse键),如果的确没有,可以用功能键代替或者手动添加。
path:kernel/include/dt-bindings/input/input.h
此时,编译烧录,按键值就可以通过 getevent 查看到,但app中收到的按键值可能与实际不对应或者未知按键。
getevent用法:https://www.cnblogs.com/lialong1st/p/9093851.html
3、打开下面路径的文件,可以看到功能码和上层对应的关系, 如果新添加的按键值没有,也需要按照已有的格式手动添加。
没有的按键值,在按键时,上层app收到的值是未知按键。
path:device/rockchip/common/ff680000_pwm.kl
key 28 ENTER key 116 POWER key 158 BACK key 139 MENU key 217 SEARCH key 232 DPAD_CENTER key 108 DPAD_DOWN key 103 DPAD_UP key 102 HOME key 105 DPAD_LEFT key 106 DPAD_RIGHT key 115 VOLUME_UP key 114 VOLUME_DOWN key 143 NOTIFICATION key 113 VOLUME_MUTE key 388 TV_KEYMOUSE_MODE_SWITCH key 104 PAGE_UP key 109 PAGE_DOWN key 15 TAB key 2 1 key 3 2 key 4 3 key 5 4 key 6 5 key 7 6 key 8 7 key 9 8 key 10 9 key 11 0 key 52 PERIOD key 111 DEL key 119 MEDIA_PAUSE key 207 MEDIA_PLAY
中间的数字是功能码对应的数字,与第二步的查找方法一致。
右侧的是与上层对应的关系,在下面路径中任意一个都可以查找到,如有特殊功能键则需要添加。
path:frameworks/base/core/java/android/view/KeyEvent.java(例如:KEYCODE_DPAD_DOWN 只需要取后半部分就可以)
path:frameworks/native/include/input/InputEventLabels.h(例如:DPAD_DOWN 只需要取括号内部的就可以)
注意:数字键不要用小键盘(NUMPAD_0 等等),因为小键盘有多功能。
此时,就大功告成了。
下面为简单的遥控器测试app源码
MainActivity.java
package com.example.aaron.irtest; import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.KeyEvent; import android.widget.TextView; import android.widget.Toast; import java.time.LocalDate; public class MainActivity extends AppCompatActivity { private static final String TAG = "IR"; TextView tv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv = (TextView) findViewById(R.id.display); } public boolean onKeyDown(int keyCode, KeyEvent event) { Log.d(TAG, String.valueOf(keyCode)); switch (keyCode) { case KeyEvent.KEYCODE_POWER: tv.setText("电源键"); Toast.makeText(getBaseContext(), "电源键", Toast.LENGTH_SHORT).show(); break; case KeyEvent.KEYCODE_HOME: tv.setText("主页键"); Toast.makeText(getBaseContext(), "主页键", Toast.LENGTH_SHORT).show(); break; case KeyEvent.KEYCODE_MENU: tv.setText("菜单键"); Toast.makeText(getBaseContext(), "菜单键", Toast.LENGTH_SHORT).show(); break; case KeyEvent.KEYCODE_VOLUME_MUTE: tv.setText("静音键"); Toast.makeText(getBaseContext(), "静音键", Toast.LENGTH_SHORT).show(); break; case KeyEvent.KEYCODE_STEM_PRIMARY: tv.setText("鼠标键"); Toast.makeText(getBaseContext(), "鼠标键", Toast.LENGTH_SHORT).show(); break; case KeyEvent.KEYCODE_DPAD_UP: tv.setText("上键"); Toast.makeText(getBaseContext(), "上键", Toast.LENGTH_SHORT).show(); break; case KeyEvent.KEYCODE_PAGE_UP: tv.setText("上页键"); Toast.makeText(getBaseContext(), "上页键", Toast.LENGTH_SHORT).show(); break; case KeyEvent.KEYCODE_VOLUME_UP: tv.setText("音量+键"); Toast.makeText(getBaseContext(), "音量+键", Toast.LENGTH_SHORT).show(); break; case KeyEvent.KEYCODE_DPAD_LEFT: tv.setText("左键"); Toast.makeText(getBaseContext(), "左键", Toast.LENGTH_SHORT).show(); break; case KeyEvent.KEYCODE_ENTER: tv.setText("确认键"); Toast.makeText(getBaseContext(), "确认键", Toast.LENGTH_SHORT).show(); break; case KeyEvent.KEYCODE_DPAD_RIGHT: tv.setText("右键"); Toast.makeText(getBaseContext(), "右键", Toast.LENGTH_SHORT).show(); break; case KeyEvent.KEYCODE_VOLUME_DOWN: tv.setText("音量-键"); Toast.makeText(getBaseContext(), "音量-键", Toast.LENGTH_SHORT).show(); break; case KeyEvent.KEYCODE_TAB: tv.setText("Tab键"); Toast.makeText(getBaseContext(), "Tab键", Toast.LENGTH_SHORT).show(); break; case KeyEvent.KEYCODE_DPAD_DOWN: tv.setText("下键"); Toast.makeText(getBaseContext(), "下键", Toast.LENGTH_SHORT).show(); break; case KeyEvent.KEYCODE_PAGE_DOWN: tv.setText("下页键"); Toast.makeText(getBaseContext(), "下页键", Toast.LENGTH_SHORT).show(); break; case KeyEvent.KEYCODE_BACK: tv.setText("返回键"); Toast.makeText(getBaseContext(), "返回键", Toast.LENGTH_SHORT).show(); break; case KeyEvent.KEYCODE_1: tv.setText("1"); Toast.makeText(getBaseContext(), "1", Toast.LENGTH_SHORT).show(); break; case KeyEvent.KEYCODE_2: tv.setText("2"); Toast.makeText(getBaseContext(), "2", Toast.LENGTH_SHORT).show(); break; case KeyEvent.KEYCODE_3: tv.setText("3"); Toast.makeText(getBaseContext(), "3", Toast.LENGTH_SHORT).show(); break; case KeyEvent.KEYCODE_4: tv.setText("4"); Toast.makeText(getBaseContext(), "4", Toast.LENGTH_SHORT).show(); break; case KeyEvent.KEYCODE_5: tv.setText("5"); Toast.makeText(getBaseContext(), "5", Toast.LENGTH_SHORT).show(); break; case KeyEvent.KEYCODE_6: tv.setText("6"); Toast.makeText(getBaseContext(), "6", Toast.LENGTH_SHORT).show(); break; case KeyEvent.KEYCODE_7: tv.setText("7"); Toast.makeText(getBaseContext(), "7", Toast.LENGTH_SHORT).show(); break; case KeyEvent.KEYCODE_8: tv.setText("8"); Toast.makeText(getBaseContext(), "8", Toast.LENGTH_SHORT).show(); break; case KeyEvent.KEYCODE_9: tv.setText("9"); Toast.makeText(getBaseContext(), "9", Toast.LENGTH_SHORT).show(); break; case KeyEvent.KEYCODE_0: tv.setText("0"); Toast.makeText(getBaseContext(), "0", Toast.LENGTH_SHORT).show(); break; case KeyEvent.KEYCODE_PERIOD: tv.setText("小数点"); Toast.makeText(getBaseContext(), "小数点", Toast.LENGTH_SHORT).show(); break; case KeyEvent.KEYCODE_DEL: tv.setText("删除键"); Toast.makeText(getBaseContext(), "删除键", Toast.LENGTH_SHORT).show(); break; case KeyEvent.KEYCODE_MEDIA_PAUSE: tv.setText("暂停键"); Toast.makeText(getBaseContext(), "暂停键", Toast.LENGTH_SHORT).show(); break; case KeyEvent.KEYCODE_MEDIA_PLAY: tv.setText("播放键"); Toast.makeText(getBaseContext(), "播放键", Toast.LENGTH_SHORT).show(); break; } return false; } }
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.aaron.irtest.MainActivity"> <TextView android:id="@+id/display" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" android:textSize="50sp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> </android.support.constraint.ConstraintLayout>