Eingabemethode erstellen

Ein Eingabemethodeneditor (IME) ist ein Steuerelement, mit dem Nutzer Text eingeben können. Android bietet ein erweiterbares Eingabemethoden-Framework, mit dem Apps Nutzern alternative Eingabemethoden wie Bildschirmtastaturen oder Spracheingaben bieten können. Nach der Installation der IMEs kann der Nutzer einen IMEs aus den Systemeinstellungen auswählen und im gesamten System verwenden. Es kann jeweils nur ein IME aktiviert werden.

Wenn du dem Android-System einen IME hinzufügen möchtest, erstelle eine Android-App mit einer Klasse, die InputMethodService erweitert. Darüber hinaus erstellen Sie normalerweise eine Einstellungsaktivität, die Optionen an den IME-Dienst übergibt. Sie können auch eine UI für Einstellungen definieren, die als Teil der Systemeinstellungen angezeigt wird.

Auf dieser Seite werden die folgenden Themen behandelt:

Wenn Sie IMEs noch nicht verwendet haben, lesen Sie zuerst den einführenden Artikel zu On-Screen-Eingabemethoden.

IME-Lebenszyklus

Im folgenden Diagramm wird der Lebenszyklus eines IME beschrieben:

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

In den folgenden Abschnitten wird beschrieben, wie Sie die UI und den Code implementieren, der mit einem IME verknüpft ist, der diesem Lebenszyklus folgt.

IME-Komponenten im Manifest deklarieren

Im Android-System ist ein IME eine Android-App, die einen speziellen IME-Dienst enthält. In der Manifestdatei der Anwendung muss der Dienst deklariert, die erforderlichen Berechtigungen angefordert und ein Intent-Filter angegeben werden, der mit der Aktion action.view.InputMethod übereinstimmt. Außerdem müssen Metadaten angegeben werden, die die Eigenschaften des IME definieren. Zusätzlich zu einer Einstellungsoberfläche, über die Nutzer das Verhalten des IME ändern können, können Sie eine Einstellungsaktivität definieren, die über die Systemeinstellungen gestartet werden kann.

Mit dem folgenden Snippet wird ein IME-Dienst deklariert. Er fordert die Berechtigung BIND_INPUT_METHOD an, damit der Dienst den IME mit dem System verbinden kann, richtet einen Intent-Filter ein, der der Aktion android.view.InputMethod entspricht, und definiert Metadaten für den 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>

Das nächste Snippet deklariert die Einstellungsaktivität für den IME. Sie hat einen Intent-Filter für ACTION_MAIN, der darauf hinweist, 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 den Zugriff auf die IME-Einstellungen auch direkt über die Benutzeroberfläche gewähren.

Die Eingabemethoden-API

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

Der zentrale Teil eines IME ist eine Dienstkomponente – eine Klasse, die InputMethodService erweitert. Neben der Implementierung des normalen Dienstlebenszyklus enthält diese Klasse Callbacks für die Bereitstellung der UI Ihres IME, die Verarbeitung von Nutzereingaben und die Übermittlung von Text an das ausgewählte Feld. Standardmäßig übernimmt die Klasse InputMethodService den Großteil der Implementierung zum Verwalten des Status und der Sichtbarkeit des IME und die Kommunikation mit dem aktuellen Eingabefeld.

Die folgenden Klassen sind ebenfalls wichtig:

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

UI für Eingabemethoden entwerfen

Ein IME hat zwei visuelle Hauptelemente: die Ansicht input und die Ansicht candidates. 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 der 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 das Layout 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.

Kandidatenansicht

Die Kandidatenansicht ist die Benutzeroberfläche, in der der IME mögliche Wortkorrekturen oder Vorschläge anzeigt, die der Nutzer auswählen kann. Im IME-Lebenszyklus ruft das System onCreateCandidatesView() auf, wenn die Ansicht „Kandidaten“ angezeigt werden kann. Geben Sie bei der Implementierung dieser Methode ein Layout mit Wortvorschlägen oder null zurück, wenn nichts angezeigt werden soll. Eine Null-Antwort ist das Standardverhalten. Sie müssen dies also nicht implementieren, wenn Sie keine Vorschläge machen.

Überlegungen zum UI-Design

In diesem Abschnitt werden einige Überlegungen zum UI-Design für IMEs beschrieben.

Mehrere Bildschirmgrößen verarbeiten

Die Benutzeroberfläche für Ihren IME muss für verschiedene Bildschirmgrößen skaliert werden können und sowohl im Quer- als auch im Hochformat funktionieren. Lassen Sie im IME-Modus ohne Vollbildansicht genügend Platz für die Anwendung, um das Textfeld und den zugehörigen Kontext anzuzeigen, damit nicht mehr als die Hälfte des Bildschirms von dem IME belegt wird. Im IME-Vollbildmodus ist das kein Problem.

Verschiedene Eingabetypen verarbeiten

Mit Android-Textfeldern können Sie einen bestimmten Eingabetyp festlegen, z. B. Freitext, Zahlen, URLs, E-Mail-Adressen und Suchstrings. Wenn Sie einen neuen IME implementieren, ermitteln Sie den Eingabetyp jedes Felds und stellen Sie die entsprechende Schnittstelle dafür bereit. Sie müssen jedoch keinen IME einrichten, um zu prüfen, ob der Nutzer gültigen Text für den Eingabetyp eingibt. Dies liegt in der Verantwortung der Anwendung, der das Textfeld gehört.

Hier sehen Sie als Beispiel die Schnittstelle, die der Latin IME für die Texteingabe der Android-Plattform bereitstellt:

Ein Bild, das eine Texteingabe auf einem lateinischen IME zeigt
Abbildung 2. Texteingabe für lateinischen IME

Hier ist die Schnittstelle, die der Latin IME für die numerische Eingabe der Android-Plattform bereitstellt:

Ein Bild, das eine numerische Eingabe auf einem lateinischen IME zeigt
Abbildung 3: Numerische Eingabe des lateinischen IME

Wenn ein Eingabefeld den Fokus aufnimmt und der 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 eine int, die Bitmuster für verschiedene Einstellungen des Eingabetyps enthält. Um ihn auf den Eingabetyp des Textfelds zu testen, maskieren Sie ihn mit der Konstante TYPE_MASK_CLASS. Beispiel:

Kotlin

inputType and InputType.TYPE_MASK_CLASS

Java

inputType & InputType.TYPE_MASK_CLASS

Das Bitmuster des Eingabetyps kann einen von mehreren Werten haben, darunter:

TYPE_CLASS_NUMBER
Ein Textfeld zur Eingabe von Zahlen. Wie in Abbildung 3 dargestellt, zeigt der lateinische IME einen Ziffernblock für Felder dieses Typs an.
TYPE_CLASS_DATETIME
Ein Textfeld für die Eingabe von Datum und Uhrzeit.
TYPE_CLASS_PHONE
Ein Textfeld zur Eingabe von Telefonnummern.
TYPE_CLASS_TEXT
Ein Textfeld zur Eingabe der unterstützten Zeichen.

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

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

TYPE_TEXT_VARIATION_PASSWORD
Eine Variante von TYPE_CLASS_TEXT zur Eingabe von Passwörtern. Die Eingabemethode zeigt Dingbats anstelle des eigentlichen Texts an.
TYPE_TEXT_VARIATION_URI
Eine Variante von TYPE_CLASS_TEXT zur Eingabe von Web-URLs und anderen URIs (Uniform Resource Identifiers).
TYPE_TEXT_FLAG_AUTO_COMPLETE
Eine Variante von TYPE_CLASS_TEXT zur Eingabe von Text, den die Anwendung automatisch aus einem Wörterbuch, einer Suche oder einer anderen Einrichtung vervollständigt.

Maskieren Sie inputType mit der entsprechenden Konstante, wenn Sie diese Varianten testen. Die verfügbaren Maskenkonstanten finden Sie in der Referenzdokumentation zu InputType.

Text an die Anwendung senden

Während der Nutzer mit Ihrem IME Text eingibt, können Sie Text an die Anwendung senden, indem Sie einzelne Schlüsselereignisse senden oder den Text um den Cursor 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, können Sie in BaseInputConnection folgende Methoden verwenden:

getTextBeforeCursor()
Gibt eine CharSequence zurück, die die Anzahl der angeforderten Zeichen vor der aktuellen Cursorposition enthält.
getTextAfterCursor()
Gibt eine CharSequence mit der Anzahl der angeforderten Zeichen nach der aktuellen Cursorposition zurück.
deleteSurroundingText()
Löscht die angegebene Anzahl von Zeichen vor und nach der aktuellen Cursorposition.
commitText()
Übermittelt ein CharSequence an das Textfeld und legt eine neue Cursorposition fest.

Das folgende Snippet zeigt beispielsweise, wie die vier Zeichen links vom Cursor durch den Text „Hello!“ 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);

Texterstellung vor dem Commit unterstützen

Wenn Ihr IME Text vorhersagen kann oder zum Erstellen einer Glyphe oder eines Wortes mehrere Schritte erfordert, können Sie den Fortschritt im Textfeld anzeigen lassen, bis der Nutzer das Wort übergibt. Anschließend können Sie die Teilzusammensetzung durch den fertigen Text ersetzen. Sie können dem Text eine Sonderbehandlung geben, indem Sie ihm bei der Übergabe an setComposingText() ein span-Element hinzufügen.

Das folgende Snippet zeigt, 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 der Eingabemethode keinen expliziten Fokus hat, empfängt es Hardwareschlüsselereignisse zuerst und kann sie verarbeiten oder an die Anwendung weiterleiten. Beispielsweise können Sie die Pfeiltasten nutzen, um während der Zusammensetzung innerhalb Ihrer UI die Kandidatenauswahl zu nutzen. Sie können die Zurück-Taste auch festhalten, um alle Dialogfelder zu schließen, die aus dem Eingabemethodenfenster stammen.

Überschreiben Sie onKeyDown() und onKeyUp(), um Hardwareschlüssel abzufangen.

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

IME-Untertyp erstellen

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

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

Der Modus kann aus einem beliebigen Text bestehen, z. B. „Tastatur“ oder „Sprache“. Mit einem Untertyp kann auch eine Kombination dieser Eigenschaften verfügbar sein.

Die Untertypinformationen werden für ein Dialogfeld zum IME-Wechsler, das in der Benachrichtigungsleiste verfügbar ist, und für die IME-Einstellungen verwendet. Auf diese Weise kann das Framework auch direkt einen bestimmten Untertyp eines IME aufrufen. Verwende beim Erstellen eines IME die Einrichtung für den Untertyp, da Nutzer so leichter verschiedene IME-Sprachen und -Modi identifizieren und zwischen ihnen wechseln können.

Definieren Sie Untertypen in einer der XML-Ressourcendateien der Eingabemethode mit dem Element <subtype>. Im folgenden Code-Snippet wird ein IME mit zwei Untertypen definiert: einem Tastatur-Untertyp für Englisch (USA) und einem weiteren Tastatur-Untertyp für die Sprache Französisch für 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 korrekt gekennzeichnet werden, verwenden Sie „%s“, um ein Untertyplabel zu erhalten, das mit dem Sprachlabel des Untertyps identisch ist. Dies wird in den nächsten beiden Code-Snippets gezeigt. 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 nächste Snippet ist Teil der strings.xml-Datei des IME. Die Stringressource label_subtype_generic, die von der UI-Definition für die Eingabemethode verwendet wird, um das Label des Untertyps festzulegen, ist so definiert:

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

Diese Einstellung bewirkt, dass der Anzeigename des Untertyps mit der Spracheinstellung übereinstimmt. In jeder englischen Sprache lautet der Anzeigename beispielsweise „Englisch (USA)“.

IME-Untertypen aus der Benachrichtigungsleiste auswählen

Das Android-System verwaltet alle von allen IMEs bereitgestellten Untertypen. IME-Untertypen werden als Modi des IME behandelt, zu dem sie gehören. Der Nutzer kann von der Benachrichtigungsleiste oder der App „Einstellungen“ zu einem Menü mit verfügbaren IME-Untertypen wechseln, wie in der folgenden Abbildung dargestellt:

Ein Bild, auf dem das Menü „Sprachen und Eingabesystem“ zu sehen ist
Abbildung 4: Das Systemmenü Sprachen und Eingabe

IME-Untertypen in den Systemeinstellungen auswählen

Der Nutzer kann außerdem in den Systemeinstellungen im Bereich Sprache & Eingabe festlegen, wie Untertypen verwendet werden:

Ein Bild, auf dem das Menü für die Sprachauswahl zu sehen ist
Abbildung 5: Das Systemmenü Sprachen

Zwischen IME-Untertypen wechseln

Mit einer Taste wie dem globusförmigen Sprachsymbol auf der Tastatur können Nutzer ganz einfach zwischen IME-Untertypen wechseln. Dies verbessert die Bedienungsfreundlichkeit der Tastatur und ist praktisch für die Nutzenden. So aktivieren Sie den Wechsel:

  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 „true“ zurückgibt, zeigen Sie einen Wechselschlüssel an.
  4. Wenn der Nutzer auf den Wechselschlüssel tippt, wird switchToNextInputMethod() aufgerufen und es wird „false“ übergeben. Der Wert „false“ weist das System an, alle Untertypen unabhängig von ihrem IME gleich zu behandeln. Wenn Sie „true“ angeben, muss das System die Untertypen im aktuellen IME durchlaufen.

Allgemeine Hinweise zu IMEs

Beachten Sie bei der Implementierung des IMEs außerdem Folgendes:

  • Nutzern die Möglichkeit geben, Optionen direkt über die Benutzeroberfläche des IME festzulegen
  • Bieten Sie Nutzern die Möglichkeit, direkt über die UI für die Eingabemethode zu einem anderen IME zu wechseln, da möglicherweise mehrere IMEs auf dem Gerät installiert sind.
  • Rufen Sie die Benutzeroberfläche des IME schnell auf. Große Ressourcen sollten vorab geladen oder bei Bedarf geladen werden, sodass Nutzer den IME sehen, sobald sie auf ein Textfeld tippen. Speichern Sie Ressourcen und Ansichten für nachfolgende Aufrufe der Eingabemethode im Cache.
  • Geben Sie große Arbeitsspeicherzuweisungen sofort nach dem Ausblenden des Fensters für die Eingabemethode frei, damit die Anwendungen genügend Arbeitsspeicher zum Ausführen haben. Verwenden Sie eine verzögerte Nachricht, um Ressourcen freizugeben, wenn der IME für einige Sekunden ausgeblendet ist.
  • Nutzer sollten so viele Zeichen wie möglich für die mit dem IME verknüpfte Sprache oder Region eingeben können. Nutzer verwenden möglicherweise Satzzeichen in Passwörtern oder Nutzernamen. Daher muss Ihr IME viele verschiedene Zeichen enthalten, über die die Nutzer ein Passwort eingeben und auf das Gerät zugreifen können.