Eingabemethode erstellen

Ein Eingabemethoden-Editor (IME) ist ein Steuerelement, mit dem Nutzer Text eingeben können. Android bietet ein erweiterbares Framework für Eingabemethoden, mit dem Apps Nutzern alternative Eingabemethoden wie Bildschirmtastaturen oder die Spracheingabe zur Verfügung stellen können. Nach der Installation der IMEs kann der Nutzer eine davon in den Systemeinstellungen auswählen und für das gesamte System verwenden. Es kann immer nur eine IME aktiviert sein.

Wenn Sie dem Android-System eine IME hinzufügen möchten, erstellen Sie eine Android-Anwendung mit einer Klasse, die InputMethodService erweitert. Außerdem erstellen Sie in der Regel eine Aktivität vom Typ „Einstellungen“, die Optionen an den IME-Dienst übergibt. Sie können auch eine Benutzeroberfläche für Einstellungen definieren, die als Teil der Systemeinstellungen angezeigt wird.

Auf dieser Seite werden die folgenden Themen behandelt:

Wenn Sie noch keine Erfahrung mit IMEs haben, lesen Sie zuerst den Einführungsartikel Eingabemethoden auf dem Bildschirm.

IME-Lebenszyklus

Das folgende Diagramm beschreibt den Lebenszyklus einer IME:

Ein Bild, das den Lebenszyklus einer IME zeigt.
Abbildung 1. Der Lebenszyklus einer IME.

In den folgenden Abschnitten wird beschrieben, wie Sie die Benutzeroberfläche und den Code für eine IME implementieren, die diesem Lebenszyklus folgt.

IME-Komponenten im Manifest deklarieren

Im Android-System ist eine IME eine Android-Anwendung, die einen speziellen IME-Dienst enthält. In der Manifestdatei der Anwendung muss der Dienst deklariert, die erforderlichen Berechtigungen angefordert, ein Intent-Filter angegeben werden, der der Aktion action.view.InputMethod entspricht, und Metadaten bereitgestellt werden, die die Eigenschaften der IME definieren. Wenn Sie eine Einstellungsoberfläche bereitstellen möchten, über die der Nutzer das Verhalten der IME ändern kann, können Sie eine Aktivität vom Typ „Einstellungen“ definieren, die über die Systemeinstellungen gestartet werden kann.

Im folgenden Snippet wird ein IME-Dienst deklariert. Er fordert die Berechtigung BIND_INPUT_METHOD an, damit der Dienst die IME mit dem System verbinden kann, richtet einen Intent-Filter ein, der der Aktion android.view.InputMethod entspricht, und definiert Metadaten für die IME:

<!-- Declares the input method service. -->
<service android:name="FastInputIME"
    android:label="@string/fast_input_label"
    android:permission="android.permission.BIND_INPUT_METHOD">
    <intent-filter>
        <action android:name="android.view.InputMethod" />
    </intent-filter>
    <meta-data android:name="android.view.im"
               android:resource="@xml/method" />
</service>

Im nächsten Snippet wird die Einstellungsaktivität für die IME deklariert. Es gibt einen Intent-Filter für ACTION_MAIN, der angibt, dass diese Aktivität der Haupteinstiegspunkt für die IME-Anwendung ist:

<!-- Optional: an activity for controlling the IME settings. -->
<activity android:name="FastInputIMESettings"
    android:label="@string/fast_input_settings">
    <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
    </intent-filter>
</activity>

Sie können auch direkt über die Benutzeroberfläche der IME Zugriff auf die Einstellungen gewähren.

Die API für Eingabemethoden

Klassen, die speziell für IMEs gelten, finden Sie in den Paketen android.inputmethodservice und android.view.inputmethod. Die KeyEvent-Klasse ist wichtig für die Verarbeitung von Tastaturzeichen.

Der zentrale Teil einer IME ist eine Dienstkomponente – eine Klasse, die InputMethodService erweitert. Neben der Implementierung des normalen Dienstlebenszyklus enthält diese Klasse Rückrufe zum Bereitstellen der Benutzeroberfläche Ihrer IME, zum Verarbeiten von Nutzereingaben und zum Senden von Text an das Feld, das den Fokus hat. Standardmäßig bietet die InputMethodService-Klasse den Großteil der Implementierung zum Verwalten des Status und der Sichtbarkeit der IME und zur Kommunikation mit dem aktuellen Eingabefeld.

Die folgenden Klassen sind ebenfalls wichtig:

BaseInputConnection
Definiert den Kommunikationskanal von einem InputMethod zurück an die Anwendung, die die Eingabe empfängt. Sie können damit Text um den Cursor herum lesen, Text in das Textfeld eingeben und Roheingabeereignisse an die Anwendung senden. Anwendungen müssen diese Klasse erweitern, anstatt die Basisschnittstelle InputConnection zu implementieren.
KeyboardView
Eine Erweiterung von View, die eine Tastatur darstellt und auf Nutzereingabeereignisse reagiert. Das Tastaturlayout wird durch eine Instanz von Keyboard angegeben, die Sie in einer XML-Datei definieren können.

Benutzeroberfläche der Eingabemethode entwerfen

Es gibt zwei Hauptelemente für eine IME: die Eingabeansicht und die Anzeige der Vorschläge. Sie müssen nur die Elemente implementieren, die für die von Ihnen entworfene Eingabemethode relevant sind.

Eingabeansicht

Die Eingabeansicht ist die Benutzeroberfläche, in der der Nutzer Text in Form von Tastenklicks, Handschrift oder Gesten eingibt. Wenn die IME zum ersten Mal angezeigt wird, ruft das System den onCreateInputView()-Callback auf. Erstellen Sie bei der Implementierung dieser Methode das Layout, das im IME-Fenster angezeigt werden soll, und geben Sie es an das System zurück. Das folgende Snippet zeigt ein Beispiel für die Implementierung der Methode onCreateInputView():

Kotlin

override fun onCreateInputView(): View {
    return layoutInflater.inflate(R.layout.input, null).apply {
        if (this is MyKeyboardView) {
            setOnKeyboardActionListener(this@MyInputMethod)
            keyboard = latinKeyboard
        }
    }
}

Java

@Override
public View onCreateInputView() {
    MyKeyboardView inputView =
        (MyKeyboardView) getLayoutInflater().inflate(R.layout.input, null);

    inputView.setOnKeyboardActionListener(this);
    inputView.setKeyboard(latinKeyboard);

    return inputView;
}

In diesem Beispiel ist MyKeyboardView eine Instanz einer benutzerdefinierten Implementierung von KeyboardView, die eine Keyboard rendert.

Ansicht „Bewerber“

In der Ansicht „Vorschläge“ werden vom Nutzer auszuwählende potenzielle Wortkorrekturen oder Vorschläge angezeigt. Im IME-Lebenszyklus ruft das System onCreateCandidatesView() auf, wenn die Ansicht der Vorschläge angezeigt werden kann. Geben Sie bei der Implementierung dieser Methode ein Layout zurück, in dem Wortvorschläge angezeigt werden, oder null, wenn nichts angezeigt werden soll. Eine Nullantwort ist das Standardverhalten. Sie müssen diese Funktion also nicht implementieren, wenn Sie keine Vorschläge machen.

Überlegungen zum UI-Design

In diesem Abschnitt werden einige Aspekte des UI-Designs für IMEs beschrieben.

Mehrere Bildschirmgrößen berücksichtigen

Die Benutzeroberfläche Ihrer IME muss für verschiedene Bildschirmgrößen skalierbar sein und sowohl im Quer- als auch im Hochformat funktionieren. Lassen Sie im Modus der Eingabemethode ohne Vollbild ausreichend Platz, damit die Anwendung das Textfeld und den zugehörigen Kontext anzeigen kann. Die IME darf nicht mehr als die Hälfte des Bildschirms einnehmen. Im Vollbildmodus der Eingabemethode ist das kein Problem.

Mit verschiedenen Eingabetypen umgehen

In Android-Textfeldern können Sie einen bestimmten Eingabetyp festlegen, z. B. beliebigen Text, Zahlen, URLs, E-Mail-Adressen und Suchstrings. Wenn Sie eine neue IME implementieren, erkennen Sie den Eingabetyp jedes Felds und stellen Sie die entsprechende Benutzeroberfläche dafür bereit. Sie müssen Ihre IME jedoch nicht so einrichten, dass sie prüft, ob der Nutzer gültigen Text für den Eingabetyp eingibt. Dies liegt in der Verantwortung der Anwendung, zu der das Textfeld gehört.

Hier sehen Sie beispielsweise die Benutzeroberfläche, die die Latin IME für die Texteingabe auf der Android-Plattform bereitstellt:

Ein Bild, das die Texteingabe in einer lateinischen Eingabemethode zeigt
Abbildung 2. Texteingabe mit lateinischer Eingabemethode

Hier sehen Sie die Benutzeroberfläche, die die lateinische Eingabemethode für die Android-Plattform für die numerische Eingabe bereitstellt:

Ein Bild, auf dem eine numerische Eingabe in einer lateinischen Eingabemethode zu sehen ist
Abbildung 3. Lateinische IME-Zahleneingabe.

Wenn ein Eingabefeld den Fokus erhält und die IME gestartet wird, ruft das System onStartInputView() auf und übergibt ein EditorInfo-Objekt, das Details zum Eingabetyp und andere Attribute des Textfelds enthält. In diesem Objekt enthält das Feld inputType den Eingabetyp des Textfelds.

Das Feld inputType ist ein int, das Bitmuster für verschiedene Einstellungen des Eingabetyps enthält. Wenn Sie den Eingabetyp des Textfelds testen möchten, maskieren Sie es mit der Konstante TYPE_MASK_CLASS, z. B. so:

Kotlin

inputType and InputType.TYPE_MASK_CLASS

Java

inputType & InputType.TYPE_MASK_CLASS

Das Bitmuster für den Eingabetyp kann einen der folgenden Werte haben:

TYPE_CLASS_NUMBER
Ein Textfeld für die Eingabe von Zahlen. Wie in Abbildung 3 dargestellt, zeigt die lateinische Eingabemethode für Felder dieses Typs eine Ziffernleiste an.
TYPE_CLASS_DATETIME
Ein Textfeld für die Eingabe von Datum und Uhrzeit.
TYPE_CLASS_PHONE
Ein Textfeld für die Eingabe von Telefonnummern.
TYPE_CLASS_TEXT
Ein Textfeld zum Eingeben beliebiger unterstützter Zeichen.

Diese Konstanten werden in der Referenzdokumentation zu InputType ausführlicher beschrieben.

Das Feld inputType kann weitere Bits enthalten, die eine Variante des Textfeldtyps angeben, z. B.:

TYPE_TEXT_VARIATION_PASSWORD
Eine Variante von TYPE_CLASS_TEXT zum Eingeben von Passwörtern. Die Eingabemethode zeigt Dingbats anstelle des tatsächlichen Texts an.
TYPE_TEXT_VARIATION_URI
Eine Variante von TYPE_CLASS_TEXT zum Eingeben von Web-URLs und anderen Uniform Resource Identifiers (URIs).
TYPE_TEXT_FLAG_AUTO_COMPLETE
Eine Variante von TYPE_CLASS_TEXT zum Eingeben von Text, der von der Anwendung automatisch aus einem Wörterbuch, einer Suche oder einer anderen Funktion vervollständigt wird.

Maskieren Sie inputType mit der entsprechenden Konstante, wenn Sie diese Varianten testen. Die verfügbaren Maskenkonstanten sind in der Referenzdokumentation für InputType aufgeführt.

Text an die Anwendung senden

Während der Nutzer Text mit Ihrer IME eingibt, können Sie Text an die Anwendung senden, indem Sie einzelne Tastenereignisse senden oder den Text um den Cursor herum im Textfeld der Anwendung bearbeiten. Verwenden Sie in beiden Fällen eine Instanz von InputConnection, um den Text zu senden. Rufen Sie InputMethodService.getCurrentInputConnection() auf, um diese Instanz abzurufen.

Text um den Cursor herum bearbeiten

Wenn Sie vorhandenen Text bearbeiten, sind in BaseInputConnection folgende Methoden hilfreich:

getTextBeforeCursor()
Gibt einen CharSequence zurück, der die Anzahl der angeforderten Zeichen vor der aktuellen Cursorposition enthält.
getTextAfterCursor()
Gibt ein CharSequence zurück, das die Anzahl der angeforderten Zeichen nach der aktuellen Cursorposition enthält.
deleteSurroundingText()
 Löscht die angegebene Anzahl von Zeichen vor und nach der aktuellen Cursorposition.
commitText()
 Speichert ein CharSequence im Textfeld und setzt eine neue Cursorposition.

Im folgenden Snippet wird beispielsweise gezeigt, wie die vier Zeichen links vom Cursor durch den Text „Hallo!“ ersetzt werden:

Kotlin

currentInputConnection.also { ic: InputConnection ->
    ic.deleteSurroundingText(4, 0)
    ic.commitText("Hello", 1)
    ic.commitText("!", 1)
}

Java

InputConnection ic = getCurrentInputConnection();
ic.deleteSurroundingText(4, 0);
ic.commitText("Hello", 1);
ic.commitText("!", 1);

Unterstützung für das Verfassen von Text vor dem Commit

Wenn Ihre IME Text vorhersagt oder mehrere Schritte zum Erstellen eines Schriftzeichens oder Wortes erforderlich sind, können Sie den Fortschritt im Textfeld anzeigen, bis der Nutzer das Wort bestätigt. Anschließend können Sie die teilweise Eingabe durch den vollständigen Text ersetzen. Sie können den Text besonders formatieren, indem Sie ihm beim Übergeben an setComposingText() einen Span hinzufügen.

Im folgenden Snippet wird gezeigt, wie der Fortschritt in einem Textfeld angezeigt wird:

Kotlin

currentInputConnection.also { ic: InputConnection ->
    ic.setComposingText("Composi", 1)
    ic.setComposingText("Composin", 1)
    ic.commitText("Composing ", 1)
}

Java

InputConnection ic = getCurrentInputConnection();
ic.setComposingText("Composi", 1);
ic.setComposingText("Composin", 1);
ic.commitText("Composing ", 1);

Hardware-Schlüsselereignisse abfangen

Auch wenn das Fenster für die Eingabemethode nicht explizit den Fokus hat, empfängt es zuerst Hardwaretastenereignisse und kann sie verarbeiten oder an die Anwendung weiterleiten. So können Sie beispielsweise die Richtungstasten verwenden, um sich bei der Texterstellung in der Benutzeroberfläche zu bewegen und Kandidaten auszuwählen. Sie können auch den Rückwärtspfeil erfassen, um alle Dialogfelder zu schließen, die aus dem Fenster für die Eingabemethode stammen.

Wenn Sie Hardwareschlüssel abfangen möchten, überschreiben Sie onKeyDown() und onKeyUp().

Rufen Sie die Methode super() für Schlüssel auf, die Sie nicht selbst verwalten möchten.

IME-Untertyp erstellen

Mithilfe von Untertypen kann die IME mehrere Eingabemodi und Sprachen bereitstellen, die von einer IME unterstützt werden. Ein Untertyp kann Folgendes darstellen:

  • Eine Sprache, z. B. „en_US“ oder „fr_FR“
  • Einen Eingabemodus, z. B. Spracheingabe, Tastatur oder Handschrift
  • Andere Eingabestile, Formulare oder Eigenschaften, die für die IME spezifisch sind, z. B. 10-Tasten- oder QWERTY-Tastaturlayouts

Der Modus kann beliebiger Text sein, z. B. „Tastatur“ oder „Stimme“. Ein Untertyp kann auch eine Kombination dieser Elemente enthalten.

Informationen zum Untertyp werden für ein IME-Schaltfenster verwendet, das in der Benachrichtigungsleiste verfügbar ist, und für IME-Einstellungen. Anhand dieser Informationen kann das Framework auch direkt einen bestimmten Untertyp einer IME aufrufen. Verwenden Sie beim Erstellen einer IME die Untertypfunktion, da sie Nutzern hilft, verschiedene IME-Sprachen und ‑Modi zu identifizieren und zu wechseln.

Definieren Sie Untertypen in einer der XML-Ressourcendateien der Eingabemethode mit dem Element <subtype>. Im folgenden Code-Snippet wird eine IME mit zwei Untertypen definiert: ein Tastaturuntertyp für die US-englische Sprache und ein weiterer Tastaturuntertyp für die französische Sprache in Frankreich:

<input-method xmlns:android="http://schemas.android.com/apk/res/android"
        android:settingsActivity="com.example.softkeyboard.Settings"
        android:icon="@drawable/ime_icon">
    <subtype android:name="@string/display_name_english_keyboard_ime"
            android:icon="@drawable/subtype_icon_english_keyboard_ime"
            android:languageTag="en-US"
            android:imeSubtypeMode="keyboard"
            android:imeSubtypeExtraValue="somePrivateOption=true" />
    <subtype android:name="@string/display_name_french_keyboard_ime"
            android:icon="@drawable/subtype_icon_french_keyboard_ime"
            android:languageTag="fr-FR"
            android:imeSubtypeMode="keyboard"
            android:imeSubtypeExtraValue="someVariable=30,someInternalOption=false" />
    <subtype android:name="@string/display_name_german_keyboard_ime" ... />
</input-method>

Damit Ihre Untertypen in der Benutzeroberfläche richtig gekennzeichnet sind, verwenden Sie „%s“, um ein Untertyplabel zu erhalten, das mit dem Label der Unterart in der jeweiligen Sprache übereinstimmt. Das wird in den nächsten beiden Code-Snippets veranschaulicht. Das erste Snippet zeigt einen Teil der XML-Datei der Eingabemethode:

<subtype
    android:label="@string/label_subtype_generic"
    android:imeSubtypeLocale="en_US"
    android:icon="@drawable/icon_en_us"
    android:imeSubtypeMode="keyboard" />

Das folgende Snippet ist Teil der strings.xml-Datei der IME. Die Stringressource label_subtype_generic, die in der Benutzeroberflächendefinition der Eingabemethode zum Festlegen des Labels des Untertyps verwendet wird, ist so definiert:

<string name="label_subtype_generic">%s</string>

Mit dieser Einstellung stimmt der Anzeigename des Untertyps mit der Gebietsschemaeinstellung überein. In einer englischsprachigen Sprache lautet der Anzeigename beispielsweise „Englisch (Vereinigte Staaten)“.

IME-Untertypen über die Benachrichtigungsleiste auswählen

Das Android-System verwaltet alle von allen Eingabemethoden bereitgestellten Untertypen. IME-Untertypen werden als Modi der zugehörigen IME behandelt. Der Nutzer kann über die Benachrichtigungsleiste oder die Einstellungen zu einem Menü mit verfügbaren IME-Untertypen wechseln, wie in der folgenden Abbildung dargestellt:

Ein Bild, das das Systemmenü „Sprachen und Eingabe“ zeigt
Abbildung 4: Das Systemmenü Sprachen und Eingabe

IME-Untertypen in den Systemeinstellungen auswählen

Der Nutzer kann auch in den Systemeinstellungen unter Sprache und Eingabe festlegen, wie Untertypen verwendet werden:

Ein Bild, das das Auswahlmenü für Sprachen zeigt
Abbildung 5: Das Systemmenü Sprachen

Zwischen IME-Untertypen wechseln

Sie können Nutzern das Umschalten zwischen IME-Untertypen erleichtern, indem Sie eine Umschalttaste bereitstellen, z. B. das kugelförmige Sprachsymbol auf der Tastatur. Dies verbessert die Nutzerfreundlichkeit der Tastatur. So aktivieren Sie diese Umschaltung:

  1. Deklarieren Sie supportsSwitchingToNextInputMethod = "true" in den XML-Ressourcendateien der Eingabemethode. Ihre Deklaration muss in etwa so aussehen:
    <input-method xmlns:android="http://schemas.android.com/apk/res/android"
            android:settingsActivity="com.example.softkeyboard.Settings"
            android:icon="@drawable/ime_icon"
            android:supportsSwitchingToNextInputMethod="true">
  2. Rufen Sie die Methode shouldOfferSwitchingToNextInputMethod() auf.
  3. Wenn die Methode „wahr“ zurückgibt, wird ein Schalter angezeigt.
  4. Wenn der Nutzer auf den Schalter tippt, rufe switchToNextInputMethod() mit „false“ auf. Wenn der Wert „false“ ist, werden alle Untertypen unabhängig von der zugehörigen IME gleich behandelt. Wenn Sie „wahr“ angeben, muss das System durch die Untertypen in der aktuellen IME wechseln.

Allgemeine Hinweise zu Eingabemethoden

Beachten Sie bei der Implementierung Ihrer IME Folgendes:

  • Bieten Sie Nutzern die Möglichkeit, Optionen direkt über die Benutzeroberfläche der IME festzulegen.
  • Bieten Sie Nutzern die Möglichkeit, direkt über die Benutzeroberfläche der Eingabemethode zu einer anderen Eingabemethode zu wechseln, da möglicherweise mehrere Eingabemethoden auf dem Gerät installiert sind.
  • Die Benutzeroberfläche der IME schnell aufrufen. Laden Sie alle großen Ressourcen vorab oder bei Bedarf, damit Nutzer die Eingabemethode sehen, sobald sie auf ein Textfeld tippen. Ressourcen und Ansichten für nachfolgende Aufrufe der Eingabemethode im Cache speichern.
  • Große Arbeitsspeicherzuweisungen sofort nach dem Ausblenden des Fensters für die Eingabemethode freigeben, damit Anwendungen genügend Arbeitsspeicher zum Ausführen haben. Verwenden Sie eine verzögerte Nachricht, um Ressourcen freizugeben, wenn die IME einige Sekunden lang ausgeblendet ist.
  • Achten Sie darauf, dass Nutzer für die mit der IME verknüpfte Sprache oder das verknüpfte Gebietsschema möglichst viele Zeichen eingeben können. Nutzer verwenden möglicherweise Satzzeichen in Passwörtern oder Nutzernamen. Ihre IME muss daher viele verschiedene Zeichen enthalten, damit Nutzer ein Passwort eingeben und auf das Gerät zugreifen können.