Android 在到达焦点视图之前处理按键事件

Android handle key event before reaching focused view

我在 HID 模式下通过蓝牙将外部条码扫描器连接到我的平板电脑,并尝试在我的应用程序中处理输入。条形码扫描器基本上像键盘一样工作。

我有一个简单的图形用户界面,在我的主要 activity 我有以下方法:

@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
    System.out.println(keyCode + " - " + (char) event.getUnicodeChar());
    return true;
}

问题:

当我打开文本应用程序时,例如 google 笔记并扫描任何代码,条形码被插入后跟一个新行。这让我觉得我可以处理关键事件并将所有字符写入 stringbuilder,直到我到达 'Enter'.

的关键事件

但问题是,当我在我的应用程序中使用扫描仪 (this barcode) 时,上述方法的输出如下:

59 - �� <- 'Shift'
29 - a
59 - ��
47 - s
62 -
8 - 1
9 - 2
10 - 3

条形码末尾的'Enter'无法在事件中捕获(应该是keyCode 66)但是我的GUI中的元素之一被突出显示,这意味着扫描仪必须发送'Enter'

当我将多行 EditText 添加到我的 GUI 并在元素聚焦时扫描相同的条形码时,输出如下:

29 - a
47 - s
62 -
8 - 1
9 - 2
10 - 3
66 -

这里记录了 'Enter' 键事件,而两个 'Shift' 键都不可见(不过 EditText 元素中的字母是大写的)。

作为解决方法,我可以使用一个始终保持焦点的不可见多行元素,但我真的不想依赖不可见元素。相反,我想捕捉我的条形码扫描仪发送的所有击键。

为什么我看不到 'Enter'?

我对这个问题做了更多的研究,我找到了一个非常(对我来说)令人满意的解决方案。

显然并不总是调用 onKeyDown 和 onKeyUp,尤其是当 window 元素在其他地方消耗了 KeyEvent 时。在我的例子中,ListView 具有默认焦点并在它到达提到的方法之前消耗了 ENTER 事件(因此它像我的问题描述中提到的那样被突出显示)。

可以使用另一种方法,在将 KeyEvent 发送到 window 之前调用该方法。它是 dispatchKeyEvent。但要小心,该事件被调用了两次,一次是按下键,一次是弹起键。

这里是示例代码:

@Override
public boolean dispatchKeyEvent(KeyEvent event) {

    System.out.println(event.getAction() + " " + event.getKeyCode() + " - " + (char) event.getUnicodeChar());

    return true;
}

这个解决方案对我有用,因为我的应用程序不需要监听任何其他按键事件,否则应该使用另一个 return。