Vés al contingut

Android/IME

Que és un IME?

[modifica]

Un 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

[modifica]

A 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

[modifica]

Per 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

[modifica]

Per 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ó

[modifica]

Tenim 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

[modifica]

Em 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.

Combinacions
(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

[modifica]

Es 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

[modifica]

Per 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

Codis per números i lletres
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
Codis per caràcters modificadors
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

Referència(Android developers)

Com crear el nostre propi IME

[modifica]

Per a poder crear el nostre IME, haurem de seguir una sèrie de pasos, els quals son els següents:

  1. Editar AndroidManifest.xml
  2. Crear l'arxiu metode.xml
  3. Editar strings.xml
  4. Definir el disseny del teclat
  5. Definir les tecles del teclat
  6. Crear una nova classe Java
  7. Provar el teclat

1. Editar AndroidManifest.xml

[modifica]

Un 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

[modifica]

L'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

[modifica]

Ara em de modificar res/values/strings.xml per tal de definir el següent:

  1. El nom de l'aplicació
  2. L'etiqueta de l'IME
  3. 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

[modifica]

El 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

[modifica]

Els detalls de les tecles del teclat i les seves posicions s'especifiquen en un arxiu XML. Cada tecla té els següents atributs:

  1. keyLabel: Aquest atribut conté el text que es mostra en pantalla.
  2. 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

[modifica]

Crea 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:

  1. Un KeyboardView que fà referència a la vista definida en el disseny.
  2. Un Keyboard que s'assignarà a KeyboardView.
  3. 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:

  1. commitText: per afegir un o més caràcters al camp d'entrada.
  2. deleteSurroundingText: per esborrar un o més caràcters del camp d'entrada.
  3. 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.

  1. Si el codi és KEYCODE_DELETE, s'elimina un caràcter a l'esquerra del cursor utilitzant el mètode deleteSurroundingText.
  2. 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.
  3. 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

[modifica]

Finalment 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!

Referències

[modifica]