J.Kim
J.Kim

Reputation: 61

InputConnection.commitCorrection() does not seem to work properly

I am developing soft keyboard for Android. I want to correct some text using InputConnection.commitCorrecrion(), If key corresponding to Keyboard.KEYCODE_DONE is pressed. But, the text doesn't change, it just flash once. How can I solve this problem?

public class SimpleIME extends InputMethodService
    implements KeyboardView.OnKeyboardActionListener {
....

@Override
public void onKey(int primaryCode, int[] keyCodes) {
    InputConnection ic = getCurrentInputConnection();
    switch(primaryCode){
    ....

        case Keyboard.KEYCODE_DONE:
            ic.commitCorrection(new CorrectionInfo(oldTextPosition, oldText, newText));
            break;
    ....
    }
}

Upvotes: 6

Views: 1023

Answers (2)

Milan
Milan

Reputation: 1000

From some reason commitCorrection() seems not to be working. So, for our soft keyboard we implemented a workaround solution:

val correctionInfo: CorrectionInfo = ... // an instance of CorrectionInfo
val cursorStart = ... // Current position of the cursor in the input field

val original = correctionInfo.oldText as String
val replace = correctionInfo.newText as String
val offset = correctionInfo.offset
val editingEnd = offset + original.length

// Setting the value to 1 leaves the cursor at the end of the text, the 'offset' to previous cursor position is added later.
val newCursorPosition = 1

inputConnectionLocal.beginBatchEdit()

// Adds the 'offset' to the previous cursor position. This is important for the cases when the user has managed to type something while the current autocorrection is still going on.
val cursorOffset = cursorStart - editingEnd

inputConnectionLocal.setComposingRegion(offset, editingEnd)
inputConnectionLocal.setComposingText(replace, newCursorPosition + cursorOffset)
inputConnectionLocal.finishComposingText()

// Fix for Teams and similar apps that seem to ignore the offset set in setComposingText
val additionalChars = replace.length - original.length
inputConnectionLocal.setSelection(cursorStart + additionalChars, cursorStart + additionalChars)

inputConnectionLocal.endBatchEdit()
                inputConnectionLocal.requestCursorUpdates(InputConnection.CURSOR_UPDATE_IMMEDIATE)

Upvotes: 0

alr3000
alr3000

Reputation: 83

I had a similar issue, but no flash, just no change to the text at all. I decided the EditText input was simply not responding to this commitCorrection call or not accepting it for some reason, so I used deleteSurroundingText and commitText instead (I was replacing whatever word the cursor was in, if any):

 // limit=0 allows trailing empty strings to represent end-of-string split
    fun getWordBeforeCursor() : String {
        val arr = wordbreak.split(ic.getTextBeforeCursor(255, 0), 0)
        Log.d(TAG, "words before: " + arr.joinToString(","))
        return if (arr.isEmpty()) "" else arr.last()
    }

    fun getWordAfterCursor() : String {
        val arr = wordbreak.split(ic.getTextAfterCursor(255, 0), 0)
        Log.d(TAG, "words after: " + arr.joinToString(","))
        return if (arr.isEmpty()) "" else arr.first()
    }


    fun getCursorPosition() : Int {
        val extracted: ExtractedText = ic.getExtractedText(ExtractedTextRequest(), 0);
        return extracted.startOffset + extracted.selectionStart;
    }

    try {
         ...

        val backward = getWordBeforeCursor()
        val forward = getWordAfterCursor()

        Log.d(TAG, "cursor position: " + getCursorPosition())
        Log.d(TAG, "found adjacent text: [" + backward + "_" + forward + "]")

        // if in the middle of a word, delete it
        if (forward.isNotEmpty() && backward.isNotEmpty()) {
            //instead of this:
            //ic.commitCorrection(CorrectionInfo(getCursorPosition()-backward.length, backward + forward, icon.text))

            //do this:
            ic.deleteSurroundingText(backward.length, forward.length)
            ic.commitText(newText, 1)
        }
    ...

Upvotes: 2

Related Questions