Learning Resources
Keyboard events handling in Android
Android supports a variety of keyboard devices including special function keypads (volume and power controls), compact embedded QWERTY keyboards, and fully featured PC-style external keyboards.
This document describes physical keyboards only. Refer to the Android SDK for information about soft keyboards (Input Method Editors).
Keyboard Classification
An input device is classified as a keyboard if either of the following conditions hold:
-
The input device reports the presence of any Linux key codes used on keyboards including
0
through0xff
orKEY_OK
throughKEY_MAX
. -
The input device reports the presence of any Linux key codes used on joysticks and gamepads including
BTN_0
throughBTN_9
,BTN_TRIGGER
throughBTN_DEAD
, orBTN_A
throughBTN_THUMBR
.
Joysticks are currently classified as keyboards because joystick and gamepad buttons are reported by EV_KEY
events in the same way keyboard keys are reported. Thus joysticks and gamepads also make use of key map files for configuration. Refer to the section on Joystick Devices for more information.
Once an input device has been classified as a keyboard, the system loads the input device configuration file and keyboard layout for the keyboard.
The system then tries to determine additional characteristics of the device.
-
If the input device has any keys that are mapped to
KEYCODE_Q
, then the device is considered to have an alphabetic keypad (as opposed to numeric). The alphabetic keypad capability is reported in the resourceConfiguration
object asKEYBOARD_QWERTY
. -
If the input device has any keys that are mapped to
KEYCODE_DPAD_UP
,KEYCODE_DPAD_DOWN
,KEYCODE_DPAD_LEFT
,KEYCODE_DPAD_RIGHT
, andKEYCODE_DPAD_CENTER
(all must be present), then the device is considered to have a directional keypad. The directional keypad capability is reported in the resourceConfiguration
object asNAVIGATION_DPAD
. -
If the input device has any keys that are mapped to
KEYCODE_BUTTON_A
or other gamepad related keys, then the device is considered to have a gamepad.
Keyboard Driver Requirements
-
Keyboard drivers should only register key codes for the keys that they actually support. Registering excess key codes may confuse the device classification algorithm or cause the system to incorrectly detect the supported keyboard capabilities of the device.
-
Keyboard drivers should use
EV_KEY
to report key presses, using a value of0
to indicate that a key is released, a value of1
to indicate that a key is pressed, and a value greater than or equal to2
to indicate that the key is being repeated automatically. -
Android performs its own keyboard repeating. Auto-repeat functionality should be disabled in the driver.
-
Keyboard drivers may optionally indicate the HID usage or low-level scan code by sending
EV_MSC
withMSC_SCANCODE
and a valud indicating the usage or scan code when the key is pressed. This information is not currently used by Android. -
Keyboard drivers should support setting LED states when
EV_LED
is written to the device. Thehid-input
driver handles this automatically. At the time of this writing, Android usesLED_CAPSLOCK
,LED_SCROLLLOCK
, andLED_NUMLOCK
. These LEDs only need to be supported when the keyboard actually has the associated indicator lights. -
Keyboard drivers for embedded keypads (for example, using a GPIO matrix) should make sure to send
EV_KEY
events with a value of0
for any keys that are still pressed when the device is going to sleep. Otherwise keys might get stuck down and will auto-repeat forever.
Keyboard Operation
The following is a brief summary of the keyboard operation on Android.
-
The
EventHub
reads raw events from theevdev
driver and maps Linux key codes (sometimes referred to as scan codes) into Android key codes using the keyboard's key layout map. -
The
InputReader
consumes the raw events and updates the meta key state. For example, if the left shift key is pressed or released, the reader will set or reset theMETA_SHIFT_LEFT_ON
andMETA_SHIFT_ON
bits accordingly. -
The
InputReader
notifies theInputDispatcher
about the key event. -
The
InputDispatcher
asks theWindowManagerPolicy
what to do with the key event by callingWindowManagerPolicy.interceptKeyBeforeQueueing
. This method is part of a critical path that is responsible for waking the device when certain keys are pressed. TheEventHub
effectively holds a wake lock along this critical path to ensure that it will run to completion. -
If an
InputFilter
is currently in use, theInputDispatcher
gives it a chance to consume or transform the key. TheInputFilter
may be used to implement low-level system-wide accessibility policies. -
The
InputDispatcher
enqueues the key for processing on the dispatch thread. -
When the
InputDispatcher
dequeues the key, it gives theWindowManagerPolicy
a second chance to intercept the key event by callingWindowManagerPolicy.interceptKeyBeforeDispatching
. This method handles system shortcuts and other functions. -
The
InputDispatcher
then identifies the key event target (the focused window) and waits for them to become ready. Then, theInputDispatcher
delivers the key event to the application. -
Inside the application, the key event propagates down the view hierarchy to the focused view for pre-IME key dispatch.
-
If the key event is not handled in the pre-IME dispatch and an IME is in use, the key event is delivered to the IME.
-
If the key event was not consumed by the IME, then the key event propagates down the view hierarchy to the focused view for standard key dispatch.
-
The application reports back to the
InputDispatcher
as to whether the key event was consumed. If the event was not consumed, theInputDispatcher
callsWindowManagerPolicy.dispatchUnhandledKey
to apply "fallback" behavior. Depending on the fallback action, the key event dispatch cycle may be restarted using a different key code. For example, if an application does not handleKEYCODE_ESCAPE
, the system may redispatch the key event asKEYCODE_BACK
instead.
Keyboard Configuration
Keyboard behavior is determined by the keyboard's key layout, key character map and input device configuration.
Properties
The following input device configuration properties are used for keyboards.
keyboard.layout
Definition: keyboard.layout
=
Specifies the name of the key layout file associated with the input device, excluding the .kl
extension. If this file is not found, the input system will use the default key layout instead.
Spaces in the name are converted to underscores during lookup.
Refer to the key layout file documentation for more details.
keyboard.characterMap
Definition: keyboard.characterMap
=
Specifies the name of the key character map file associated with the input device, excluding the .kcm
extension. If this file is not found, the input system will use the default key character map instead.
Spaces in the name are converted to underscores during lookup.
Refer to the key character map file documentation for more details.
keyboard.orientationAware
Definition: keyboard.orientationAware
= 0
| 1
Specifies whether the keyboard should react to display orientation changes.
-
If the value is
1
, the directional keypad keys are rotated when the associated display orientation changes. -
If the value is
0
, the keyboard is immune to display orientation changes.
The default value is 0
.
Orientation awareness is used to support rotation of directional keypad keys, such as on the Motorola Droid. For example, when the device is rotated clockwise 90 degrees from its natural orientation, KEYCODE_DPAD_UP
is remapped to produce KEYCODE_DPAD_RIGHT
since the 'up' key ends up pointing 'right' when the device is held in that orientation.
keyboard.builtIn
Definition: keyboard.builtIn
= 0
| 1
Specifies whether the keyboard is the built-in (physically attached) keyboard.
The default value is 1
if the device name ends with -keypad
, 0
otherwise.
The built-in keyboard is always assigned a device id of 0
. Other keyboards that are not built-in are assigned unique non-zero device ids.
Using an id of 0
for the built-in keyboard is important for maintaining compatibility with the KeyCharacterMap.BUILT_IN_KEYBOARD
field, which specifies the id of the built-in keyboard and has a value of 0
. This field has been deprecated in the API but older applications might still be using it.
A special-function keyboard (one whose key character map specifies a type of SPECIAL_FUNCTION
) will never be registered as the built-in keyboard, regardless of the setting of this property. This is because a special-function keyboard is by definition not intended to be used for general purpose typing.
Example Configurations
# This is an example input device configuration file for a built-in
# keyboard that has a DPad.
# The keyboard is internal because it is part of the device.
device.internal = 1
# The keyboard is the default built-in keyboard so it should be assigned
# an id of 0.
keyboard.builtIn = 1
# The keyboard includes a DPad which is mounted on the device. As the device
# is rotated the orientation of the DPad rotates along with it, so the DPad must
# be aware of the display orientation. This ensures that pressing 'up' on the
# DPad always means 'up' from the perspective of the user, even when the entire
# device has been rotated.
keyboard.orientationAware = 1
Compatibility Notes
Prior to Honeycomb, the keyboard input mapper did not use any configuration properties. All keyboards were assumed to be physically attached and orientation aware. The default key layout and key character map was named qwerty
instead of Generic
. The key character map format was also very different and the framework did not support PC-style full keyboards or external keyboards.
When upgrading devices to Honeycomb, make sure to create or update the necessary configuration and key map files.
HID Usages, Linux Key Codes and Android Key Codes
The system refers to keys using several different identifiers, depending on the layer of abstraction.
For HID devices, each key has an associated HID usage. The Linux hid-input
driver and related vendor and device-specific HID drivers are responsible for parsing HID reports and mapping HID usages to Linux key codes.
As Android reads EV_KEY
events from the Linux kernel, it translates each Linux key code into its corresponding Android key code according to the key layout file of the device.
When the key event is dispatched to an application, the android.view.KeyEvent
instance reports the Linux key code as the value of getScanCode()
and the Android key code as the value of getKeyCode()
. For the purposes of the framework, only the value of getKeyCode()
is important.
Note that the HID usage information is not used by Android itself or passed to applications.
Code Tables
The following
The LKC column specifies the Linux key code in hexadecimal.
The AKC column specifies the Android key code in hexadecimal.
The Notes column refers to notes that are posted after the
The Version column specifies the first version of the Android platform to have included this key in its default key map. Multiple rows are shown in cases where the default key map has changed between versions. The oldest version indicated is 1.6.
-
In Gingerbread (2.3) and earlier releases, the default key map was
qwerty.kl
. This key map was only intended for use with the Android Emulator and was not intended to be used to support arbitrary external keyboards. Nevertheless, a few OEMs added Bluetooth keyboard support to the platform and relied onqwerty.kl
to provide the necessary keyboard mappings. Consequently these older mappings may be of interest to OEMs who are building peripherals for these particular devices. Note that the mappings are substantially different from the current ones, particularly with respect to the treatment of theHOME
key. It is recommended that all new peripherals be developed according to the Honeycomb or more recent key maps (ie. standard HID). -
As of Honeycomb (3.0), the default key map is
Generic.kl
. This key map was designed to support full PC style keyboards. Most functionality of standard HID keyboards should just work out of the box.
The key code mapping may vary across versions of the Linux kernel and Android. When changes are known to have occurred in the Android default key maps, they are indicated in the version column.
Device-specific HID drivers and key maps may apply different mappings than are indicated here.