インプット メソッド エディタ(IME)は、ユーザーがテキストを入力するためのユーザー コントロールです。Android には拡張可能なインプット メソッド フレームワークが用意されており、画面キーボードや音声入力など、別の入力方法をユーザーに提供できます。ユーザーは、IME をインストールした後、システム設定からいずれかの IME を選択し、システム全体で使用できます。一度に有効にできる IME は 1 つのみです。
Android システムに IME を追加するには、InputMethodService
を拡張するクラスを含む Android アプリを作成します。また、通常は、IME サービスにオプションを渡す「設定」アクティビティを作成します。また、システム設定の一部として表示される設定 UI を定義することもできます。
このページでは、次のトピックについて説明します。
- IME のライフサイクル
- アプリ マニフェストで IME コンポーネントを宣言する
- IME API
- IME UI を設計する
- IME からアプリにテキストを送信する
- IME サブタイプの使用
- IME に関するその他の考慮事項
IME を使ったことがない場合は、まず画面上の入力方法の入門記事をお読みください。
IME のライフサイクル
次の図は、IME のライフサイクルを示しています。
以下のセクションでは、このライフサイクルに沿って IME に関連付けられた UI とコードを実装する方法について説明します。
マニフェスト内で IME コンポーネントを宣言する
Android システムの IME は、特別な IME サービスを含む Android アプリです。アプリのマニフェスト ファイルは、サービスを宣言し、必要な権限をリクエストして、アクション action.view.InputMethod
に一致するインテント フィルタを提供し、IME の特性を定義するメタデータを提供する必要があります。さらに、ユーザーが IME の動作を変更できる設定インターフェースを提供するために、システム設定から起動できる「設定」アクティビティを定義できます。
IME サービスを宣言するスニペットを以下に示します。サービスが IME をシステムに接続できるように権限 BIND_INPUT_METHOD
をリクエストし、アクション android.view.InputMethod
に一致するインテント フィルタを設定して、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>
次のスニペットは、IME の設定アクティビティを宣言しています。ACTION_MAIN
用のインテント フィルタがあり、このアクティビティが IME アプリのメイン エントリ ポイントであることを示します。
<!-- 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>
UI から直接 IME の設定にアクセスできるようにすることも可能です。
インプット メソッド API
IME 固有のクラスは、android.inputmethodservice
パッケージと android.view.inputmethod
パッケージにあります。KeyEvent
クラスは、キーボード文字を処理するうえで重要です。
IME の中心部分は、サービス コンポーネント(InputMethodService
を拡張するクラス)です。このクラスには、通常のサービス ライフサイクルの実装に加えて、IME の UI の提供、ユーザー入力の処理、フォーカスされているフィールドへのテキスト配信のためのコールバックがあります。デフォルトでは、IME の状態と表示設定を管理し、現在の入力フィールドと通信するための実装のほとんどは InputMethodService
クラスで提供されます。
次のクラスも重要です。
BaseInputConnection
-
InputMethod
から入力を受信するアプリケーションへの通信チャネルを定義します。このクラスを使用すると、カーソルの周囲のテキストを読み取り、テキスト ボックスにテキストをコミットし、未加工のキーイベントをアプリに送信できます。アプリは、ベース インターフェースInputConnection
を実装するのではなく、このクラスを拡張する必要があります。 KeyboardView
- キーボードをレンダリングし、ユーザー入力イベントに応答する
View
の拡張機能です。キーボード レイアウトは、XML ファイルで定義できるKeyboard
のインスタンスによって指定します。
インプット メソッド UI を設計する
IME には、入力ビューと候補ビューの 2 つの主要な視覚要素があります。設計している入力方法に関連する要素のみを実装する必要があります。
入力ビュー
入力ビューは、ユーザーがキークリック、手書き、ジェスチャーなどの形式でテキストを入力する UI です。IME が初めて表示されたとき、システムは onCreateInputView()
コールバックを呼び出します。このメソッドの実装では、IME ウィンドウに表示するレイアウトを作成し、そのレイアウトをシステムに返します。次のスニペットは、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; }
この例の MyKeyboardView
は、Keyboard
をレンダリングする KeyboardView
のカスタム実装のインスタンスです。
候補ビュー
候補ビューは、ユーザーが選択できる単語の修正候補や候補を IME が表示する UI です。IME のライフサイクルでは、候補ビューを表示する準備ができたら、システムによって onCreateCandidatesView()
が呼び出されます。このメソッドの実装では、単語の候補を表示するレイアウトを返すか、何も表示しない場合は null を返します。null レスポンスはデフォルトの動作であるため、提案を指定しない場合は実装する必要はありません。
UI 設計に関する考慮事項
このセクションでは、IME の UI 設計に関する考慮事項について説明します。
さまざまな画面サイズを処理する
IME の UI は、さまざまな画面サイズに合わせてスケーリングし、横向きと縦向きの両方を処理できる必要があります。非全画面表示 IME モードでは、アプリがテキスト フィールドと関連するコンテキストを表示するのに十分なスペースを確保して、IME が画面の半分を占有しないようにします。全画面 IME モードでは問題ありません。
さまざまな入力タイプを処理する
Android のテキスト フィールドを使用すると、自由形式のテキスト、数字、URL、メールアドレス、検索文字列など、特定の入力タイプを設定できます。新しい IME を実装する場合は、各フィールドの入力タイプを検出し、適切なインターフェースを提供します。ただし、ユーザーが入力タイプに有効なテキストを入力しているかどうかを確認するために IME を設定する必要はありません。これは、テキスト フィールドを所有するアプリケーションが行います。
たとえば、Latin IME が Android プラットフォームのテキスト入力用に提供しているインターフェースは次のとおりです。
Latin IME が Android プラットフォームの数値入力に対して提供するインターフェースは次のとおりです。
入力フィールドがフォーカスを受け取り、IME が起動すると、システムは onStartInputView()
を呼び出し、テキスト フィールドの入力タイプやその他の属性に関する詳細を含む EditorInfo
オブジェクトを渡します。このオブジェクトの inputType
フィールドには、テキスト フィールドの入力タイプが含まれています。
inputType
フィールドは、さまざまな入力タイプ設定のビットパターンを含む int
です。テキスト フィールドの入力タイプをテストするには、次のように定数 TYPE_MASK_CLASS
でマスクします。
Kotlin
inputType and InputType.TYPE_MASK_CLASS
Java
inputType & InputType.TYPE_MASK_CLASS
入力型のビットパターンには、次のいずれかの値を指定できます。
TYPE_CLASS_NUMBER
- 数値を入力するためのテキスト フィールド。図 3 に示すように、Latin IME では、このタイプのフィールドに対してテンキーを表示します。
TYPE_CLASS_DATETIME
- 日時を入力するためのテキスト フィールド。
TYPE_CLASS_PHONE
- 電話番号を入力するためのテキスト フィールド。
TYPE_CLASS_TEXT
- サポートされている文字を入力するためのテキスト フィールド。
これらの定数について詳しくは、InputType
のリファレンス ドキュメントをご覧ください。
inputType
フィールドには、テキスト フィールド タイプのバリアントを示す次のようなビットを含めることができます。
TYPE_TEXT_VARIATION_PASSWORD
- パスワードを入力するための
TYPE_CLASS_TEXT
のバリアント。インプット メソッドでは、実際のテキストではなくディンバットが表示されます。 TYPE_TEXT_VARIATION_URI
- ウェブ URL やその他の URI(Uniform Resource Identifier)を入力するための
TYPE_CLASS_TEXT
のバリアント。 TYPE_TEXT_FLAG_AUTO_COMPLETE
TYPE_CLASS_TEXT
のバリアント。辞書や検索、またはその他の施設からアプリが予測入力するテキストを入力します。
このようなバリアントをテストするときは、適切な定数で inputType
をマスクします。使用可能なマスク定数のリストについては、InputType
のリファレンス ドキュメントをご覧ください。
テキストをアプリに送信する
ユーザーが IME でテキストを入力すると、アプリにテキストを送信できます。そのためには、個々のキーイベントを送信するか、アプリのテキスト フィールドのカーソルの周囲のテキストを編集します。いずれの場合も、InputConnection
のインスタンスを使用してテキストを配信します。このインスタンスを取得するには、InputMethodService.getCurrentInputConnection()
を呼び出します。
カーソルの周囲のテキストを編集する
既存のテキストの編集を処理する場合、BaseInputConnection
には次のような便利なメソッドがあります。
-
getTextBeforeCursor()
- 現在のカーソル位置より前のリクエストされた文字数を含む
CharSequence
を返します。 -
getTextAfterCursor()
- 現在のカーソル位置の後にリクエストされた文字数を含む
CharSequence
を返します。 -
deleteSurroundingText()
- 現在のカーソル位置の前後の指定された文字数を削除します。
-
commitText()
CharSequence
をテキスト フィールドに commit し、新しいカーソル位置を設定します。
たとえば、次のスニペットは、カーソルの左側にある 4 文字をテキスト「Hello!」に置き換える方法を示しています。
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);
commit 前のテキスト作成をサポート
IME がテキストを予測する場合や、グリフや単語を構成するために複数のステップを必要とする場合は、ユーザーが単語を commit するまでテキスト フィールドに進行状況を表示し、部分的な構成を完成したテキストに置き換えることができます。テキストを setComposingText()
に渡すときにスパンを追加すると、テキストに特別な処理を施すことができます。
次のスニペットは、テキスト フィールドに進行状況を表示する方法を示しています。
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);
ハードウェア キーイベントをインターセプトする
インプット メソッド ウィンドウに明示的なフォーカスがない場合でも、ハードウェア キーイベントを最初に受け取り、それらを使用したりアプリに転送したりできます。たとえば、方向キーを使用して、コンポーズ中に候補を選択する UI 内を移動できます。また、戻るキーをトラップして、インプット メソッド ウィンドウから発生したダイアログを閉じることもできます。
ハードウェア キーをインターセプトするには、onKeyDown()
と onKeyUp()
をオーバーライドします。
自身で処理しないキーに対して super()
メソッドを呼び出します。
IME サブタイプを作成する
サブタイプを使用すると、IME がサポートしている複数の入力モードと言語を公開できます。サブタイプは以下を表します。
- 言語 / 地域(en_US、fr_FR など)
- 入力モード(音声、キーボード、手書きなど)
- IME に固有のその他の入力スタイル、フォーム、プロパティ(テンキー、QWERTY キーボードのレイアウトなど)
モードには、「keyboard」や「voice」などの任意のテキストを指定できます。サブタイプではこれらの組み合わせを公開することもできます
サブタイプ情報は、通知バーから利用できる IME 切り替えダイアログと IME 設定に使用されます。この情報により、フレームワークで IME の特定のサブタイプを直接表示することもできます。IME を作成するときは、サブタイプ機能を使用します。これにより、ユーザーが IME の言語とモードを識別して切り替えることができるためです。
<subtype>
要素を使用して、インプット メソッドの XML リソース ファイルのいずれかでサブタイプを定義します。次のコード スニペットでは、2 つのサブタイプを持つ IME を定義しています。1 つは米国英語の言語 / 地域用のキーボード サブタイプ、もう 1 つはフランスの言語 / 地域用のキーボード サブタイプです。
<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>
UI でサブタイプが正しくラベル付けされるようにするには、`%s` を使用して、サブタイプの言語 / 地域ラベルと同じサブタイプ ラベルを取得します。これを次の 2 つのコード スニペットに示します。最初のスニペットは、インプット メソッドの XML ファイルの一部です。
<subtype android:label="@string/label_subtype_generic" android:imeSubtypeLocale="en_US" android:icon="@drawable/icon_en_us" android:imeSubtypeMode="keyboard" />
次のスニペットは、IME の strings.xml
ファイルの一部を示しています。インプット メソッドの UI 定義でサブタイプのラベルを設定するために使用される文字列リソース label_subtype_generic
は、次のように定義されます。
<string name="label_subtype_generic">%s</string>
この設定により、サブタイプの表示名がロケール設定と一致します。たとえば、英語の言語 / 地域では、表示名は「English (United States)」になります。
通知バーから IME サブタイプを選択する
Android システムは、すべての IME がエクスポーズするすべてのサブタイプを管理します。IME サブタイプは、それが属する IME のモードとして扱われます。ユーザーは、次の図に示すように、通知バーまたは設定アプリから、利用可能な IME サブタイプのメニューに移動できます。
システム設定から IME サブタイプを選択する
ユーザーは、システム設定の [言語と入力] 設定パネルで、サブタイプの使用方法も管理できます。
IME サブタイプを切り替える
キーボード上の地球型の言語アイコンなどの切り替えキーを提供することで、ユーザーが IME サブタイプを簡単に切り替えられるようにすることができます。これにより、キーボードのユーザビリティが向上し、ユーザーにとって便利です。この切り替えを有効にするには、次の操作を行います。
- インプット メソッドの XML リソース ファイル内で、
supportsSwitchingToNextInputMethod = "true"
を宣言します。この宣言は、次のコード スニペットのようになります。<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">
shouldOfferSwitchingToNextInputMethod()
メソッドを呼び出します。- メソッドが true を返した場合は、切り替えキーを表示します。
- ユーザーが切り替えキーをタップしたら、
switchToNextInputMethod()
を呼び出して false を渡します。値が false の場合、どの IME に属しているかにかかわらず、すべてのサブタイプを平等に扱うようシステムに指示します。true を指定した場合、現在の IME 内でサブタイプを切り替える必要があります。
IME に関する一般的な考慮事項
IME を実装する際は、以下の点も考慮してください。
- ユーザーが IME の UI から直接オプションを設定できるようにしました。
- デバイスに複数の IME がインストールされている可能性があるため、ユーザーがインプット メソッド UI から直接別の IME に切り替える方法を提供します。
- IME の UI をすばやく表示します。大きなリソースをプリロードまたはオンデマンドで読み込み、ユーザーがテキスト フィールドをタップしたらすぐに IME を表示できるようにします。後続の入力メソッドの呼び出しのために、リソースとビューをキャッシュに保存します。
- インプット メソッド ウィンドウが非表示になった直後に大きなメモリ割り当てを解放して、アプリを実行するのに十分なメモリを確保します。IME が数秒間非表示になった場合に、遅延メッセージを使用してリソースを解放します。
- ユーザーが IME に関連付けられている言語またはロケールをできるだけ多く入力できるようにします。ユーザーはパスワードやユーザー名に句読点を使用する可能性があるため、ユーザーがパスワードを入力してデバイスにアクセスできるようにするには、IME でさまざまな文字を使用する必要があります。