flide
flide

Reputation: 189

Selection using Android IME

In my input method service I am trying to select the text before the current cursor position. Following is the code snippet

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);

This has a very flaky behaviour, sometimes it selects, sometimes it just moves the cursor one step back.

Can anybody point out what is it that I am doing wrong?

ADDITION:

Since this question has remained unanswered for some time, I would like to pose an alternate question. I was looking around for some alternate ways of selecting text and on the hackers-Keyboard, pressing the shift and then a arrow key does the trick, but I am not able to replicate the process. I tried sending the d-pad keys down and up key-events along with meta_shift_on flag.

But that is not working... Again, what am I doing wrong?

Upvotes: 3

Views: 929

Answers (3)

S.J Hashmi
S.J Hashmi

Reputation: 83

Best solution for selection in 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);

    }

Upvotes: 3

user9748649
user9748649

Reputation: 1

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));

Upvotes: -1

flide
flide

Reputation: 189

I solved this problem by using the shift+arrow keys.

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);
}

And that is all it took.

Note: This solution is more or less a hack and I am still looking for a better solution that also allows me to switch anchor of a selection. If you know better, please share.

Upvotes: 0

Related Questions