我正在开发一个,它使用硬件按钮(如电源、音量等)来启动一些操作。我想添加一个“设置”用户界面,这样用户就可以选择他想要使用的按钮。
到目前为止,我找到了几个可行的解决方案,但没有一个适合我。例如,以下所有内容都返回true:
boolean hasMenuKey = ViewConfiguration.get(context).hasPermanentMenuKey();
boolean hasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK);
boolean hasVolumeUpKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_VOLUME_UP);
然而,设备实际上根本没有任何卷键。通过记录硬件键,我发现“音量”键实际上是KEYCODE_F1。因此,检查deviceHasKey()是不可靠的,我不能指望它。
是否有另一种方法来检查哪些硬件密钥可用,这实际上像您所期望的那样工作?或者更好的是,有没有一种方法可以获得所有可用按钮的完整列表?
还有谁能解释一下,为什么deviceHasKey()对卷键(_UP、_DOWN、_MUTE)返回true,而根本没有单个卷按钮?我认为这肯定与设备的KeyCharacterMap有关,由于该设备是一款便宜的中国设备,这一功能可能实现得很糟糕。
我的第三个问题是:有没有办法区分设备休眠时工作的按钮(我的情况下是电源、音量、F1 )和不工作的按钮(比如菜单、背面、家庭,它们都是显示器下面的触屏按钮(不是显示中的软件按钮),而不是可按的按钮)?
任何提示都是非常感谢的:)
提前谢谢你
-更新
正如Burak所建议的,这是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 if来检查设备是否对所有设备返回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));
是的,他们都回来了.
发布于 2016-06-10 06:58:39
我得出的结论是,如果设备制造商做得不好,就没有可靠的方法可以找到可用的硬件按钮。
在我的例子中,硬件/软件可以有几个按钮。然而,该设备实际上只有几个按钮焊接在逻辑板上。
没有办法确定一个按钮是否实际上是焊接到板上的应用程序级别。
发布于 2016-05-30 07:02:18
您可以使用adb shell getevent -lp
检查设备上的硬件密钥。
它将从/dev/input/
文件夹返回在linux级别上可能发生事件的实际设备。
您可以通过查找KEY_POWER
、KEY_VOLUMEUP
、KEY_VOLUMEDOWN
事件来选择其中的键输入设备,并查看哪个被接受为硬键。
只有硬钥匙才能在设备休眠时使用。
或者,如果您需要在设备休眠时保持处理器的清醒状态,则可以使用PowerManager PARTIAL_WAKE_LOCK
。
对不起,我知道这不是最好的答案,但是为了得到一个清晰的解释,我可以更新我的答案。因为声誉不高所以不能对你的问题发表评论。
https://stackoverflow.com/questions/37516774
复制相似问题