0

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

到目前为止,我找到了几种可能的解决方案,但没有一个适合我。例如,以下都返回 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 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 来检查设备是否对所有这些都返回 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));

是的,它们都返回真实......

4

2 回答 2

1

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

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

无法确定按钮是否在 App 级别实际焊接到板上。

于 2016-06-10T06:58:39.593 回答
1

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

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

您可以通过搜索KEY_POWERKEY_VOLUMEUPKEY_VOLUMEDOWN事件来选择其中的键输入设备,并查看哪个被接受为硬键。

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

或者,如果您需要在设备休眠时保持处理器唤醒,您可以使用PowerManager 。 PARTIAL_WAKE_LOCK

抱歉,我知道这不是最好的答案,但为了清楚的解释,我可以更新我的答案。由于声誉低,无法对您的问题发表评论。

于 2016-05-30T07:02:18.623 回答