Páginas

martes, 30 de julio de 2013

Configurar Mini Teclado inalámbrico RT-MWK01 Riitek Micro Keyboard para utilizarlo con sistema Android en español

El mini teclado inalámbrico externo RT-MWK01, de la empresa china Riitek especializada en mini teclados, venía con el sistema multimedia basado en Android, WOXTER TV 200. Es un teclado QWERTY completo, con touchpad y cursor. Cuando salió al mercado, el teclado resultó un complemento  maravilloso, ya que te permitía utilizar el sistema multimedia de forma casi similar a si estuvieras manipulando la pantalla táctil de un móvil.
Sin un teclado, estos dispositivos multimedia serían prácticamente inútiles, pues no podrías beneficiarte del sistema Android que incorpora. No podrías navegar por Internet, ni mandar correos, ni cualquier otro programa que requiriese para su funcionamiento el uso de un teclado.

El teclado dispone de un LED bastante luminoso (aunque yo no lo he utilizado nunca) y está dotado de retroiluminación en todas las teclas, muy práctico si estás viendo una película en el salón con las luces apagadas. No necesita pilas, pues incorpora una pequeña batería, recargable mediante conexión USB.
El sistema funcionaba perfectamente hasta que opté por cambiar la ROM original que equipaba el dispositivo WOXTER por otra versión de Gingerbread, la 2.3.6, que incorporaba mejoras y permitía rooterlo. Dos pasos para adelante... y uno para atrás: El teclado dejó de responderme conforme a un teclado español. Las teclas respondían a un teclado inglés.
Cuando me encontré en esta situación, traté de buscar una solución, rastreando por Internet, pero no fui capaz de resolver el problema. Tampoco era un problema acuciante de resolver, que me preocupase excesivamente.

Pero al haber solucionado este mismo problema para un miniPC sistema Android, el MK808 con teclado RC12 (ver entrada en este mismo blog Personalización del teclado externo inalámbrico RC12 de un miniPC MK808 basado en Android) pensé que ahora sí me sería fácil solucionar el problema, y opté por aplicar los conocimientos adquiridos en dicha entrada.
MUY IMPORTANTE:
Antes de continuar hay que tener en cuenta que para realizar todos los procedimientos que siguen, el dispositivo tiene que estar ROOTEADO. Este procedimiento ha sido probado en un sistema determinado, y que probablemente funcione sin mayores problemas en otro sistema Android. A pesar de ello, no me responsabilizo de los problemas que puedan surgir al aplicar lo que se indica en este blog.Los procedimientos que se indican en esta entrada del blog han funcionado en un sistema Android con versión 4.2.2. Probablemente funcione para versiones anteriores de Android 4.0 y superiores.

Herramientas a utilizar

Esta vez voy a utilizar solamente el sistema Android. Existen otros modos de solucionar el problema tal como vienen indicados con suficiente detalle en la entrada que he mencionado con anterioridad.
Pero en este caso las herramientas que voy a utilizar serán sólo aplicaciones de Android:
- Un emulador de terminal desde Android, por ejemplo Android Terminal Emulator.
- la aplicación ES Explorador de Archivos.
- y la aplicación KeyTest.apk.
u otras aplicaciones que tengan las mismas funcionalidades que las anteriores.


Parámetros del teclado

Primero, vamos averiguar el nombre que debemos darle a los dos ficheros requeridos por un dispositivo de introducción de datos como es un teclado externo.
   /system/usr/keylayout/Vendor_XXXX_Product_XXXX_Version_XXXX.kl
   /system/usr/keychars/Vendor_XXXX_Product_XXXX_Version_XXXX.kcm
Para ello, utilizaremos la aplicación Android Terminal Emulator para ver el 'contenido' de un fichero - /proc/bus/input/devices. En linux,  el contenido de un fichero se muestra mediante la sentencia cat:
user_01@android:/ $ cat /proc/bus/input/devices
...
I: Bus=0003 Vendor=1997 Product=0409 Version=0111
N: Name="Riitek Micro Keyboard"
P: Phys=usb-s3cotg-1/input0
S: Sysfs=/devices/platform/s3c_otghcd/usb2/2-1/2-1:1.0/input/input9
U: Uniq=
H: Handlers=sysrq kbd event9 keychord 
B: PROP=0
B: EV=120013
B: KEY=10000 7 ff800000 7ff febeffdf ffefffff ffffffff fffffffe
B: MSC=10
B: LED=1f

I: Bus=0003 Vendor=1997 Product=0409 Version=0111
N: Name="Riitek Micro Keyboard"
P: Phys=usb-s3cotg-1/input1
S: Sysfs=/devices/platform/s3c_otghcd/usb2/2-1/2-1:1.1/input/input10
U: Uniq=
H: Handlers=kbd event10 keychord 
B: PROP=0
B: EV=1f
B: KEY=4837fff 72ff32d bf544446 0 0 70001 20c10 b17c000 267bfa d9415fed 9e1680 4400 0 10000002
B: REL=143
B: ABS=1 0
B: MSC=10
user_01@android:/ $
Tenemos los tres parámetros que requerimos para nombrar los dos ficheros:
- Vendor = 1997
- Product = 0409
- Version = 0111 (este último parámetro no se requiere)
además de indicarnos el nombre del producto "Riitek Micro Keyboard".

Ficheros genéricos

Vamos a utilizar unos ficheros genéricos como base de nuestras modificaciones. Estos ficheros,corresponden a Generic.kl y Generic.kcm y se encuentran ubicados en las carpetas /system/usr/keylayout y /system/usr/keychars, respectivamente.
De nuevo volvemos a utilizar el Terminal Emulator:

user_01@android:/ $ su
root@android:/ # cat /proc/mounts | grep system
/dev/block/mmcblk0p9 /system ext4 ro,relatime,barrier=1,data=ordered 0 0
/dev/block/dm-6 /mnt/asec/com.mobisystems.editor.office_registered-1 vfat ro,di
rsync,nosuid,nodev,noatime,nodiratime,uid=1000,fmask=0222,dmask=0222,codepage=c
p437,iocharset=iso8859-1,shortname=mixed,utf8,errors=remount-ro 0 0
root@android:/ # mount -o remount,rw -t ext4 /dev/block/mmcblk0p9 /system
root@android:/ # cd /system/usr/keylayout
root@android:/system/usr/keylayout # cp Generic.kl Vendor_1997_Product_0409.kl
root@android:/system/usr/keylayout # cd /system/usr/keylayout
root@android:/system/usr/keychars # cp Generic.kcm Vendor_1997_Product_0409.kcm
root@android:/system/usr/keychars # exit
user_01@android:/ $ 
Lo que hemos hecho ha sido primero hacernos usuario root (su), después hemos averiguado el punto de montaje de la carpeta /system (/dev/block/mmcblk0p9), hemos montado la carpeta /system en modo escritura/lectura (rw) y creado los correspondientes ficheros mediante el procedimiento de copia a partir de los ficheros genéricos Generic.kl y Generic.kcm.


Códigos del teclado

El siguiente paso es averiguar el código (scanCode) asociado a cada tecla. Para ello utilizaremos la aplicación KeyTest, que nos habremos bajado e instalado convenientemente. Al ejecutarla aparecerá por la pantalla del dispositivo Android la siguiente información:
A medida que vayamos pulsando las teclas, el valor asociado a scanCode irá cambiando. Y será en estos valores en los que nos iremos fijando, anotando estos valores en la distribución de teclado que aparece en la siguiente imagen, en donde mostramos el scanCode de cada tecla al pulsarla:
La tecla azul 'Fn' funciona de una forma peculiar. Si pulsamos simultáneamente Fn y las teclas serigrafiadas parcialmente con símbolos azules, generarán, en algunos casos, un scanCode distinto, el que se muestra en la parte inferior de la tecla correspondiente; y en otros casos, tienen una función local al teclado, como es el caso de Fn+5, que retroilumina el teclado. La combinación Fn+F4 que apaga momentáneamente la pantalla del dispositivo Android. Existen otras teclas que responden con otro scanCode al pulsarlas simultáneamente con la tecla Fn, pero que al no estar serigrafiadas voy prescindir de ellas.
Dentro de este fichero Riitek_Micro_Keyboard_RT-MWK01 se encuentran los dos ficheros con los cambios requeridos para que este teclado funcione para el idioma español.
El procedimiento que he seguido para editar estos ficheros ha sido el que a continuación se muestra. Se puede hacer directamente en el dispositivo Android, de una manera más cómoda, en un propio PC, pues la edición de un fichero de texto es mucho más sencilla.
Si optamos por hacerlo de forma autónoma, sin recurrir a un PC, nos metemos dentro del ES Explorador de Archivos, vamos a las carpetas correspondientes, los abrimos en modo texto y lo editamos y guardamos los cambios. Si lo hacemos con un PC, hay que copiarlos al PC, editarlos convenientemente, guardar los cambios y volcarlos de nuevo a las mismas carpetas.

Edición de Vendor_1997_Product_0409.kl

Todas y cada una de las teclas que hayan respondido a la aplicación KeyTest, produciendo un scanCode determinado corresponderán a una línea en este fichero. Cada línea (se puede seguir el enlace Key Layout Files) constará de los siguientes campos:
key [scanCode]    [keyCode name]  [etiquetas]
De este modo, y como ejemplo, para los códigos 8, 28, 59 y 103, las líneas se definirán como sigue, si es que no están definidas ya:

...
key 9     8
...
key 28    ENTER
...
key 59    F1
...
key 103   DPAD_UP
...
y así obraremos con todas las teclas. La primera columna siempre es key, la segunda es el código que nos ha proporcionado KeyTest,  la siguiente columna es la etiqueta, o etiquetas, que tendrá una entrada en el fichero kcm. Estas etiquetas están fijadas por la versión del sistema Android, y, a veces, también por el propio fabricante, al personalizar la ROM del dispositivo. En un principio, las etiquetas serán sólo válidas las que aparecen en Generic.kl
Con los códigos 13, 41 y 43, y posiblemente algún otro, se ha tomado una etiqueta que no corresponde. La razón de ello es de que no existe una etiqueta válida para el signo de exclamación invertido ¡, ni para la cedilla, Ç, ni tampoco para el símbolo de grado centesimal,º. O yo no he sido capaz de encontrarlos como etiquetas válidas. Para estos códigos, las líneas se definirán del siguiente modo:
...
key 13    SLASH
...
key 41    BACKSLASH
...
key 43    RIGHT_BRACKET
...
que no corresponde a ninguna etiqueta en tercera columna del fichero kl. De esta manera he medio resuelto el pequeño problema que tenía. En el fichero kcm resolveré el problema completamente, y a mi manera. Seguro que habrá alguien con mayores conocimientos que sabe encontrar la solución idónea.

Edición de Vendor_1997_Product_0409.kcm

Ahora nos toca personalizar el fichero kcm. Cada línea del fichero kl tiene que tener una estructura de datos en el fichero kcm del tipo:
# cualquier comentario empieza por el carácter almohadilla
key [etiqueta] {
    label:                          '[etiqueta de la tecla]'
    base:                           '[tecla sin modificador]'
    [modificador]:                  '[tecla con modificador]'
    [modificador]+[modificador]:    '[tecla con ambos modificadores simultáneos]'
    [modificador],[modificador]:    '[tecla con algún modificador de entre los indicados]'
    [modificador]:                   fallback [tecla mágica] 
    [modificador],[modificador]:     none
}
en donde los parámetros entre corchetes son los que tenemos que determinar.
Los modificadores pueden tomar los valores ralt, lalt, alt (tecla ALT dcha/izda/indistinta) , rshift, lshift, shift (tecla SHIFT dcha/izda/indistinta) , rctrl, lctrl, ctrl (tecla CTRL dcha/izda/indistinta) , capslock, y rmeta, lmeta, meta (tecla WIN dcha/izda/indistinta) si existiera la tecla WIN, y pueden combinarse de distintas maneras.

El parámetro label corresponde a la etiqueta de la tecla tal como aparece en el teclado. Esta línea se puede omitir, siendo éste el caso para los caracteres específicos españoles, Ñ, Ç, etc. En la segunda columna se deben poner entre comillas los caracteres que se enviarán al sistema de entrada, teniendo en cuenta que los ficheros kl y kcm sólo admiten caracteres UNICODE, por lo que para las letras Ñ o Ç deberemos ponerlo tal como sigue:
...
key RO {
    base:                              '\u00f1'  # n minuscula con tilde
    shift, capslock:                   '\u00d1'  # N mayuscula con tilde
}
...
key RIGHT_BRACKET {
    base:                               '\u00e7'  # cedilla minuscula
    shift, capslock:                    '\u00c7'  # cedilla mayuscula
    alt:                                '}'
}
...
El modificador no actuará si en la siguiente columna aparece none. Si lo que aparece es fallback, corresponde a una tecla mágica, es decir, la etiqueta que sigue a fallback será interpretada directamente por el sistema Android. Este es el caso de MENU, HOME, BACK, etc.En el fichero kcm que adjunto aparecen los siguientes bloques con el atributo fallback
...
key ESCAPE {
    base:                               fallback BACK
    alt, meta:                          fallback HOME
    ctrl:                               fallback MENU
}

key F1 {
    base:                               fallback MENU
}

key F2 {
    base:                               fallback HOME
}

key F3 {
    base:                               fallback SEARCH
}

key F4 {
    base:                               fallback VOLUME_DOWN
    shift:                              fallback VOLUME_MUTE
}

key F5 {
    base:                               fallback VOLUME_UP
    shift:                              fallback VOLUME_MUTE
}

key F6 {
    base:                               fallback MEDIA_PREVIOUS
}

key F7 {
    base:                               fallback MEDIA_PLAY_PAUSE
}

key F8 {
    base:                               fallback MEDIA_NEXT
}

key F9 {
    base:                               fallback EXPLORER
}

key F10 {
    base:                               fallback ENVELOPE
}

key F11 {
    base:                               fallback MUSIC
}

...
Los caracteres unicode  \u030x, en base hexadecimal, donde x puede tomar un valor de 0 a F, corresponden a los signos diacríticos, es decir, los acentos ortográficos, diéresis, oclusión, etc. en donde la tecla que siga a esta tecla se verá afectada por un signo diacrítico. En nuestro caso, el fichero kcm contiene los siguientes bloques para tratar los signos diacríticos:
...
key U {
    label:                              'U'
    base:                               'u'
    shift, capslock:                    'U'
    alt:                                '\u0308' # acento diéresis en siguiente letra vocal
}
...
key GRAVE {
    label:                              '`'
    base:                               '\u0300' # acento grave
    shift:                              '\u0302' # acento circunflejo
    alt:                                '['
}
...
key LEFT_BRACKET {
    base:                               '\u0301'
    shift:                              '"'
    alt:                                '{'
}
...
Una vez hayamos realizado todos los cambios en los ficheros kl y kcm, los hayamos copiado a las carpetas correspondientes, deberemos de asignarles unos permisos para que puedan ser utilizados por el sistema Android:
user@pc-desktop:~$ adb shell
root@android:/ # chmod 644 /system/usr/keychars/Vendor_1997_Product_0409.kcm
root@android:/ # chmod 644 /system/usr/keylayout/Vendor_1997_Product_0409.kl

 Conclusión

Con esta entrada en el blog, y otra anterior en este mismo blog Personalización del teclado externo inalámbrico RC12 de un miniPC MK808 basado en Android, queda suficientemente explicado el modo de resolver el problema de adaptar los distintos tipos de teclados externos que pueden conectarse a un sistema Android.
A pesar de todo, agradecería comentarios al respecto, indicándome aquellos aspectos que no están suficientemente claros, para que lo pueda explicar más claro y extensamente.

Referencias

- http://source.android.com/devices/tech/input/overview.html
- How to Create a Customized Keylayout for Any USB or Bluetooth Keyboard (ROOTED)
- [TUTORIAL] External keyboard remapping [3.0+]
- Android Terminal Emulator
- KeyTest.apk  
- estándar de codificación UNICODE 
- http://en.wikipedia.org/wiki/List_of_Unicode_characters  
- Tabla Extendida de Códigos de Caracteres en HTML

viernes, 19 de julio de 2013

Personalización del teclado externo inalámbrico RC12 de un miniPC MK808 basado en Android

Desde hace poco tiempo tengo un sistema multimedia, un smartTV MK808+RC12, basado en el sistema operativo Android, con el que puedo visionar las películas que tengo almacenadas en red o en un disco duro externo. El conjunto consta de un miniPC Android MK808, empaquetado en un pendrive, y de un teclado inalámbrico RC12, que consume uno de los dos puertos USB con el que viene equipado el MK808.
Al MK808 le he sustituido la ROM de origen y le he instalado una nueva, la Finless 2.1 con lo que pasa a tener la versión 4.2.2 de Android. Funciona a las mil maravillas.
La única 'pega' es de que el teclado es inglés, por lo que la disposición de las teclas no coincide con las de un teclado español, carece de algunas de ellas, como la 'ñ' o la 'ç' y complicado conseguir acentuar las vocales . Si el conjunto lo utilizara para edición de textos en español, podría tener un cierto problema, que solucionaría comprándome un teclado español.  Pero como el 'cacharro' lo he comprado para lo que lo he comprado, voy a tratar de remediar este inconveniente personalizando el teclado convenientemente y añadiéndole algunas funcionalidades más.
El teclado inalámbrico RC12 que vino junto al MK808 tiene el aspecto que muestra la siguiente imagen.

Desde mi punto de vista, el mayor problema de estos dispositivos radica en el modo de manejarlo, pues al no tener pantalla táctil, y no digamos si la tuviera, la mayoría de las aplicaciones que están desarrolladas para un móvil han sido desarrolladas pensando en una pantalla táctil, y son muy complicadas de utilizar con un teclado externo que pretenda simular la acción de los dedos sobre una pantalla táctil.
MUY IMPORTANTE:
Antes de continuar hay que tener en cuenta que para realizar todos los procedimientos que siguen, el dispositivo tiene que estar ROOTEADO. Este procedimiento ha sido probado en un sistema determinado, y que probablemente funcione sin mayores problemas en otro sistema Android. A pesar de ello, no me responsabilizo de los problemas que puedan surgir al aplicar lo que se indica en este blog.Los procedimientos que se indican en esta entrada del blog han funcionado en un sistema Android con versión 4.2.2. Probablemente funcione para versiones anteriores de Android 4.0 y superiores.
Como todo el mundo sabe, para encontrar en Google lo que nos interesa, hay que saber qué estamos buscando y cómo debemos preguntarle.
Lo primero que hice fue buscar en Internet si había alguna aplicación en Play Store que resolviese mi problema. Aunque no la he probado, parece existir una aplicación que personaliza los teclados externos - External Keyboard Helper Pro. Pero yo quería una solución que no fuera recurriendo a una aplicación.
Y el camino que seguí fue la de meterme en las entrañas del sistema operativo y ver la manera de alterar los drivers que manejan el teclado externo conectado al puerto USB. Sabía que el secreto estaba en el contenido de unos ficheros de configuración de los dispositivos externos que se conectan al sistema Android, con extensión .kcm y .kl, siglas de key character map y key layout, respectivamente. Y esto fue lo que busqué.
El primer enlace representativo que nos muestra la búsqueda en Google correspondió a http://source.android.com/devices/tech/input/overview.html en donde se describe el subsistema de entrada del sistema operativo Android. Ahí viene indicado claramente la existencia de los ficheros que gestionan los teclados externos y que son reconocidos por el sistema Android con unos nombres y unas ubicaciones bien determinados:

     /system/usr/keylayout/Vendor_XXXX_Product_XXXX_Version_XXXX.kl
     /system/usr/keychars/Vendor_XXXX_Product_XXXX_Version_XXXX.kcm
en donde las 'xxxx' hay que sustituirlas convenientemente, una vez averigüemos sus valores. En el enlace anterior me fue imposible encontrar el modo de averiguarlos. Indagando más, encontré los siguientes dos enlaces que fueron realmente los que me resolvieron la mayoría de las dudas y me permitieron personalizarlos ficheros convenientemente, casi como los quería:
Veamos el primer enlace. En él podemos encontrar el modo de averiguar los códigos de Vendedor, Producto y Versión que requerimos para definir los nombres de los ficheros. Tenemos varias opciones:
- Utilizar la herramienta ADB (Android Debug Bridge), que existe tanto para un sistema Windows como para un Linux. Yo utilizo UBUNTU 13.04 y tengo instalado el sistema de desarrollo de Android en Eclipse por lo que esta herramienta no tuve que instalarla pues se instala cuando instalamos el sistema de desarrollo de Android. Si no se dispone de ella, es cuestión de buscarla en Internet (pe http://www.keyables.com/2012/06/how-to-install-and-use-adb-tool.html), especificando ADB windows o ADB linux.
- Utilizar un emulador de terminal desde Android, por ejemplo, el Android Terminal Emulator desde el que podremos hacer más o menos lo mismo que haríamos si nos conectásemos al dispositivo mediante la herramienta ADB.
- Utilizar la aplicación ES Explorador de Archivos, u otra similar, desde el propio Android, con la que copiaremos, renombraremos, editaremos y daremos los permisos oportunos a estos dos ficheros.

Utilizando la herramienta ADB

Primero debemos conectar el dispositivo Android por USB o por WiFi, para que podamos acceder mediante la herramienta ADB. Iremos a Ajustes->Opciones de Desarrollo y marcaremos la opción Depuración USB. Seguidamente conectaremos el Android al PC.
Si nos conectamos por WiFi, debemos instalar una aplicación en el miniPC Android, ADB WiFi, la arrancamos y activamos pulsando sobre la cucaracha, que pasará de rojo a ser verde, y anotamos el mensaje con la IP que aparece (pe 192.168.1.25). Nos vamos al PC, y tecleamos la dirección IP que muestra el mensaje:

user@pc-desktop:~$adb connect 192.168.1.25
a partir de este punto el procedimiento es el mismo tanto para una conexión por USB o vía WiFi. Eso sí, si es por USB, no nos olvidemos de conectar el miniPC al PC :).
Accedemos al miniPC tecleando desde una ventana de comandos del PC lo siguiente:

user@pc-desktop:~$ adb shell
con lo que pasamos a ser un usuario del miniPC Android.

Utilizando un emulador de terminal desde Android

Una vez con lo instalado el emulador de terminal, lo arrancamos, y pasamos a ser usuario del miniPC Android, con lo que podremos manejarlo como en el caso anterior.
Tanto si utilizamos la herramienta ADB o el emulador de terminal, a partir de este momento será como si estuviéramos manejando un sistema Linux a nivel de comandos, por lo que si nos interesa ver el contenido de un determinado fichero, seguimos tecleando lo siguiente:

root@android:/ # cat /proc/bus/input/devices
...
I: Bus=0003 Vendor=0c45 Product=7403 Version=0100
N: Name="SONiX USB Device"
P: Phys=usb-usb20_host-1/input0
S: Sysfs=/devices/platform/usb20_host/usb2/2-1/2-1:1.0/input/input2
U: Uniq=
H: Handlers=sysrq kbd event2 keychord
B: PROP=0
B: EV=120013
B: KEY=10000 7 ff800000 7ff febeffdf ffefffff ffffffff fffffffe
B: MSC=10
B: LED=1f

I: Bus=0003 Vendor=0c45 Product=7403 Version=0100
N: Name="SONiX USB Device"
P: Phys=usb-usb20_host-1/input1
S: Sysfs=/devices/platform/usb20_host/usb2/2-1/2-1:1.1/input/input3
U: Uniq=
H: Handlers=kbd event3 keychord
B: PROP=0
B: EV=17
B: KEY=1f0000 0 2020000 3878 d801d001 1e0000000
B: REL=103
B: MSC=10
root@android:/ #
Si nos fijamos en los dos bloques mostrados, aparece la información que estoy buscando:
- el nombre del dispositivo "SONiX USB Device" (que realmente no necesitamos)
- El código del vendedor (Vendor=0c45)
- El código del producto (Product=7403)
- El código de la versión del producto (Version=0100) (que podemos, o no, considerar)
Podemos observar que estos dos bloques son muy similares. Uno corresponde al teclado y el otro al ratón externos, estando asociados a un mismo puerto USB, el puerto al que está conectado el RC12 (usb-usb20_host-1, input0 e input1).
Con estos datos, determinamos el nombre de los ficheros:

/system/usr/keylayout/Vendor_0c45_Product_7403.kl
/system/usr/keychars/Vendor_0c45_Product_7403.kcm
Ahora hay que definir el contenido de estos ficheros. Para ello partiremos de unos ficheros genéricos que encontraremos en el propio dispositivo Android y los copiaremos en el mismo lugar, asignándoles los nombres que hemos determinado:
root@android:/ # cd /system/usr/keylayout
root@android:/system/usr/keylayout # cp Generic.kl Vendor_0c45_Product_7403.kl
root@android:/system/usr/keylayout # cd /system/usr/keylayout
root@android:/system/usr/keychars # cp Generic.kcm Vendor_0c45_Product_7403.kcm
Si disponemos de un editor de textos en Android, podemos editar estos dos ficheros en el propio dispositivo Android. pero por comodidad es mejor copiarlos y editar en un PC:
user@pc-desktop:~$ adb pull /system/usr/keylayout/Vendor_0c45_Product_7403.kl
user@pc-desktop:~$ adb pull /system/usr/keychars/Vendor_0c45_Product_7403.kcm
Una vez los hayamos editado (ver siguiente apartado), y si lo hemos hecho externamente, desde un PC, los copiamos en el dispositivo Android, aplicando el siguiente procedimiento:

user@pc-desktop:~$ adb remount
user@pc-desktop:~$ adb push Vendor_0c45_Product_7403.kl /system/usr/keylayout/Vendor_0c45_Product_7403.kl
user@pc-desktop:~$ adb push Vendor_0c45_Product_7403.kcm /system/usr/keychars/Vendor_0c45_Product_7403.kcm
Con la primera instrucción, adb remount, conseguimos que la memoria del sistema operativo Android sea de lectura/escritura, y de este modo podemos copiar los ficheros en las carpetas correspondientes, indicadas en las dos siguientes instrucciones.

Utilizando el ES Explorador de Archivos

Con esta aplicación podemos hacer la mayoría de las acciones que hemos indicado en los párrafos anteriores:
- ver contenido de /proc/bus/input/devices, y al abrirlo para ver su contenido hay que considerarlo como un fichero tipo texto y abrirlo con el propio editor de texto del ES Explorador de Archivos.
- Anotar Vendor, Product, [Version]
- ir a /system/usr/keylayout/ y copiar el fichero Generic.kl y pegar en la misma carpeta asignándole el nombre apropiado, según hemos indicado en párrafos anteriores.
- ir a /system/usr/keychars/ y copiar el fichero Generic.kcm y pegar en la misma carpeta asignándole el nombre apropiado, según hemos indicado en párrafos anteriores.
- editar estos ficheros con el propio editor de textos del ES Explorador de Ficheros, considerando a estos ficheros de tipo texto.
- reiniciar el miniPC, y comprobar que el teclado externo RC12 funciona tal como deseábamos.

Edición de los ficheros kl y kcm

Ya hemos dicho que Android utiliza dos ficheros, con extensiones kl y kcm, para mapear las teclas físicas de un teclado a los caracteres que llegan a las aplicaciones:

teclado >>> fichero [.kl] >>> fichero [.kcm] >>> aplicación

El fichero kl

El teclado asocia un código -scancode- a cada una de sus teclas físicas, código que determina una línea del fichero kl:

...
key 28    ENTER
key 29    CTRL_LEFT
key 30    A
key 31    S
key 32    D
key 33    F
key 34    G
key 35    H
...
key 102   HOME  WAKE
key 158   BACK  WAKE_DROPPED
...
Si pulsamos la tecla 28, el fichero kl asociará la etiqueta ENTER a dicha tecla física. Y si es la tecla 30 la que pulsamos, la etiqueta asociada será la A. Y así para el resto de las teclas. Además de la etiqueta, la línea podrá completarse con un modificador, WAKE o WAKE_DROPPED. Estos modificadores activan el teclado 'dormido', y envía la tecla pulsada o descarta la tecla pulsada, respectivamente.
Para poder averiguar los códigos -scancodes, con o sin modificadores- se puede utilizar una aplicación de Android que nos los vaya mostrando en la pantalla del dispositivo android. Por ejemplo en Play Store podemos encontrar la aplicación KeyEvent Display, o también otra, KeyTest.apk, que podemos descargar e instalar.

El fichero kcm

Una vez conocida la etiqueta asociada, si abrimos el fichero kcm podemos observar el bloque asociado a la etiqueta A:

...
key A {
  label:            'A'
  base:             'a'
  shift, capslock:  'A'
}
...
Vemos que el bloque consta de varias líneas encerradas entre llaves '{}'. De forma general, un bloque es de la siguiente manera:
# cualquier comentario empieza por el carácter almohadilla
key [etiqueta] {
    label:                          '[etiqueta de la tecla]'
    base:                           '[tecla sin modificador]'
    [modificador]:                  '[tecla con modificador]'
    [modificador]+[modificador]:    '[tecla con ambos modificadores simultáneos]'
    [modificador],[modificador]:    '[tecla con algún modificador de entre los indicados]'
    [modificador]:                   fallback [tecla mágica] 
    [modificador],[modificador]:     none
}
Un [modificador] puede tomar, entre otros, los siguientes valores: ralt, lalt, alt (tecla ALT dcha/izda/indistinta) , rshift, lshift, shift (tecla SHIFT dcha/izda/indistinta) , rctrl, lctrl, ctrl (tecla CTRL dcha/izda/indistinta) , capslock, y rmeta, lmeta, meta (tecla WIN dcha/izda/indistinta) si existiera la tecla WIN.
Ambos ficheros utilizan solo caracteres ANSI. Por tanto, cualquier carácter específico de un idioma deberá indicarse por sus equivalente hexadecimal '\uXXXX', según el estándar de codificación UNICODE. En http://en.wikipedia.org/wiki/List_of_Unicode_characters podemos encontrar la lista de todos los caracteres UNICODE.
Las teclas mágicas son aquellas que al pulsarlas nos activan una de las funciones, o aplicación, predeterminada de Android. Por ejemplo, el siguiente contenido del fichero kcm asociaría las teclas funcionales F10, F11 y F12 a las funciones de SILENCIAR VOLUMEN , BAJAR VOLUMEN y SUBIR VOLUMEN, respectivamente.
  ...
key F10 {
    base:               fallback VOLUME_MUTE
}
key F11 {
    base:               fallback VOLUME_DOWN
}
key F12 {
    base:               fallback VOLUME_UP
}
... 
En el fichero Generic.kl pueden encontrarse la mayoría de las etiquetas que pueden utilizarse después del modificador fallback.

Caso práctico


Es un teclado para el mercado inglés y, por tanto, no tenemos grabadas en las teclas los caracteres específicos de nuestra lengua, la Ñ, ni el modo de acentuar las vocales, ni otros signos de puntuación utilizados por nosotros. Este teclado tampoco respondía a las funciones asociadas a las teclas funcionales.
Para añadirle toda esta funcionalidad, vamos a modificar los dos ficheros como se muestra en los siguientes párrafos.
En el fichero kcm dejaremos las líneas correspondientes a las teclas indicadas como se muestra a continuación:
...
key 68      VOLUME_MUTE       WAKE
key 87      VOLUME_DOWN       WAKE
key 88      VOLUME_UP         WAKE
... 
En el fichero kl dejaremos modificados los siguientes bloques:
...
key C {
    label:                'C'
    base:                 'c'
    shift, capslock:      'C'
    alt:                  '\u00e7'   # cedilla minúscula
    shift+alt:            '\u00c7'   # cedilla mayúscula
}
key E {
    label:                'E'
    base:                 'e'
    shift, capslock:      'E'
    alt:                  '\u0301'   # acento agudo en siguiente letra vocal
}
key I {
    label:                'I'
    base:                 'i'
    shift, capslock:      'I'
    alt:                  '\u0302'   # acento circunflejo en siguiente letra vocal
}
key N {
    label:                'N'
    base:                 'n'
    shift, capslock:      'N'
    alt:                  '\u0303'   # signo virgulilla sobre letra n/N
}
key S {
    label:                'S'
    base:                 's'
    shift, capslock:      'S'
    alt:                  '\u00df'   # letra beta (griega)
}
key U {
    label:                'U'
    base:                 'u'
    shift, capslock:      'U'
    alt:                  '\u0308'   # acento diéresis en siguiente letra vocal
}
key 4 {
    label:                '4'
    base:                 '4'
    shift:                '$'
    alt:                  '\u20ac'   # simbolo del EURO
}
key 6 {
    label:                '6'
    base:                 '6'
    shift:                '^'
    alt+shift:            '\u0302'   # acento circunflejo en siguiente letra vocal
}
key SPACE {
    label:                ' '
    base:                 ' '
    shift:                fallback HOME
    alt, meta:            fallback SEARCH
    ctrl:                 fallback LANGUAGE_SWITCH
}
key ESCAPE {
    base:                 fallback BACK
    alt, meta:            fallback HOME
    ctrl:                 fallback MENU
}
key F1 {
    base:                 fallback MENU
}
key F2 {
    base:                 fallback EXPLORER
}
key F3 {
    base:                 fallback SEARCH
}
key F4 {
    base:                 fallback HOME
}
key F5 {
    base:                 fallback ENVELOPE
}
key F6 {
    base:                 fallback MUSIC
}
key F7 {
    base:                 fallback MEDIA_PREVIOUS
}
key F8 {
    base:                 fallback MEDIA_PLAY_PAUSE
}
key F9 {
    base:                 fallback MEDIA_NEXT
}
key F10 {
    base:                 fallback VOLUME_MUTE
}
key F11 {
    base:                 fallback VOLUME_DOWN
}
key F12 {
    base:                 fallback VOLUME_UP
}
...
En la imagen inferior se muestran las teclas que han sido alteradas para darle la funcionalidad que queríamos y que corresponden con el listado anterior.
Una vez hayamos realizado todos los cambios en los ficheros kl y kcm, los hayamos copiado a las carpetas correspondientes, deberemos de asignarles unos permisos para que puedan ser utilizados por el sistema Android:
user@pc-desktop:~$ adb shell
root@android:/ # chmod 644 /system/usr/keychars/Vendor_0c45_Product_7403.kcm
root@android:/ # chmod 644 /system/usr/keylayout/Vendor_0c45_Product_7403.kl
Una vez llegados aquí, deberemos reiniciar el sistema Android, y si no nos hemos equivocado, el teclado externo funcionará como deseábamos.
Los siguientes enlaces corresponden a los ficheros generados y utilizados en mi sistema multimedia Android, conforme a la disposición que aparece en la imagen anterior.
Quedan algunas cosas pendientes de resolución, que en una futura entrada trataré de incluir. Por ejemplo, de qué manera invocamos aplicaciones específicas al pulsar una tecla funcional o tecla y modificador.