Search code examples
javaandroidandroid-softkeyboardsoft-keyboard

Why deleteSurroundingText doesn't work with emojis and select all?


I'm working on a custom keyboard and I'm using deleteSurroundingText to delete characters. I only have two issue with this. deleteSurroundingText doesn't work well while deleting emojis. I need to press del button twice in order to get rid of single emoji. And second del key is not working with select all option.

case Keyboard.KEYCODE_DELETE:
    getCurrentInputConnection().deleteSurroundingText(1,0);
    break;

This is what happens to emoji when I press try to del an emoji: ?

It turns into a question mark. Also, when I try to del text by doing select all nothing happens.

Any help would be appreciated


Solution

  • Java use 16-bit characters (see note in the documentation). So one character can store codepoint from U+0000 to U+FFFF.
    Modern unicode define codepoint range from U+0000 to U+10FFFF. Most of emojis have codepoints beyond U+FFFF. To represent such codepoints so called "surrogate pairs" are used.
    In other words each emoji (and all other codepoints beyond U+FFFF boundary) are represented by two consequent characters in the string.
    When you call deleteSurroundingText(1,0); you corrupt surrogate pair. Not yet deleted part of surrogate pair are rendered as an ? mark.

    Documentation for deleteSurroundingText() specially emphasize this case:

    IME authors: please be careful not to delete only half of a surrogate pair. Also take care not to delete more characters than are in the editor, as that may have ill effects on the application. Calling this method will cause the editor to call onUpdateSelection(int, int, int, int, int, int) on your service after the batch input is over.

    Please next time read method documentation carefully before trying to use it.

    To determine if character is a part of surrogate pair use Chracter::isSurrogate() method.