Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Injecting non-English characters in Android

I am programming on a remote control app. One of the tasks is injecting characters. The code I am currently using looks like this:

Instrumentation instr = new Instrumentation();

String str="a";

// basically the same like calling instr.sendStringSync(str);
char[] chars = str.toCharArray();
KeyCharacterMap keyCharacterMap = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD);
KeyEvent[] keyEvents = keyCharacterMap.getEvents(chars);
if (keyEvents != null) {
    for (KeyEvent kev : keyEvents) {
        instr.sendKeySync(kev);
    }
}

That works perfectly on English characters (The characters show up in EditText boxes). However, if I am trying to inject e.g. Korean characters, this fails. The function getEvents returns null, even when I have configured Korean language and keyboard.

I know there is another method for injecting strings directly:

KeyEvent event = new KeyEvent(SystemClock.uptimeMillis(), str, 0, 0);
instr.sendKeySync(event);

This is not working either - no characters shown in EditText boxes, and onKeyMultiple() is not called either in my test activity.

This is strange since dispatchKeyEvent() with the same event works in my test activity:

KeyEvent event = new KeyEvent(SystemClock.uptimeMillis(), str, 0, 0);
dispatchKeyEvent(event);

My remote control app needs to inject events no matter to which activity. This is possible using Instrumentation (with android.permission.INJECT_EVENTS and a signature with the platform key).

How can I inject non-English characters using instrumentation? Is there another way to accomplish this? E.g. Using dispatchKeyEvent (has to work for other activities/apps as well).

like image 554
kahlk Avatar asked May 25 '12 10:05

kahlk


1 Answers

I leave the part above as extra info. I have found a solution. It requires to have root, but if you can sign with the application key I guess that's not a problem. What you can do is edit the file Virtual.kcm (/system/usr/keychars/Virtual.kcm), which is the default key character map (kcm). You can add any character you want, and then use the method Instrumentation.sendStringSync(String string), because it will be able to generate KeyEvents from the new kcm.

I had some problems editting the kcm on the phone, so what I did was to copy it on a computer, edit it there and then copy it back to the device.

I hope this helps!


In this link, the following content appears. It seams that the virtual keyboard has a US keyCharacterMap and layout, no matter what you choose on settings. I haven't been able to find a way to solve this.

Language Note

Android does not currently support multilingual keyboards. Moreover, the built-in generic key character map assumes a US English keyboard layout.

OEMs are encouraged to provide custom key character maps for their keyboards if they are designed for other languages.

Future versions of Android may provide better support for multilingual keyboards or user-selectable keyboard layouts.
like image 172
dleal Avatar answered Sep 18 '22 10:09

dleal