安卓4.4获得硬件密钥ID(实际上在设备上可用)



我正在开发一个Xposed模块,它使用硬件按钮(如电源、音量增大等)来启动一些操作。我想添加一个"设置"UI,这样用户就可以选择要使用的按钮。

到目前为止,我找到了几种可能的解决方案,但都不适合我。例如,以下都返回true:

boolean hasMenuKey = ViewConfiguration.get(context).hasPermanentMenuKey();
boolean hasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK);
boolean hasVolumeUpKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_VOLUME_UP);

然而,该设备实际上根本没有任何音量键。通过记录硬件密钥,我发现"volume"密钥实际上是KEYCODE_F1。所以检查设备HasKey()是不可靠的,我不能指望它

有没有另一种解决方案可以检查哪些硬件密钥是可用的,这些密钥实际上可以像您预期的那样工作?或者更好的是,有没有办法获得所有可用按钮的完整列表?

还有人能解释一下为什么在根本没有单个音量按钮的情况下,deviceHasKey()对音量键(_UP、_DOWN、_MUTE)返回true吗?我认为这一定与该设备的KeyCharacterMap有关,由于该设备是一款廉价的中国设备,该设备的实现可能很差。

我的第三个问题是:有没有办法区分设备休眠时有效的按钮(在我的情况下是电源、音量、F1)和无效的按钮(如菜单、返回、主页,它们都是显示屏下方的触摸按钮(而不是显示屏中的软件按钮),而不是可按下的按钮)?

任何提示都将不胜感激:)

提前感谢

-----更新------

正如Burak Day所建议的,以下是adb shell getevent -lp:的结果

add device 1: /dev/input/event0
name:     "mtk-kpd"
events:
KEY (0001): KEY_HOME              KEY_END               KEY_VOLUMEDOWN        KEY_VOLUMEUP         
KEY_POWER             KEY_MENU              KEY_BACK              KEY_HP               
KEY_CAMERA            KEY_SEND             
input props:
<none>
add device 2: /dev/input/event4
name:     "mtk-tpd-kpd"
events:
KEY (0001): KEY_MENU              KEY_BACK              KEY_HOMEPAGE         
input props:
<none>
could not get driver version for /dev/input/mouse0, Not a typewriter
add device 3: /dev/input/event3
name:     "mtk-tpd"
events:
KEY (0001): KEY_MENU              KEY_BACK              KEY_HOMEPAGE          BTN_TOUCH            
ABS (0003): ABS_X                 : value 0, min 0, max 240, fuzz 0, flat 0, resolution 240
ABS_Y                 : value 0, min 0, max 240, fuzz 0, flat 0, resolution 240
ABS_PRESSURE          : value 0, min 0, max 255, fuzz 0, flat 0, resolution 0
ABS_MT_TOUCH_MAJOR    : value 0, min 0, max 100, fuzz 0, flat 0, resolution 0
ABS_MT_TOUCH_MINOR    : value 0, min 0, max 100, fuzz 0, flat 0, resolution 0
ABS_MT_POSITION_X     : value 0, min 0, max 240, fuzz 0, flat 0, resolution 0
ABS_MT_POSITION_Y     : value 0, min 0, max 240, fuzz 0, flat 0, resolution 0
ABS_MT_TRACKING_ID    : value 0, min 0, max 0, fuzz 0, flat 0, resolution 0
input props:
INPUT_PROP_DIRECT
add device 4: /dev/input/event2
name:     "hwmdata"
events:
REL (0002): REL_Y                
input props:
<none>
add device 5: /dev/input/event1
name:     "ACCDET"
events:
KEY (0001): KEY_VOLUMEDOWN        KEY_VOLUMEUP          KEY_HANGEUL           KEY_NEXTSONG         
KEY_PLAYPAUSE         KEY_PREVIOUSSONG      KEY_STOPCD            KEY_SEND             
input props:
<none>
could not get driver version for /dev/input/mice, Not a typewriter

正如您所看到的,设备认为有按钮可用,在与制造商交谈后,我们发现他们可以向设备添加更多按钮(如果我们订购一定数量并额外支付几千美元)。但是,在当前的变体中,按钮仍然不存在。

我的猜测是,该设备使用了一个模块化的板/处理器/驱动程序,你可以将按钮焊接到它上,也可以将它们留空,但软件不知道按钮是否焊接在板上。

我该如何知道按钮是否实际可用?我想让我的模块尽可能通用,这样它将来就可以在其他设备上运行,而不会显式地更改代码。此外,我不想向用户显示可能的按钮,如果它们不是真正存在的。

另一件事是,我仍然需要一种方法来区分设备休眠时可用的按钮(电源、音量)和不可用的按钮。

----更新2-

我检查了event0设备的密钥的原始十六进制值。然后我使用"mtk-kpd.kl"字符映射来翻译它们。然后,我使用各自的KeyEvent ID来检查设备是否对所有这些ID都返回true:

Log.d(Constants.LOG_TAG, "Home:" + KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_HOME));
Log.d(Constants.LOG_TAG, "END:" + KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_ENDCALL));
Log.d(Constants.LOG_TAG, "Volume Up:" + KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_VOLUME_UP));
Log.d(Constants.LOG_TAG, "Volume Down:" + KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_VOLUME_DOWN));
Log.d(Constants.LOG_TAG, "POWER:" + KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_POWER));
Log.d(Constants.LOG_TAG, "Menu:" + KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_MENU));
Log.d(Constants.LOG_TAG, "Back:" + KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK));
Log.d(Constants.LOG_TAG, "HP:" + KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_FOCUS));
Log.d(Constants.LOG_TAG, "CAMERA:" + KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_CAMERA));
Log.d(Constants.LOG_TAG, "Send:" + KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_CALL));

是的,它们都是真的。。。

您可以使用adb shell getevent -lp检查设备上的硬件密钥。

它将从/dev/input/文件夹中返回带有linux级别上可能事件的实际设备。

您可以通过查找KEY_POWERKEY_VOLUMEUPKEY_VOLUMEDOWN事件来选择其中的键输入设备,并查看接受的硬键。

当设备处于睡眠状态时,只有硬键可用。

或者,如果您需要在设备睡眠时保持处理器清醒,则可以使用PowerManagerPARTIAL_WAKE_LOCK

对不起,我知道这不是最好的答案,但为了得到明确的解释,我可以更新我的答案。由于声誉不佳,无法对您的问题发表评论。

我得出的结论是,如果设备制造商做得不好,就没有可靠的方法来找出哪些硬件按钮可用。

在我的情况下,硬件/软件能够有几个按钮。然而,该设备实际上只有几个按钮焊接在逻辑板上。

在应用程序级别,无法确定按钮是否真的焊接在板上。

最新更新