使用 Android IME 选择

Selection using Android IME

在我的输入法服务中,我试图 select 当前光标位置之前的文本。以下是代码片段

InputConnection inputConnection = getCurrentInputConnection();
ExtractedText extractedText = inputConnection.getExtractedText(new ExtractedTextRequest(), 0);
inputConnection.setSelection(extractedText.selectionStart-1,extractedText.selectionEnd);

InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.updateSelection(null, extractedText.selectionStart-1,extractedText.selectionEnd, 0, 0);

这有一个非常不稳定的行为,有时它 selects,有时它只是将光标向后移动一步。

谁能指出我做错了什么?

添加:

由于这个问题有一段时间没有得到解答,我想提出一个替代问题。我正在四处寻找 selecting 文本和黑客键盘的一些替代方法,按 shift 键然后按箭头键就可以了,但我无法复制这个过程。我尝试向下和向上发送方向键事件以及 meta_shift_on 标志。

但那是行不通的...再一次,我做错了什么?

我使用 shift+箭头键解决了这个问题。

1 --> I was requesting the "inputConnection" for each event. I have now started using just one instance of inputConnection which I request for on the hook "onBindInput" and use it for all.
2 --> Sending Meta_shift_on as a flag along with the dpad_left/right/whatever was not enough, Now I send a press down shift event, then dpad up-down, and then up shift event. following is the pseudo-code: 


private void moveSelection(int dpad_keyCode) {   
inputMethodService.sendDownKeyEvent(KeyEvent.KEYCODE_SHIFT_LEFT, 0);
inputMethodService.sendDownAndUpKeyEvent(dpad_keyCode, 0);
inputMethodService.sendUpKeyEvent(KeyEvent.KEYCODE_SHIFT_LEFT, 0);
}

仅此而已。

注意:这个解决方案或多或少是一个 hack,我仍在寻找一个更好的解决方案,它也允许我切换选择的锚点。如果你知道更好,请分享。

inputConnection.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_SHIFT_LEFT));
inputConnection.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_));
inputConnection.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_SHIFKEYCODE_DPAD_T_LEFT));
inputConnection.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_SHIFT_LEFT));

在 IME 中选择的最佳解决方案

private void SelectionLeft() {
        ExtractedText extractedText = mLatinIme.getCurrentInputConnection().getExtractedText(new ExtractedTextRequest(), 0);
        if (extractedText == null || extractedText.text == null) return;

        int selectionStart = extractedText.selectionStart;
        int selectionEnd = extractedText.selectionEnd;


        mLatinIme.getCurrentInputConnection().setSelection(selectionStart, selectionEnd - 1);

    }

    private void SelectionRight() {
        ExtractedText extractedText = mLatinIme.getCurrentInputConnection().getExtractedText(new ExtractedTextRequest(), 0);
        if (extractedText == null || extractedText.text == null) return;

        int selectionStart = extractedText.selectionStart;
        int selectionEnd = extractedText.selectionEnd;

        mLatinIme.getCurrentInputConnection().setSelection(selectionStart, selectionEnd + 1);

    }