Ein Eingabemethoden-Editor (IME) ist ein Steuerelement, mit dem Nutzer Text eingeben können. Android bietet ein erweiterbares Framework für Eingabemethoden, mit dem Anwendungen Nutzern alternative Eingabemethoden wie Bildschirmtastaturen oder Spracheingabe zur Verfügung stellen können. Nach der Installation der IMEs kann der Nutzer einen davon in den Systemeinstellungen auswählen und im gesamten System verwenden. Es kann immer nur ein IME aktiviert sein.
Wenn du dem Android-System eine Eingabemethode hinzufügen möchtest, erstelle eine Android-App mit einer Klasse, die InputMethodService erweitert.
Außerdem erstellen Sie in der Regel eine „Einstellungen“-Aktivität, die Optionen an den IME-Dienst übergibt. Sie können auch eine Benutzeroberfläche für die Einstellungen definieren, die als Teil der Systemeinstellungen angezeigt wird.
Auf dieser Seite werden die folgenden Themen behandelt:
- Der IME-Lebenszyklus
- IME-Komponenten im App-Manifest deklarieren
- IME API
- IME-UI entwerfen
- Text von einem IME an eine Anwendung senden
- Mit IME-Untertypen arbeiten
- Weitere Hinweise zu Eingabemethoden
Wenn du noch nicht mit IMEs gearbeitet hast, lies zuerst den Einführungsartikel Bildschirm-Eingabemethoden.
Der IME-Lebenszyklus
Das folgende Diagramm beschreibt den Lebenszyklus einer Eingabemethode:
In den folgenden Abschnitten wird beschrieben, wie Sie die Benutzeroberfläche und den Code für eine Eingabemethode implementieren, die diesem Lebenszyklus folgt.
IME-Komponenten im Manifest deklarieren
Im Android-System ist eine Eingabemethode eine Android-App, die einen speziellen Eingabemethodendienst enthält. In der Manifestdatei der Anwendung muss der Dienst deklariert, die erforderlichen Berechtigungen angefordert, ein Intent-Filter bereitgestellt, der mit der Aktion action.view.InputMethod übereinstimmt, und Metadaten bereitgestellt werden, die die Merkmale der Eingabemethode definieren. Außerdem kannst du eine „Einstellungen“-Aktivität definieren, die über die Systemeinstellungen gestartet werden kann, um eine Einstellungsoberfläche bereitzustellen, über die der Nutzer das Verhalten der Eingabemethode ändern kann.
Im folgenden Snippet wird ein IME-Dienst deklariert. Sie fordert die Berechtigung BIND_INPUT_METHOD an, damit der Dienst die Eingabemethode mit dem System verbinden kann, richtet einen Intent-Filter ein, der mit der Aktion android.view.InputMethod übereinstimmt, und definiert Metadaten für die Eingabemethode:
<!-- 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 Aktivität für die Einstellungen der Eingabemethode deklariert. Sie hat 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>
Du kannst den Zugriff auf die Einstellungen der Eingabemethode auch direkt über die Benutzeroberfläche ermöglichen.
Die Eingabemethoden-API
IME-spezifische Klassen befinden sich in den Paketen android.inputmethodservice und android.view.inputmethod. Die Klasse KeyEvent ist wichtig für die Verarbeitung von Tastaturzeichen.
Der zentrale Teil einer Eingabemethode ist eine Dienstkomponente, also eine Klasse, die InputMethodService erweitert. Zusätzlich zur Implementierung des normalen Dienstlebenszyklus bietet diese Klasse Callbacks, um die UI deiner Eingabemethode bereitzustellen, Nutzereingaben zu verarbeiten und Text an das Feld zu senden, das den Fokus hat. Standardmäßig stellt die Klasse InputMethodService den Großteil der Implementierung für die Verwaltung des Status und der Sichtbarkeit der Eingabemethode sowie für die Kommunikation mit dem aktuellen Eingabefeld bereit.
Die folgenden Klassen sind ebenfalls wichtig:
BaseInputConnection-
Definiert den Kommunikationskanal von einem
InputMethodzurück zur Anwendung, die die Eingabe empfängt. Sie können damit Text um den Cursor herum lesen, Text in das Textfeld eingeben und Rohschlüsselereignisse an die Anwendung senden. Anwendungen müssen diese Klasse erweitern, anstatt die BasisschnittstelleInputConnectionzu implementieren. KeyboardView-
Eine Erweiterung von
View, die eine Tastatur rendert und auf Nutzereingabeereignisse reagiert. Das Tastaturlayout wird durch eine Instanz vonKeyboardangegeben, die du in einer XML-Datei definieren kannst.
Benutzeroberfläche für die Eingabemethode entwerfen
Ein IME hat zwei visuelle Hauptelemente: die Eingabeansicht und die Kandidatenansicht. Du musst nur die Elemente implementieren, die für die von dir entwickelte Eingabemethode relevant sind.
Eingabeansicht
Die Eingabeansicht ist die Benutzeroberfläche, auf der der Nutzer Text in Form von Tastenklicks, Handschrift oder Gesten eingibt. Wenn die Eingabemethode zum ersten Mal angezeigt wird, ruft das System den Callback onCreateInputView() auf. Erstelle in deiner Implementierung dieser Methode das Layout, das im IME-Fenster angezeigt werden soll, und gib 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 ein Keyboard rendert.
Kandidatenansicht
Die Kandidatenansicht ist die Benutzeroberfläche, auf der die Eingabemethode potenzielle Wortkorrekturen oder Vorschläge anzeigt, die der Nutzer auswählen kann. Im IME-Lebenszyklus ruft das System onCreateCandidatesView() auf, wenn die Kandidatenansicht angezeigt werden kann. Geben Sie in Ihrer Implementierung dieser Methode ein Layout zurück, das Wortvorschläge enthält, oder geben Sie „null“ zurück, wenn Sie nichts anzeigen möchten. Eine Nullantwort 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 deiner Eingabemethode muss für verschiedene Bildschirmgrößen skalierbar sein und sowohl das Quer- als auch das Hochformat unterstützen. Im IME-Modus, der nicht im Vollbildmodus ausgeführt wird, muss genügend Platz für die Anwendung vorhanden sein, um das Textfeld und den zugehörigen Kontext anzuzeigen, sodass nicht mehr als die Hälfte des Bildschirms vom IME belegt wird. Im Vollbild-IME-Modus ist das kein Problem.
Verschiedene Eingabetypen verarbeiten
In Android-Textfeldern können Sie einen bestimmten Eingabetyp festlegen, z. B. Freiformtext, Zahlen, URLs, E‑Mail-Adressen und Suchstrings. Wenn du eine neue Eingabemethode implementierst, musst du den Eingabetyp jedes Felds erkennen und die entsprechende Oberfläche dafür bereitstellen. Du musst deine Eingabemethode 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 ist beispielsweise die Benutzeroberfläche, die die lateinische Eingabemethode für die Texteingabe auf der Android-Plattform bietet:
Und hier ist die Benutzeroberfläche, die die lateinische Eingabemethode für die numerische Eingabe auf der Android-Plattform bietet:
Wenn ein Eingabefeld den Fokus erhält und die Eingabemethode gestartet wird, ruft das System onStartInputView() auf und übergibt ein EditorInfo-Objekt, das Details zum Eingabetyp und zu anderen Attributen 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 Eingabetypeinstellungen enthält. Wenn Sie den Eingabetyp des Textfelds testen möchten, maskieren Sie ihn mit der Konstante TYPE_MASK_CLASS:
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 die lateinische Eingabemethode für Felder dieses Typs einen Ziffernblock an.
TYPE_CLASS_DATETIME- Ein Textfeld zur Eingabe von Datum und Uhrzeit.
TYPE_CLASS_PHONE- Ein Textfeld zur Eingabe von Telefonnummern.
TYPE_CLASS_TEXT- Ein Textfeld zur Eingabe aller unterstützten Zeichen.
Diese Konstanten werden in der Referenzdokumentation für 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_TEXTfür die Eingabe von Passwörtern. Die Eingabemethode zeigt Dingbats anstelle des eigentlichen Texts an. TYPE_TEXT_VARIATION_URI- Eine Variante von
TYPE_CLASS_TEXTzur Eingabe von Web-URLs und anderen Uniform Resource Identifiers (URIs). TYPE_TEXT_FLAG_AUTO_COMPLETE- Eine Variante von
TYPE_CLASS_TEXTzur Eingabe 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
Wenn der Nutzer Text mit deiner Eingabemethode eingibt, kannst du Text an die Anwendung senden, indem du einzelne Schlüsselereignisse sendest oder den Text um den Cursor im Textfeld der Anwendung bearbeitest. Verwenden Sie in beiden Fällen eine Instanz von InputConnection, um den Text zu übermitteln. Rufen Sie InputMethodService.getCurrentInputConnection() auf, um diese Instanz abzurufen.
Text um den Cursor herum bearbeiten
Wenn Sie vorhandenen Text bearbeiten, sind die folgenden Methoden in BaseInputConnection nützlich:
-
getTextBeforeCursor() - Gibt einen
CharSequencemit der Anzahl der angeforderten Zeichen vor der aktuellen Cursorposition zurück. -
getTextAfterCursor() - Gibt einen
CharSequencemit 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() - Übernimmt einen
CharSequencein das Textfeld und legt eine neue Cursorposition fest.
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 beim Verfassen von Text vor dem Übernehmen
Wenn deine Eingabemethode Text vorhersagt oder mehrere Schritte zum Erstellen einer Glyphe oder eines Wortes erfordert, kannst du den Fortschritt im Textfeld anzeigen, bis der Nutzer das Wort bestätigt. Anschließend kannst du die unvollständige Eingabe durch den vollständigen Text ersetzen. Sie können den Text besonders behandeln, indem Sie ihm einen Span hinzufügen, wenn Sie ihn an setComposingText() übergeben.
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);
Hardwaretastenereignisse abfangen
Obwohl das Fenster der Eingabemethode nicht explizit im Fokus ist, empfängt es zuerst Hardwaretastenereignisse und kann sie verarbeiten oder an die Anwendung weiterleiten. Beispielsweise können Sie die Richtungstasten verwenden, um während der Eingabe in der Benutzeroberfläche zur Kandidatenauswahl zu navigieren. Möglicherweise möchtest du auch die Zurück-Taste abfangen, um alle Dialogfelder zu schließen, die aus dem Fenster der Eingabemethode stammen.
Wenn du Hardwaretasten abfangen möchtest, überschreibe onKeyDown() und onKeyUp().
Rufen Sie die Methode super() für Schlüssel auf, die Sie nicht selbst verwalten möchten.
IME-Untertyp erstellen
Über Untertypen kann die Eingabemethode mehrere Eingabemodi und Sprachen verfügbar machen, die von der Eingabemethode unterstützt werden. Ein Untertyp kann Folgendes darstellen:
- Eine Sprache, z. B. en_US oder fr_FR
- Einen Eingabemodus, z. B. Sprache, Tastatur oder Handschrift
- Andere Eingabestile, Formulare oder Eigenschaften, die für die Eingabemethode spezifisch sind, z. B. 10-Tasten- oder QWERTY-Tastaturlayouts
Der Modus kann ein beliebiger Text sein, z. B. „keyboard“ oder „voice“. Ein Untertyp kann auch eine Kombination dieser Elemente verfügbar machen.
Die Informationen zum Untertyp werden für ein Dialogfeld zum Wechseln der Eingabemethode verwendet, das über die Benachrichtigungsleiste und die Einstellungen für die Eingabemethode verfügbar ist. Anhand der Informationen kann das Framework auch einen bestimmten Untertyp einer Eingabemethode direkt aufrufen. Wenn du einen IME erstellst, verwende die Untertyp-Funktion, da sie dem Nutzer hilft, verschiedene IME-Sprachen und ‑Modi zu identifizieren und zwischen ihnen zu wechseln.
Definiere Untertypen in einer der XML-Ressourcendateien der Eingabemethode mit dem Element <subtype>. Im folgenden Code-Snippet wird eine Eingabemethode mit zwei Untertypen definiert: ein Tastaturuntertyp für das Gebietsschema „US-Englisch“ und ein weiterer Tastaturuntertyp für das Gebietsschema „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 Gebietsschemalabel des Untertyps übereinstimmt. Dies 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 nächste Snippet ist Teil der strings.xml-Datei des IME. Die String-Ressource label_subtype_generic, die von der UI-Definition der Eingabemethode verwendet wird, um das Label des Untertyps festzulegen, ist so definiert:
<string name="label_subtype_generic">%s</string>Mit dieser Einstellung wird der Anzeigename des Untertyps an die Spracheinstellung angepasst. In allen englischen Sprachen ist der Anzeigename beispielsweise „English (United States)“.
IME-Untertypen in der Benachrichtigungsleiste auswählen
Das Android-System verwaltet alle Untertypen, die von allen IMEs bereitgestellt werden. IME-Untertypen werden als Modi der IME behandelt, zu der sie gehören. Der Nutzer kann über die Benachrichtigungsleiste oder die Einstellungen zu einem Menü mit verfügbaren IME-Untertypen navigieren, wie in der folgenden Abbildung dargestellt:
IME-Untertypen in den Systemeinstellungen auswählen
Der Nutzer kann auch in den Systemeinstellungen im Bereich Sprache & Eingabe festlegen, wie Untertypen verwendet werden:
Zwischen IME-Untertypen wechseln
Du kannst Nutzern die Möglichkeit geben, einfach zwischen IME-Untertypen zu wechseln, indem du eine Schaltertaste bereitstellst, z. B. das globusförmige Sprachsymbol auf der Tastatur. Das verbessert die Nutzerfreundlichkeit der Tastatur und ist für den Nutzer praktisch. So aktivieren Sie diesen Wechsel:
- Deklariere
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">
- Rufen Sie die Methode
shouldOfferSwitchingToNextInputMethod()auf. - Wenn die Methode „true“ zurückgibt, wird eine Schaltertaste angezeigt.
- Wenn der Nutzer auf die Umschalttaste tippt, rufe
switchToNextInputMethod()auf und übergib „false“. Der Wert „false“ weist das System an, alle Untertypen gleich zu behandeln, unabhängig davon, zu welcher Eingabemethode sie gehören. Wenn du „true“ angibst, muss das System die Untertypen in der aktuellen Eingabemethode durchlaufen.
Allgemeine Hinweise zu IMEs
Hier sind weitere Punkte, die du bei der Implementierung deiner IME beachten solltest:
- Biete Nutzern die Möglichkeit, Optionen direkt über die Benutzeroberfläche der Eingabemethode festzulegen.
- Biete 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 Eingabemethode schnell aufrufen. Laden Sie große 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.
- Gib große Arbeitsspeicherzuweisungen sofort nach dem Ausblenden des Fensters der Eingabemethode frei, damit Anwendungen genügend Arbeitsspeicher zum Ausführen haben. Verwende eine verzögerte Nachricht, um Ressourcen freizugeben, wenn die Eingabemethode für einige Sekunden ausgeblendet ist.
- Achte darauf, dass Nutzer so viele Zeichen wie möglich für die Sprache oder das Gebietsschema eingeben können, die mit der Eingabemethode verknüpft sind. Nutzer verwenden möglicherweise Satzzeichen in Passwörtern oder Nutzernamen. Daher muss deine Eingabemethode viele verschiedene Zeichen bereitstellen, damit Nutzer ein Passwort eingeben und auf das Gerät zugreifen können.