Android keymaps

3 years, 11 months ago

(31 comments)

I recently bought a Bluetooth keyboard to use on Android; unfortunately some keys weren't recognised at all and others weren't quite mapped as I'd like. This is fairly easy to fix as an end user, as long as you have a rooted device (adb remount must succeed). Here's a quick howto, since I couldn't find one.

It shouldn't need saying, but you do this at your own risk. You can easily break your device's response to keys, and possibly make your device unbootable too if the file is invalid.

It's pretty much as described under Keymaps and Keyboard Input in the porting documentation. What we're going to do is edit one file: /system/usr/keylayout/qwerty.kl. This file maps scancodes to Android keycodes. For example: key 30 A means scancode 30 (decimal) maps toKEYCODE_A (29), the A key. As the porting docs say, a separate Key Character Map file deals with what characters, if any (e.g. "a", "A", "#"), should be generated given the keycode and the state of the modifiers (Shift, Fn/Sym, etc). A different KCM can be loaded for Bluetooth keyboards depending on their device name, but at least by default, the same key layout file (including your changes) is used for Bluetooth and the built-in keyboard (if any).

So, first we need to fetch your current key layout, and it's a good idea to keep backups (both on the device and locally).

adb pull /system/usr/keylayout/qwerty.kl qwerty.kl
cp qwerty.kl qwerty-orig.kl
adb shell cp /system/usr/keylayout/qwerty.kl /sdcard/qwerty-orig.kl

Now, edit qwerty.kl as you like. It should look initially look similar to this Nexus One example. You might find it helpful at this point to see what scancodes your keyboard is sending. There really ought to be a tool for this in Dev Tools or Spare Parts, but it seems there isn't. I've made a dirt-simple app to show you KeyEvent.toString(), which was the work of 5 minutes and could certainly be improved.

My particular keyboard is a white roll-up 87-key variety, that you can still find on eBay. It has F-keys doubling as media keys: if you get this model, be aware that the Fn key is really F-lock (toggles the state rather than acting as a modifier). Here is my layout file in case it's helpful. This layout mostly follows the principle of least surprise, except that the button with "Home" printed on it is Call, to mirror "End" being Hangup. F1 with F-lock on (Home symbol) is the Android "Home" keycode (goes to the home screen).

Now copy the layout back onto the device:

adb remount
adb push qwerty.kl /system/usr/keylayout/qwerty.kl

(If the remount fails, you probably don't have a rooted device.) It seems you need to reboot for the changes to take effect, so go ahead and do that, and your keys should then behave as you've specified. :-)

Comments

Julien Bourdoiseau 3 years, 7 months ago

very useful - works fine HTC desire + bluetooth keyboard AZERTY
Thanks

Link | Reply

Rafael Machado 2 years, 11 months ago

Hi, nice tutorial, but, i'm using a portuguese (brazilian) keyboard, and my tablet doesn't have a layout for this keyboard, i tried use your tutorial, but when i start the Key test, i push the "ç" letter, and appear key 74, but when i change the key in qwerty.kl some keys stops work, and the "ç" doesn't work too, so can you help me?

Link | Reply

Chris Boyle 2 years, 11 months ago

Have you perhaps put something like "key 74 ç" in qwerty.kl? That won't work (and would probably stop it reading the rest of the file), because ç is a character, but you need a keycode, something like CCEDILLA, but that isn't on the list... I'm looking at the list of Android keycodes and in fact I don't see any for accented characters, so I don't know how that would work. :-(

I would recommend you try asking on android.stackexchange.com, about keycodes for accented characters. I hope I've missed something obvious and that it is possible somehow, I mean, they're already selling Android devices in plenty of countries that would require such keys on the phone itself, aren't they?

Link | Reply

Rafael Machado 2 years, 11 months ago

Thanks for the help, I already asked in the forum who you posted

Link | Reply

Rafael Machado 2 years, 11 months ago

Hey, I think i have a solution, I had a motorola cliq, which has a physical keyboard, so i thought, it has to be a ROM with the layout, so i found, but wasn't configurated to a external keyboard, but opening the keychar, i searched for Ç, and i found, and I rename to qwert.kcm, but now the problem is, how can I configure the qwerty.kl to work with Ç?

Link | Reply

Chris Boyle 2 years, 11 months ago

If you look at your kcm file (it's plain text), look for the lines with the Ç, you can see at the start of the line what keycode is mapped to that. Use that keycode in qwerty.kl. A problem you might encounter is that the kcm expects an ordinary C and a modifier, which is seemingly not what you have. If it does that, I don't know how to proceed from here, and can only suggest looking at relevant parts of the platform source.

Link | Reply

Balbino Rodriguez 2 years, 6 months ago

Hi, sorry i'm checking for an app or similar for change the funtions of the keys <<,>>,>,Pause, etc of the normal radiocd with a2dp, when it's in a normal bluetooth sync between an android phone..
i try to change this funtions to make diferent thinks on the phone when i press this keys on the radiocd.. it´s possible to make this??

Link | Reply

Chris Boyle 2 years, 6 months ago

Yes, I would guess you should be able to catch the buttons in the same way that media players like last.fm do it. Looks like you want to catch Intent.ACTION_MEDIA_BUTTON. Here is last.fm's implementation, search for MEDIA_BUTTON in both cases:

https://github.com/c99koder/lastfm-android/blob/master/app/src/fm/last/android/LastFMMediaButtonHandler.java

https://github.com/c99koder/lastfm-android/blob/master/app/AndroidManifest.xml

Link | Reply

Rafael Bergamin 2 years, 4 months ago

Hi there.
I have one question. Are you able to wake your device up and also unlock it? I'm testing an apple wireless kb with my android but it will only turn the screen on and wont unlock the phone. I saw in your .kl file and in mine also that there is a WAKE and WAKE_DROPPED thing. So how could I unlock it with my keyboard? Did you get it? Sry for any bad english.

Thanks!

Link | Reply

Chris Boyle 2 years, 4 months ago

This might vary by device, ROM, and Android version, but I just tried it on a current CyanogenMod 9 build on my Galaxy S II, and it seems any key will wake the device, except the media keys will work without waking, and the Fn key, which I think is internal to the keyboard, and only changes what the F1/F2/.../F12 keys do.

Link | Reply

Rafael Bergamin 2 years, 4 months ago

When it wake the device, it opens the lockscreen right? or yours go straight to the home screen?

Link | Reply

Chris Boyle 2 years, 4 months ago

Yes, it goes to the lock screen.

Link | Reply

Rafael Bergamin 2 years, 4 months ago

so you can't go far from the lockscreen using just the keyboard also?
Sorry if i'm bothering you. One last question, are you able to navigate the app drawer using your keyboard? Thanks again

Link | Reply

Chris Boyle 2 years, 4 months ago

I think those would both depend on which ROM and which Android version... I think I was able to navigate within the app drawer (on CM9 with Trebuchet) and in principle you ought to be able to unlock with a PIN or password that way, but not a pattern. Personally I'm using face unlock at the moment, which gets around this problem. :-)

Link | Reply

Rafael Bergamin 2 years, 4 months ago

Two more things.
I'm getting the same scancode when pressing shift + 'O' and just 'O' for example. I thought it would give me different scancodes. Happens the same for all shift, control, alt, command...
And the other one my fn key wont give any scancode, ou it would be zero. Does it means android wont "read" it?

Thanks again.

Link | Reply

Chris Boyle 2 years, 4 months ago

As I understand it, getting the same scancode is normal. You would get two scancodes, one for the shift key itself, and one for the O key (the keymap file determines which scancode is which), and then the separate Key Character Map deals with combining the modifier state (e.g. shift) + scancode "o" -> character "O". As for Fn, on the keyboard I have here, it looks like Fn is internal to the keyboard, see previous comment, which would mean it only changes what scancodes the other keys send. Hope that helps.

Link | Reply

Rafael Bergamin 2 years, 4 months ago

ok i get it, so i think mine wont be of use for me, cause it dont even changes the scancode of the Fkeys. But thanks, you're helping me a lot.

Link | Reply

Rafael Bergamin 2 years, 4 months ago

do you know how to find the specific keyboard name for creating an exclusive .kl . I've seen in the web something like "vendor_xxxx_product_xxxx_version_xxxx.kl". Would you know how to find it? Thanks again man

Link | Reply

Chris Boyle 2 years, 4 months ago

On my device I can see a bunch of layouts including 8 with names like that in /system/usr/keylayout e.g. Vendor_045e_Product_028e.kl - these seem to come from frameworks/base/data/keyboards , as shown here for CyanogenMod: https://github.com/CyanogenMod/android_frameworks_base/tree/ics/data/keyboards

I haven't tried doing anything device-specific like that, and don't know how you would find the relevant vendor/product IDs for a Bluetooth device, but hope that helps.

Link | Reply

Rafael Bergamin 2 years, 4 months ago

I will check that source bur found an esay way to do that. The command 'lsusb' lists all bluetooth devices connected with the device, just in case it would help you sometime. Thanks for all the help man. Really appreciate it!

Link | Reply

John Kha 1 year ago

You may have already figured this out, but you can use the command:

logcat -d | grep event

to see information about the input devices.

Link | Reply

tom cat 2 years ago

How do I use adb :S

Link | Reply

Chris Boyle 2 years ago

The instructions on d.a.c are quite good: http://developer.android.com/tools/help/adb.html

Link | Reply

Nick Spacek 2 years ago

Any thoughts on how I might catch/determine the key code coming back from a long-press? I'm working to remap some of the hard-keys on my HTC One V for CM9. I have the TASK_SWITCH working but want to map the long-press that brings up the MENU.

Link | Reply

Chris Boyle 2 years ago

I haven't looked at this for a while, but I think long presses aren't specifically represented in the kl/kcm files. I think a different layer handles that, by looking for longer times between key down and key up, and the mapping of a key to its long-press meaning might not be configurable (I could be wrong). All I can really suggest is to go hunting in the Android source, sorry.

Link | Reply

Dominik Jenzer 1 year, 9 months ago

Cool thing, thanks
Before I do some modifications, I try to prepare carefully ;-) And I remarked something strange to me:
I use the Microsoft Wedge Bluetooth Keyboard with Swiss-German-Layout. Anyway, I remarked it on Key Q, this key should be on the same place in US-Layout.
In all .kl files, this key has keycode 16.
When I use your Key-Test-App, it told me keycode 45, where keycode 16 is the key O.
When I press the key in any app, Q-key produces a Q and O-key an O (wow...).

Whats wrong?

I use ICS on a Samsung GT-P7500 pad.

Link | Reply

Mykolas Panavas 1 year, 8 months ago

Hi,

Thanks for a great info!
I had some problems with changing Generic.kl file:
1. as i used windows for editing key layout file after copying it back to android i had to change file permisions.
2. had some dublicate entries of keys.
3. I'm not sure, but eof of text file is important. In my case i changed it to unix format.

Link | Reply

Mikkel Juul Erup 1 year, 1 month ago

Hi.

Thanks for the great info.

I have been trying to make some layout configuration changes to my bluetooth keyboard on my Nexus 7 running 4.2.2 following this guide and other sources. Any changes seem to be ignored, however. My google research turned up some pages showing other people having had problems getting changes in the kl and kcm files to take effect since Jelly Bean.

would you happen to have an idea about whats going on.

Link | Reply

Chris Boyle 1 year, 1 month ago

I'm afraid I haven't looked into this in recent releases. Hopefully someone with more up-to-date knowledge has an idea?

Link | Reply

le yo 6 months, 2 weeks ago

I have a problem, I'm a root user, but when I try to edit qwerty.kl with an html editor, I can't save it :/

Link | Reply

Guido Haag 6 months ago

I had the same problem a few days ago. See the part where Chris says " adb pull /system/usr/keylayout/qwerty.kl qwerty.kl " you need to use ADB to perform a pull command. Make sure you have mounted the system with read/write access (mount -o rw,remount -t yaffs2 /dev/block/mtdblock3 /system) so that after you edit the file on your computer and 'push' it back you will have permission, also you need root access and once you have rebooted and are happy with how it works set system to read only mode again using (mount -o ro,remount -t yaffs2 /dev/block/mtdblock3 /system)

Link | Reply

New Comment

required

required (not published)

optional