在安卓系统中如何覆盖删除键?

16

我主要通过dispatchKeyEvent中的这些行来解决问题:

byte[] cmdLeft = { (byte) 27, (byte) '[', (byte) 'D' };
byte[] cmdErase = { (byte) 27, (byte) '[', (byte) 'P' };


mSession.appendToEmulator(cmdLeft, 0, cmdLeft.length);
mSession.appendToEmulator(cmdErase, 0, cmdErase.length);

现在唯一的问题是,如果我选择editText并按删除键,则会删除一个字符,但似乎会出现两个。所以,如果我写 enable 并按删除键,它将变为 enab,但实际上发送的是 enabl。
我重写了dispatchKeyEvent,有点起作用了。如果选择了editText,则终端现在通过串行方式删除字符,所以这是一个好步骤。然而,主要问题仍然存在,如果选择终端本身,则屏幕上会写入奇怪的小框,而不是删除字符。嗯,写了一个,如果我继续按删除键,它就会停留在那个小框中,但下次我键入时,按下的删除键数量会显示为方框。这非常奇怪...
就好像它只被edittext覆盖,而没有被终端覆盖。
所有其荣耀的奇怪小框:

Enter image description here

public boolean dispatchKeyEvent(KeyEvent event) {
    if (event != null && event.getAction() == KeyEvent.ACTION_UP) {

        return false;
    }
    if (event.getKeyCode() == KeyEvent.KEYCODE_DEL) {

        try {
            sendOverSerial("\b".getBytes("UTF-8"));
        }
        catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    return super.dispatchKeyEvent(event);
};

我正在使用android中的一个库连接到终端仿真器,这将连接到一个串行设备(交换机)并显示发送/接收的数据。我通过终端下方的文本框或在终端中键入并在键盘上按“Enter”来通过连接发送数据。它只会使用软键盘。
如果我发送了一个不正确的字符串,由于没有删除键实现,我会处于无法恢复的状态。我的editTxt中的退格键可以正常工作,我只想在终端突出显示并且我正在其中编写时它也能工作。
目前,如果我按删除键,会出现一个奇怪的小框字符并且什么都不会发生,有时候日志中会出现异常(http://i.imgur.com/wMRaLPX.png)。我想知道如何改变删除键的功能,以便当我按下它时,我可以像这样发送一个删除字符,同时保留删除编辑框中字符的能力等:
sendOverSerial("\b".getBytes("UTF-8"))

这里发送了一个正确的退格键,我只需要将其合并即可。
但是软键盘似乎无法注册按键?我一直得到一个0的按键代码,只有Enter键可以使用。
我目前正在尝试https://dev59.com/c3VD5IYBdhLWcg3wXamd...62035_11377462,但如果有其他建议,那就太好了,因为迄今为止约有10个建议都没有奏效。我的退格键不会与editText相关联,而是与终端视图相关联。我甚至无法检测到删除键被按下。

嗨,你尝试过使用“退格”键吗? - Blundell
查看这个帖子(特别是第二个回复):https://dev59.com/v2445IYBdhLWcg3wZJUn#b4AGoYgBc1ULPQZFzABd - Brandon
会看一下,谢谢。 - Paul
似乎你的库不支持删除字符。抛出异常的类是做什么的? - Daniel De León
我只有两个类,异常显示127抛出了一个错误,这是删除字符。发出警告的类在库中。我知道它支持删除,因为他们提供了一个例子。这个例子连接到一个telnet服务器而不是串口。如果我连接到一个telnet服务器,删除就可以正常工作,但如果我不连接,则会出现小方框,所以连接到有效的telnet服务器似乎有助于终端处理退格键。 - Paul
显示剩余3条评论
4个回答

4
看起来你正在使用的终端控制器必须正在消耗KEYCODE_DEL,而不是让它传播到窗口,并且必须发送不同的字符到远程端,而不是\b。因此,当您的编辑文本获得焦点时,dispatchKeyEvent会处理按下事件-但是当终端获得焦点时,您看不到它。您是否通过调试器确认了事件处理程序在终端获得焦点时触发?您没有说您正在使用哪个库用于终端,但我建议您查看一下并尝试设置键处理程序或其他内容。

我会尝试你说的,谢谢。我正在使用的库是https://github.com/jackpal/Android-Terminal-Emulator。这与我使用的usb-to-serial库是分开的,但该库没有问题。 - Paul
这是抛出我之前发布的异常的类 https://github.com/jackpal/Android-Terminal-Emulator/blob/master/libraries/emulatorview/src/jackpal/androidterm/emulatorview/EmulatorView.java - Paul
快速浏览代码,看起来onKeyDown和onKeyUp都返回true,这会阻止事件向上传播。你可能可以在你的activity中处理onKeyDown,但我对键盘事件处理流程的记忆非常模糊,所以你需要自己去研究一下。似乎TermKeyListener将KEYCODE_BACK映射到“\ 177”(ascii删除而不是退格键,这就是“\ b”的含义)。似乎没有简单的方法可以更改它。但也许你可以进行扩展和覆盖? - harmanjd
我已经解决了,只需要运行这些命令即可。// ESC [ D (VT100 光标左移) byte[] cmdLeft = { (byte) 27, (byte) '[', (byte) 'D' }; // ESC [ P (VT100 删除光标处字符) byte[] cmdErase = { (byte) 27, (byte) '[', (byte) 'P' }; - Paul

2

我没有Android方面的经验,也从来没有尝试过实现删除/退格键绑定。然而,如果我要做到这一点,并且不知道一个好的标准实现,我可以想到一个解决方法,可能会很好地发挥作用。创建一个与动作监听器相关联的删除键绑定。使动作监听器getText()获取您的文本字段并将其存储为字符串。对该字符串进行子串操作以排除最后一个字符。然后使用setText()设置新字符串的文本字段。这有点手工,但肯定能够起作用。


嘿,这是一种很好的存储文本字段中内容的方法,如果我在过程中意外删除了内容,我不确定是否会删除最后一个字符。如果我按下删除键并且终端被突出显示,那么我只想让editText数据保持不变,我想要发送一个删除字符到串行端口。当我将其突出显示并使用退格键时,editText已经删除了一个字符。 - Paul

1
我建议在用户按下“发送”按钮时,一次性捕获完整字符串并全部发送,就像聊天程序一样。

我想这样做,但我不知道该怎么做。该库已设置为每次按下字符时向“write”类发送一个字符。我的其余代码也是如此,editText会发送一个字符串。我会研究一下的。 - Paul

0
解决方案是将向屏幕写入的方法移动到另一个类中,然后一切都正常了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接