Reputation: 61
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
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
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