轉載請注明出處: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>