Android/IME
Que és un IME?
modificaUn editor de mètodes d’entrada(IME) és quelcom que permet als usuaris introduïr text a la nostra aplicació. Android proporciona als usuaris un mètode d’entrada de text alternatiu, tal com els teclats lògics o bé l’entrada de veu. Així, els usuaris poden instal·lar els IME o teclats que vulguin i utilitzar-los indiscriminadament, tenint en compte que només es pot tenir habilitat un tipus d'IME a la vegada.
Hi ha dos tipus de teclats: físics o lògics. En els teclats físics (com per exemple un teclat hardware connectat directament al dispositiu) utilitzarem el mètode KeyEvent, en canvi, en els lògics (una emulació de teclat físic) utilitzarem el mètode actionId. Per tant, em de tenir en compte quin és el tipus de teclat que volem fer servir i monotoritzar, ja que estarem capturant events diferents.
El cicle de vida d'un IME
modificaA continuació podeu veure un diagrama que representa el cicle de vida d'un IME:
- onCreate(): on s'inicialitza la nostra activity
- onCreateInputView(): crea i retorna la jerarquia de la vista utilitzada per a l'àrea d'entrada de text
- onCreateCandidatesView(): crea i retorna la jerarquia de la vista utilitzada per mostrar candidats
- onSartInputView(): es crida quan la vista d'entrada de text s'està mostrant i s'ha començat una nova entrada de text a un altre editor
- getCurrentMethodInputSubtype(): retorna el subtipus d'entrada de text utilitzat actualment
- onFinishInput(): es cridada quan l'entrada de text s'amaga de la vista de l'usuari
- onDestroy(): fa una neteja de l'activity abans que aquesta es destrueixi
Tipus de teclats
modificaPer definir el tipus de teclat que volem utilitzar, ho podem fer mitjançant l'atribut android:inputType del widget desitjat. Podem trobar una gran varietat de valors possibles, però els més utilitzats son els següents:
- text: mostra un teclat que ens permet introduïr text.
- textPassword: mostra un teclat que ens permet introduïr text, però aquest no es veu al camp del widget corresponent.
- number: mostra un teclat on només hi ha números.
- numberPassword: mostra un teclat on només hi ha números però els amaga al camp del widget corresponent.
- phone: mostra un teclat on podem trobar números i símbols.
- date: mostra un teclat on hi ha números i símbols habituals de les dates.
- textEmailAddress: mostra un teclat el qual ens permet escriure més fàcilment una adreça de correu.
Tecles
modificaPer tenir control sobre les tecles que l'usuari ha pogut prémer, s'ha d'especificar al fitxer xml on es defineix el nostre layout l'atribut android:KeyEvent al respectiu Widget(editText per exemple). Els valors que més s'utilitzen i pot prendre aquest atribut són els següents:
- ACTION_DOWN: la tecla s'ha premut.
- ACTION_MULTIPLE: múltiples "key events" estan ocurrint un darrere de l'altre.
- ACION_UP: la tecla ja no està premuda.
- KEYCODE_X: X pot tenir diferents valors, els quals es troben definits en aquesta secció.
Tecla d'acció
modificaTenim un atribut pels IME, anomenat android:imeOptions, el qual permet modificar la tecla d'acció d'acord amb la funció del nostre teclat. La tecla d'acció és una tecla que acostuma a apareixer a la cantonada dreta de la part baixa de la pantalla i es un botó, que depenent de quin tipus d'IME estiguem utilitzant, ens servirà per fer una cosa o una altra. D'aquesta manera podem integrar millor l'IME a l'aplicació que estem utilitzant. Alguns dels valors que pot prendre aquest atribut són els següents:
- normal: cap semàntica especificada.
- actionGo: fa que la tecla d'acció sigui un Go. Per exemple s'utilitza en les URL.
- actionSearch: fa que la tecla d'acció sigui una lupa o Search, portant a l'usuari als resultats de la cerca.
- actionSend: fa que la tecla d'acció sigui un Send, enviant el text al target específic.
- actionNext: fa que la tecla d'acció sigui un Next, portant l'usuari al següent camp que admeti entrada de text.
- actionPrevious: fa que la tecla d'acció sigui un Previous, portant l'usuari a l'anterior camp que admeti entrada de text.
- actionDone: fa que la tecla d'acció sigui un Done, on seguidament es tanca el teclat.
Combinacions possibles
modificaEm fet diverses proves sobre l'API 25 d'Android (7.1 Nougat) sobre les diferents combinacions possibles entre els atributs d'un mateix IME.
Em treballat amb diferents permutacions dels següents atributs de configuració a l'xml.
<EditText
android:inputType="Text"
android:imeOptions="actionGo"
android:password="false"
android:phoneNumber="false"
android:imeActionLabel="Go"
/>
I, per provar-ho, em fet el següent codi java per a capturar l'event del "go":
new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
return newContent(v, actionId, event);
}
}
public boolean newContent(TextView v, int actionId, KeyEvent event){
if(event != null){
return manage_hard(event);
}
else {
return manage_soft(actionId);
}
}
private boolean manage_hard(KeyEvent event){
if(event.getAction() == KeyEvent.ACTION_UP){
set_text();
return true;
}
return true;
}
private boolean manage_soft(int actionId){
if(actionId == EditorInfo.IME_ACTION_GO){
set_text();
return true;
}
return false;
}
I els resultats han estat els següents:
- Per començar parlarem de l'atribut android:password. Aquest atribut és bastant curiós ja que, fiquem les combinacions que fiquem, sempre funciona i l'únic que fa és ocultar el text que escriu l'usuari en temps real en forma d'asteriscs(*).
- Cal dir, també, que l'atribut android:phoneNumber posa el teclat en mode trucada o sms (veure fotografia) sols si no tenim definit l'atribut android:inputType. En el cas que estigui definit inputType, aquest últim pren el control i té total prioritat sobre phoneNumber.
- Sobre imeActionLabel cal comentar que tan sols modifica el nom del botó "submit" quan el mòbil està en posició landscape (horitzontal). Si no li donem valor (array buit) sols mostrarà el botó buit però funciona igualment. L'únic que em de tenir en compte és que per defecte no vincula cap actionId (integer) al botó i, per tant, no es pot capturar l'event. Perquè funcioni correctament necessita de l'imeOptions o l'imeActionId (que li donarà el número que li passesim per paràmetre).
A continuació en veurem un exemple de imeActionLabel amb imeActionId i com capturaríem l'event:
<EditText
android:imeActionLabel="Finalitzat"
android:imeActionId="10100"
/>
i per capturar l'event hauríem d'afegir el següent a la funció manage_soft:
if(actionId == 10100){
set_text();
return true;
}
Cal afegir que cada imeOptions té un label predefinit, si utilitzem juntament imeOptions i imeActionLabel aquest últim té preferència i substituirà el valor per efecte de l'options. El mateix passarà amb imeActionId.
- Dit això podem analitzar el comportament de les dues variables restants deixant de banda el password, phoneNumber i imeActionLabel ja que el comportament l'em explicat abans i no varien els resultats. A la següent taula podem veure les permutacions de imeOptions i com capturar satisfactòriament l'event generat per tal que l'EditText faci quelcom.
(xml) Valor d'imeOptions | (java) Codificació de l'event (#actionId) |
---|---|
actionGo | IME_ACTION_GO (0x00000002) |
actionSearch | IME_ACTION_SEARCH (0x00000003) |
actionSend | IME_ACTION_SEND (0x00000004) |
actionNext | IME_ACTION_NEXT (0x00000005) |
actionDone | IME_ACTION_DONE (0x00000006) |
actionPrevious | IME_ACTION_PREVIOUS (0x00000007) |
Dit tot l'anterior em de mencionar que l'atribut inputType té preferència per sobre de phoneNumber però, al mateix temps, és fàcilment modificat per tots els altres atributs mencionants anteriorment. Però, el més important, és que totes les combinacions d'atributs són possibles a excepció dels casos anomenats amb anterioritat.
Exemple d'un teclat lògic en un xml
modificaEs poden definir diferents Keyboard per a un mateix IME (en diferents fitxers XML) d'aquesta manera podem fer referència a un Keyboard per a landscape i un de diferent per a portrait o també diferents Keyboards per a diferents tipus d'entrada com per exemple Text, Number, Mail,...
A continuació podem observar un petit exemple d'un Keyboard simple, pensat per a tipus d'entrada Number
<?xml version="1.0" encoding="utf-8"?>
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
android:keyWidth="12.50%p"
android:keyHeight="7%p" >
<Row>
<Key android:codes="67" android:keyLabel="Esborra" android:keyEdgeFlags="left" />
<Key android:codes="144" android:keyLabel="0" />
<Key android:codes="82" android:keyLabel="Menú" android:keyEdgeFlags="right" />
</Row>
<Row>
<Key android:codes="145" android:keyLabel="1" android:keyEdgeFlags="left" />
<Key android:codes="146" android:keyLabel="2" />
<Key android:codes="147" android:keyLabel="3" android:keyEdgeFlags="right" />
</Row>
<Row>
<Key android:codes="148" android:keyLabel="4" android:keyEdgeFlags="left" />
<Key android:codes="149" android:keyLabel="5" />
<Key android:codes="150" android:keyLabel="6" android:keyEdgeFlags="right" />
</Row>
<Row>
<Key android:codes="151" android:keyLabel="7" android:keyEdgeFlags="left" />
<Key android:codes="152" android:keyLabel="8" />
<Key android:codes="153" android:keyLabel="9" android:keyEdgeFlags="right" />
</Row>
</Keyboard>
Taula de codificació d'events de diferents tecles d'android
modificaPer fer un teclat (Keyboard) virtual necessitarem saber quins missatges enviar per cada lletra; a continuació ficarem una referencia dels codis que considerem més rellevants a l'hora de crear un nou teclat lògic que pot interpretar de forma automàtica l'android
Tecla | Codificació (int|hex) | Nom de la constant | Tecla | Codificació (int|hex) | Nom de la constant |
---|---|---|---|---|---|
0 | 7 0x00000007 | KEYCODE_0 | 0 numeric | 144 0x00000090 | KEYCODE_NUMPAD_0 |
1 | 8 0x00000008 | KEYCODE_1 | 1 numeric | 145 0x00000091 | KEYCODE_NUMPAD_1 |
2 | 9 0x00000009 | KEYCODE_2 | 2 numeric | 146 0x000000902 | KEYCODE_NUMPAD_2 |
3 | 10 0x000000A | KEYCODE_3 | 3 numeric | 147 0x0000093 | KEYCODE_NUMPAD_3 |
4 | 11 0x0000000B | KEYCODE_4 | 4 numeric | 148 0x00000094 | KEYCODE_NUMPAD_4 |
5 | 12 0x0000000C | KEYCODE_5 | 5 numeric | 149 0x00000095 | KEYCODE_NUMPAD_5 |
6 | 13 0x0000000D | KEYCODE_6 | 6 numeric | 150 0x00000096 | KEYCODE_NUMPAD_6 |
7 | 14 0x0000000E | KEYCODE_7 | 7 numeric | 151 0x00000097 | KEYCODE_NUMPAD_7 |
8 | 15 0x0000000F | KEYCODE_8 | 8 numeric | 152 0x00000098 | KEYCODE_NUMPAD_8 |
9 | 16 0x00000010 | KEYCODE_9 | 9 numeric | 153 0x00000099 | KEYCODE_NUMPAD_9 |
A | 29 0x0000001D | KEYCODE_A | B | 30 0x0000001E | KEYCODE_B |
C | 31 0x0000001F | KEYCODE_C | D | 32 0x00000020 | KEYCODE_D |
E | 33 0x00000021 | KEYCODE_E | F | 34 0x00000022 | KEYCODE_F |
G | 35 0x00000023 | KEYCODE_G | H | 36 0x00000024 | KEYCODE_H |
I | 37 0x00000025 | KEYCODE_I | J | 38 0x00000026 | KEYCODE_J |
K | 39 0x00000027 | KEYCODE_K | L | 40 0x00000028 | KEYCODE_L |
M | 41 0x00000029 | KEYCODE_M | N | 42 0x0000002A | KEYCODE_N |
O | 43 0x0000002B | KEYCODE_O | P | 44 0x0000002C | KEYCODE_P |
Q | 45 0x0000002D | KEYCODE_Q | R | 46 0x0000002E | KEYCODE_R |
S | 47 0x0000002F | KEYCODE_S | T | 48 0x00000030 | KEYCODE_T |
U | 49 0x00000031 | KEYCODE_U | V | 50 0x00000032 | KEYCODE_V |
W | 51 0x00000033 | KEYCODE_W | X | 52 0x00000034 | KEYCODE_X |
Y | 53 0x00000035 | KEYCODE_Y | Z | 54 0x00000036 | KEYCODE_Z |
Espai | 62 0x0000003E | KEYCODE_SPACE | enter | 66 0x00000042 | KEYCODE_ENTER |
; | 74 0x0000004A | KEYCODE_SEMICOLON | # | 18 0x00000012 | KEYCODE_POUND |
. | 56 0x00000038 | KEYCODE_PERIOD | - | 69 0x00000045 | KEYCODE_MINUS |
, numeric | 159 0x0000009F | KEYCODE_NUMPAD_COMMA | . numeric | 158 0x0000009E | KEYCODE_NUMPAD_DOT |
Enter numeric | 160 0x000000A0 | KEYCODE_NUMPAD_ENTER |
Tecla | Codificació (int|hex) | Nom de la constant |
---|---|---|
Alt esquerre | 57 0x00000039 | KEYCODE_ALT_LEFT |
Alt dret | 58 0x0000003A | KEYCODE_ALT_RIGHT |
Bloqueig de majúscules | 115 0x00000073 | KEYCODE_CAPS_LOCK |
Control esquerre | 113 0x00000071 | KEYCODE_CTRL_LEFT |
Control dret | 114 0x00000072 | KEYCODE_CTRL_RIGHT |
Com crear el nostre propi IME
modificaPer a poder crear el nostre IME, haurem de seguir una sèrie de pasos, els quals son els següents:
- Editar AndroidManifest.xml
- Crear l'arxiu metode.xml
- Editar strings.xml
- Definir el disseny del teclat
- Definir les tecles del teclat
- Crear una nova classe Java
- Provar el teclat
1. Editar AndroidManifest.xml
modificaUn teclat per pantalla es considerat com un Input Method Editor (IME), el qual s'ha de declarar com a service dins del nostre arxiu AndroidManifest.xml que utilitza el permis BIND_INPUT_METHOD i respon a l'acció android.view.InputMethod.
Per tal d'introduir aquest servei al Manifest haurem d'afegir les següents linies de codi:
<service android:name=".IME"
android:label="@string/ime"
android:permission="android.permission.BIND_INPUT_METHOD">
<meta-data
android:name="android.view.im"
android:resource="@xml/metode" />
<intent-filter>
<action android:name="android.view.InputMethod" />
</intent-filter>
</service>
- android:name --> Especifica un "identificador" per al nostre ime - android:label --> Especifica el nom que es mostra a l'usuari del nostre IME - android:permission --> Com ja em esmentat, li em de donar el permís al servei per a què android el reconegui com a tal - intent-filter --> Tot el que hi ha dins d'aquest tag és per definir el servei com un InputMethod - <meta-data android:name="android.view.im" android:resource="@xml/metode" /> --> Defineix la ruta a la definició del nostre IME en si (el layout on trobarem els botons definits)
Opcionalment, si volem, podem crear una activity que s'encarregarà de mostrar les opcions del nostre IME (per canviar d'idiomes, reportar bugs,...) També l'hauríem de declarar al manifest:
<!-- activity per a ficar els settings || OPCIONAL -->
<activity
android:name=".IME_options_Activity"
android:label="@string/IME_settings">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
</intent-filter>
</activity>
2. Crear l'arxiu metode.xml
modificaL'etiqueta service de l'arxiu de Manifest conté una etiqueta anomenada meta-data que fa referència a un arxiu XML anomenat metode.xml. Sense aquest arxiu, el nostre sistema operatiu Android no podria reconèixer el nostre service com un servei IME vàlid.
Aquest arxiu conté detalls com el mètode d'entrada i els seus subtipus. Nosaltres definirem un subtipus simple per la configuració regional es_ES.
Si no tens el directori res/xml, crea'l i a continuació afegeix l'arxiu metode.xml que tindrà que contenir el següent:
<?xml version="1.0" encoding="utf-8"?>
<input-method xmlns:android="http://schemas.android.com/apk/res/android">
<subtype
android:label="@string/subtype_es"
android:imeSubtypeLocale="es_ES"
android:imeSubtypeMode="keyboard" />
</input-method>
- android:imeSubtypeLocale="es_ES" --> Especifica quin és el subtipus de teclat segons l'idioma.
3. Editar strings.xml
modificaAra em de modificar res/values/strings.xml per tal de definir el següent:
- El nom de l'aplicació
- L'etiqueta de l'IME
- L'etiqueta del subtipus de l'IME
Per fer aixó modifica strings.xml de la següent manera:
<resources>
<string name="app_name">IME Keyboard</string>
<string name="ime">IME</string>
<string name="subtype_es">Español</string>
</resources>
4. Definir el disseny del teclat
modificaEl disseny del nostre teclat unícament conté un KeyboardView. També em configurat l'atribut layout_alignParentBottom a true per tal de que el nostre teclat aparegui a la part inferior de la pantalla.
Crea un arxiu amb el nom keyboard.xml dins de res/layout i afegeix les següents linies de codi:
<?xml version="1.0" encoding="UTF-8"?>
<android.inputmethodservice.KeyboardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/keyboard"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:keyPreviewLayout ="@layout/preview"
/>
El keyPreviewLayout és el disseny de la pantalla emergent cada cop que una tecla es pulsada. Aquest conté un únic TextView. Crea l'arxiu preview.xml dins del directori res/layout i afegeix el següent codi:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:background="#ffff00"
android:textStyle="bold"
android:textSize="30sp"
>
</TextView>
5. Definir les tecles del teclat
modificaEls detalls de les tecles del teclat i les seves posicions s'especifiquen en un arxiu XML. Cada tecla té els següents atributs:
- keyLabel: Aquest atribut conté el text que es mostra en pantalla.
- codes: Aquest atribut conté els valors unicode dels caràcters representats per la tecla.
També podem trobar altres atributs com per exemple keyEdgeFlags, que s'afegeix a les tecles que es troben més a l'esquerra o més a la dreta, i el qual pot tenir el valor left o right.
Per exemple per definir la tecla "A", al l'atribut keyLabel li hauriem d'assignar el valor A i a l'atribut codes el valor 97.
ihaurà casos en que una tecla tingui assignats més d'un codi, en aquest cas conforme es vagi pulsant la tecla, el valor mostrat per pantalla canviarà segons l'ordre dels codis assignats a aquesta tecla.
Ara passarem a dissenyar el nostre teclat, el qual dividirem en 5 files, amb unes tecles de tamany 60dp d'altura i 48dp d'amplada. Les files estaràn distribuides de la següent manera:
- Fila 1: números
- Files 2, 3, 4: lletres i símbols
- Fila 5: tecles especials
Per fer aixó haurem de crear un nou arxiu anomenat teclat.xml dins del directori res/xml amb el contingut següent:
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
android:keyWidth="10%p"
android:horizontalGap="0px"
android:verticalGap="0px"
android:keyHeight="60dp"
>
<Row>
<Key android:codes="49" android:keyLabel="1" android:keyEdgeFlags="left"/>
<Key android:codes="50" android:keyLabel="2"/>
<Key android:codes="51" android:keyLabel="3"/>
<Key android:codes="52" android:keyLabel="4"/>
<Key android:codes="53" android:keyLabel="5"/>
<Key android:codes="54" android:keyLabel="6"/>
<Key android:codes="55" android:keyLabel="7"/>
<Key android:codes="56" android:keyLabel="8"/>
<Key android:codes="57" android:keyLabel="9"/>
<Key android:codes="48" android:keyLabel="0" android:keyEdgeFlags="right"/>
</Row>
<Row>
<Key android:codes="113" android:keyLabel="q" android:keyEdgeFlags="left"/>
<Key android:codes="119" android:keyLabel="w"/>
<Key android:codes="101" android:keyLabel="e"/>
<Key android:codes="114" android:keyLabel="r"/>
<Key android:codes="116" android:keyLabel="t"/>
<Key android:codes="121" android:keyLabel="y"/>
<Key android:codes="117" android:keyLabel="u"/>
<Key android:codes="105" android:keyLabel="i"/>
<Key android:codes="111" android:keyLabel="o"/>
<Key android:codes="112" android:keyLabel="p" android:keyEdgeFlags="right"/>
</Row>
<Row>
<Key android:codes="97" android:keyLabel="a" android:keyEdgeFlags="left"/>
<Key android:codes="115" android:keyLabel="s"/>
<Key android:codes="100" android:keyLabel="d"/>
<Key android:codes="102" android:keyLabel="f"/>
<Key android:codes="103" android:keyLabel="g"/>
<Key android:codes="104" android:keyLabel="h"/>
<Key android:codes="106" android:keyLabel="j"/>
<Key android:codes="107" android:keyLabel="k"/>
<Key android:codes="108" android:keyLabel="l"/>
<Key android:codes="35,64" android:keyLabel="\# \@" android:keyEdgeFlags="right"/>
</Row>
<Row>
<Key android:codes="-1" android:keyLabel="CAPS" android:keyEdgeFlags="left"/>
<Key android:codes="122" android:keyLabel="z"/>
<Key android:codes="120" android:keyLabel="x"/>
<Key android:codes="99" android:keyLabel="c"/>
<Key android:codes="118" android:keyLabel="v"/>
<Key android:codes="98" android:keyLabel="b"/>
<Key android:codes="110" android:keyLabel="n"/>
<Key android:codes="109" android:keyLabel="m"/>
<Key android:codes="46" android:keyLabel="."/>
<Key android:codes="63,33,58" android:keyLabel="\? ! :" android:keyEdgeFlags="right"/>
</Row>
<Row android:rowEdgeFlags="bottom">
<Key android:codes="44" android:keyLabel="," android:keyWidth="10%p" android:keyEdgeFlags="left"/>
<Key android:codes="47" android:keyLabel="/" android:keyWidth="10%p" />
<Key android:codes="32" android:keyLabel="SPACE" android:keyWidth="40%p" android:isRepeatable="true"/>
<Key android:codes="-5" android:keyLabel="DEL" android:keyWidth="20%p" android:isRepeatable="true"/>
<Key android:codes="-4" android:keyLabel="DONE" android:keyWidth="20%p" android:keyEdgeFlags="right"/>
</Row>
</Keyboard>
Alguns valors negatius que poden apareixer a les tecles son valors predefinits de la classe Keyboard. Per exemple, el valor -5 es igual al valor Keyboard.KEYCODE_DELETE.
6. Crear una classe Java
modificaCrea una nova classe Java i posa-li de nom IME.java. Aquesta haurà de ser extessa a la classe InputMethodService i implementar l'interfície KeyboardView.OnKeyboardActionListener. Aquesta interfície conté tots els mètodes que s'invoquen quan les tecles del teclat son presionades.
Dins d'aquesta classe declararem tres atributs privats:
- Un KeyboardView que fà referència a la vista definida en el disseny.
- Un Keyboard que s'assignarà a KeyboardView.
- Un boolean que ens dirà si tenim les majúscules activades o no.
Després de declarar aquestes variables, el codi de la classe IME.java hauria de ser aquest:
package com.example.adrian.myapplication;
import android.inputmethodservice.InputMethodService;
import android.inputmethodservice.Keyboard;
import android.inputmethodservice.KeyboardView;
import android.media.AudioManager;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.InputConnection;
/**
* Created by Adrian on 2/10/17.
*/
public class IME extends InputMethodService implements KeyboardView.OnKeyboardActionListener {
private KeyboardView keyboardView;
private Keyboard keyboard;
private boolean mayuscula = false;
@Override
public void onKey(int primaryCode, int[] keyCodes) {
}
@Override
public void onPress(int primaryCode) {
}
@Override
public void onRelease(int primaryCode) {
}
@Override
public void onText(CharSequence text) {
}
@Override
public void swipeDown() {
}
@Override
public void swipeLeft() {
}
@Override
public void swipeRight() {
}
@Override
public void swipeUp() {
}
}
Un cop es crea el teclat, s'invoca al mètode onCreateInputView. És allà on podem inicialitzar totes les variables. Afegeix la següent funció al codi:
@Override
public View onCreateInputView() {
keyboardView = (KeyboardView) getLayoutInflater().inflate(R.layout.keyboard, null);
keyboard = new Keyboard(this, R.xml.teclado);
keyboardView.setKeyboard(keyboard);
keyboardView.setOnKeyboardActionListener(this);
return keyboardView;
}
Per últim modificarem el mètode onKey per a que la nostra aplicació del teclat pugui comunicar-se amb els camps d'entrada de les altres aplicacions, a través d'un EditText per exemple.
El mètode getCurrentInputConnection s'utilitza per obtenir una connexió al camp d'entrada d'una altra aplicació. Un cop existeixi aquesta connexió podem utilitzar els següents mètodes:
- commitText: per afegir un o més caràcters al camp d'entrada.
- deleteSurroundingText: per esborrar un o més caràcters del camp d'entrada.
- sendKeyEvent: per enviar events, com KEYCODE_ENTER, a l'aplicació externa.
Cada cop que l'usuari prem una tecla, s'invoca al mètode onKey amb el valor unicode de la tecla com a un del seus paràmetres, i segons el qual es decidirà que s'ha de fer.
- Si el codi és KEYCODE_DELETE, s'elimina un caràcter a l'esquerra del cursor utilitzant el mètode deleteSurroundingText.
- Si el codi és KEYCODE_SHIFT, el valor de la variable mayuscula canvia el seu valor i l'estat de la tecla shift del teclat s'actualitza utilitzant el mètode setShifted. Un cop s'ha pres aquesta tecla, el teclat necessita ser tornat a dibuixar per tal de que les lletres apareguin correctament. Per tornar a dibuixar totes les tecles s'utilirza el mètode invalidateAllKeys.
- Per a la resta de codis, cadascun es converteix en un caràcter i s'envia al camp d'entrada. Si el codi representa una lletra de l'alfabet i la variable mayuscula té el valor true, llavors el caràcter es converteix en majúscula.
Per últim, cap actualitzar el métode onKey per tal de que quedi d'aquesta manera:
@Override
public void onKey(int primaryCode, int[] keyCodes) {
InputConnection ic = getCurrentInputConnection();
playClick(primaryCode);
switch(primaryCode){
case Keyboard.KEYCODE_DELETE :
ic.deleteSurroundingText(1, 0);
break;
case Keyboard.KEYCODE_SHIFT:
mayuscula = !mayuscula;
keyboard.setShifted(mayuscula);
keyboardView.invalidateAllKeys();
break;
case Keyboard.KEYCODE_DONE:
ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER));
break;
default:
char code = (char)primaryCode;
if(Character.isLetter(code) && mayuscula){
code = Character.toUpperCase(code);
}
c.commitText(String.valueOf(code),1);
}
}
7. Provar el teclat
modificaFinalment passarem a provar el nostre teclat. Per a fer-ho, compilem i executem en el nostre mòbil Android, però primer em d'anar a Settings -> Language & Input i activar el nostre teclat, el qual li vam posar de nom Nou IME. Després, obrim una aplicació que contingui una entrada de text i, en clicar, veurem el nostre teclat!