From 0fa6edced7496b898d31ff7dab7255a1e0dffa9b Mon Sep 17 00:00:00 2001
From: David Friedman
To add an IME to the Android system, you create an Android application
containing a class that extends {@link android.inputmethodservice.InputMethodService}. In
- addition, you usually create a "settings" activity that passes options to the IME
- service. You can also define a settings UI that's displayed as part of the system settings.
+ addition, you usually create a "settings" activity that passes options to the IME service. You
+ can also define a settings UI that's displayed as part of the system settings.
This guide covers the following:
@@ -70,29 +70,22 @@ page.tags=ime,keyboard,inputmethodservice
Figure 1. The life cycle of an IME.
- The following sections describe how to implement the UI and code associated -with an IME that + The following sections describe how to implement the UI and code associated with an IME that follows this lifecycle.
- In the Android system, an IME is an Android application that contains a
-special IME service.
- The application's manifest file must declare the service, request the
-necessary permissions,
- provide an intent filter that matches the action
-action.view.InputMethod, and
- provide metadata that defines characteristics of the IME. In addition, to
-provide a settings
- interface that allows the user to modify the behavior of the IME, you can
-define a "settings"
+ In the Android system, an IME is an Android application that contains a special IME service.
+ The application's manifest file must declare the service, request the necessary permissions,
+ provide an intent filter that matches the action action.view.InputMethod, and
+ provide metadata that defines characteristics of the IME. In addition, to provide a settings
+ interface that allows the user to modify the behavior of the IME, you can define a "settings"
activity that can be launched from System Settings.
The following snippet declares an IME service. It requests the permission
-{@link android.Manifest.permission#BIND_INPUT_METHOD} to allow the service to
-connect the IME to
- the system, sets up an intent filter that matches the action
+ {@link android.Manifest.permission#BIND_INPUT_METHOD} to allow the service to connect the IME
+ to the system, sets up an intent filter that matches the action
android.view.InputMethod, and defines metadata for the IME:
@@ -108,10 +101,8 @@ android:resource="@xml/method" />
</service>
- This next snippet declares the settings activity for the IME. It has an -intent filter for - {@link android.content.Intent#ACTION_MAIN} that indicates this activity is -the main entry point + This next snippet declares the settings activity for the IME. It has an intent filter for + {@link android.content.Intent#ACTION_MAIN} that indicates this activity is the main entry point for the IME application:
<!-- Optional: an activity for controlling the IME settings -->
@@ -127,23 +118,18 @@ the main entry point
The Input Method API
- Classes specific to IMEs are found in the {@link android.inputmethodservice} and {@link android.view.inputmethod}
- packages. The {@link android.view.KeyEvent} class is important for handling keyboard
- characters.
+ Classes specific to IMEs are found in the {@link android.inputmethodservice} and
+ {@link android.view.inputmethod} packages. The {@link android.view.KeyEvent} class is
+ important for handling keyboard characters.
The central part of an IME is a service component, a class that extends
- {@link android.inputmethodservice.InputMethodService}. In addition to
-implementing the
- normal service lifecycle, this class has callbacks for providing your IME's
-UI, handling user
- input, and delivering text to the field that currently has focus. By
-default, the
- {@link android.inputmethodservice.InputMethodService} class provides most
-of the implementation
- for managing the state and visibility of the IME and communicating with the
-current
- input field.
+ {@link android.inputmethodservice.InputMethodService}. In addition to implementing the
+ normal service lifecycle, this class has callbacks for providing your IME's UI, handling user
+ input, and delivering text to the field that currently has focus. By default, the
+ {@link android.inputmethodservice.InputMethodService} class provides most of the implementation
+ for managing the state and visibility of the IME and communicating with the current input
+ field.
The following classes are also important:
@@ -152,45 +138,32 @@ current
- There are two main visual elements for an IME: the input -view and the - candidates view. You only have to implement the elements -that are relevant to + There are two main visual elements for an IME: the input view and the + candidates view. You only have to implement the elements that are relevant to the input method you're designing.
- The input view is the UI where the user inputs text in the form of -keyclicks, handwriting or - gestures. When the IME is displayed for the first time, the system calls -the - {@link android.inputmethodservice.InputMethodService#onCreateInputView()} -callback. In your - implementation of this method, you create the layout you want to display in -the IME - window and return the layout to the system. This snippet is an example of -implementing the - {@link android.inputmethodservice.InputMethodService#onCreateInputView()} -method: + The input view is the UI where the user inputs text in the form of keyclicks, handwriting or + gestures. When the IME is displayed for the first time, the system calls the + {@link android.inputmethodservice.InputMethodService#onCreateInputView()} callback. In your + implementation of this method, you create the layout you want to display in the IME + window and return the layout to the system. This snippet is an example of implementing the + {@link android.inputmethodservice.InputMethodService#onCreateInputView()} method:
@Override
public View onCreateInputView() {
@@ -215,17 +188,12 @@ traditional QWERTY keyboard,
Candidates view
- The candidates view is the UI where the IME displays potential word
-corrections or
+ The candidates view is the UI where the IME displays potential word corrections or
suggestions for the user to select. In the IME lifecycle, the system calls
- {@link android.inputmethodservice.InputMethodService#onCreateCandidatesView()} when
-it's ready
- to display the candidates view. In your implementation of this method,
-return a layout that shows
- word suggestions, or return null if you don’t want to show anything. A
-null response is the
- default behavior, so you don’t have to implement this if you don’t
-provide suggestions.
+ {@link android.inputmethodservice.InputMethodService#onCreateCandidatesView()} when it's ready
+ to display the candidates view. In your implementation of this method, return a layout that
+ shows word suggestions, or return null if you don’t want to show anything. A null response is
+ the default behavior, so you don’t have to implement this if you don’t provide suggestions.
For an example implementation that provides user suggestions, see the
@@ -237,32 +205,22 @@ provide suggestions.
Handling multiple screen sizes
- The UI for your IME must be able to scale for different screen sizes, and
-it also
- must handle both landscape and portrait orientations. In non-fullscreen IME
-mode, leave
- sufficient space for the application to show the text field and any
-associated context, so that
- no more than half the screen is occupied by the IME. In fullscreen IME mode
-this is not an
+ The UI for your IME must be able to scale for different screen sizes, and it also
+ must handle both landscape and portrait orientations. In non-fullscreen IME mode, leave
+ sufficient space for the application to show the text field and any associated context, so that
+ no more than half the screen is occupied by the IME. In fullscreen IME mode this is not an
issue.
Handling different input types
- Android text fields allow you to set a specific input type, such as free
-form text, numbers,
- URLs, email addresses, and search strings. When you implement a new IME,
-you need to
- detect the input type of each field and provide the appropriate interface
-for it. However, you
- don't have to set up your IME to check that the user entered text
-valid for the
- input type; that's the responsibility of the application that owns the text
-field.
+ Android text fields allow you to set a specific input type, such as free-form text, numbers,
+ URLs, email addresses, and search strings. When you implement a new IME, you need to detect
+ the input type of each field and provide the appropriate interface for it. However, you
+ don't have to set up your IME to check that the user entered text valid for the input type;
+ that's the responsibility of the application that owns the text field.
- For example, here are screenshots of the interfaces that the Latin IME
-provided with the
+ For example, here are screenshots of the interfaces that the Latin IME provided with the
Android platform provides for text and phone number inputs:
@@ -273,18 +231,14 @@ provided with the
When an input field receives focus and your IME starts, the system calls
{@link android.inputmethodservice.InputMethodService#onStartInputView(EditorInfo, boolean) onStartInputView()},
- passing in an {@link android.view.inputmethod.EditorInfo} object that
- contains details about the input type and other attributes of the text
-field. In this object,
- the {@link android.view.inputmethod.EditorInfo#inputType} field contains
-the text field's input
+ passing in an {@link android.view.inputmethod.EditorInfo} object that contains details about
+ the input type and other attributes of the text field. In this object, the
+ {@link android.view.inputmethod.EditorInfo#inputType} field contains the text field's input
type.
- The {@link android.view.inputmethod.EditorInfo#inputType} field is an
-int
- that contains bit patterns for various input type settings. To test it for
-the text field's
+ The {@link android.view.inputmethod.EditorInfo#inputType} field is an int
+ that contains bit patterns for various input type settings. To test it for the text field's
input type, mask it with the constant {@link android.text.InputType#TYPE_MASK_CLASS}, like
this:
@@ -297,8 +251,7 @@ The input type bit pattern can have one of several values, including:
- These constants are described in more detail in the reference documentation -for + These constants are described in more detail in the reference documentation for {@link android.text.InputType}.
- The {@link android.view.inputmethod.EditorInfo#inputType} field can contain -other bits that + The {@link android.view.inputmethod.EditorInfo#inputType} field can contain other bits that indicate a variant of the text field type, such as:
- Remember to mask {@link android.view.inputmethod.EditorInfo#inputType} with -the appropriate - constant when you test for these variants. The available mask constants are -listed in the + Remember to mask {@link android.view.inputmethod.EditorInfo#inputType} with the appropriate + constant when you test for these variants. The available mask constants are listed in the reference documentation for {@link android.text.InputType}.
- Caution: In your own IME, make sure you handle text -correctly when you send it - to a password field. Hide the password in your UI both in the input view -and in the candidates - view. Also remember that you shouldn't store passwords on a device. To -learn more, see the Designing for Security - guide. + Caution: In your own IME, make sure you handle text correctly when you send it + to a password field. Hide the password in your UI both in the input view and in the candidates + view. Also remember that you shouldn't store passwords on a device. To learn more, see the + Designing for Security guide.
- As the user inputs text with your IME, you can send text to the application -by - sending individual key events or by editing the text around the cursor in -the application's text + As the user inputs text with your IME, you can send text to the application by sending + individual key events or by editing the text around the cursor in the application's text field. In either case, you use an instance of {@link android.view.inputmethod.InputConnection} to deliver the text. To get this instance, call {@link android.inputmethodservice.InputMethodService#getCurrentInputConnection InputMethodService.getCurrentInputConnection()}.
- When you're handling the editing of existing text in a text field, some of -the more useful + When you're handling the editing of existing text in a text field, some of the more useful methods in {@link android.view.inputmethod.BaseInputConnection} are:
- For example, the following snippet shows how to replace the four characters to -the left of the cursor with the text "Hello!": + For example, the following snippet shows how to replace the four characters to the left of the + cursor with the text "Hello!":
InputConnection ic = getCurrentInputConnection();
@@ -424,12 +360,9 @@ the left of the cursor with the text "Hello!":
- If your IME does text prediction or requires multiple steps to compose a -glyph or - word, you can show the progress in the text field until the user commits -the word, and then you - can replace the partial composition with the completed text. You may give -special treatment to + If your IME does text prediction or requires multiple steps to compose a glyph or + word, you can show the progress in the text field until the user commits the word, and then you + can replace the partial composition with the completed text. You may give special treatment to the text by adding a "span" to it when you pass it to {@link android.view.inputmethod.InputConnection#setComposingText setComposingText()}.
@@ -465,14 +398,10 @@ alt="" height="31"- Even though the input method window doesn't have explicit focus, it -receives hardware key - events first and can choose to consume them or forward them along to the -application. For - example, you may want to consume the directional keys to navigate within -your UI for candidate - selection during composition. You may also want to trap the back key to -dismiss any popups + Even though the input method window doesn't have explicit focus, it receives hardware key + events first and can choose to consume them or forward them along to the application. For + example, you may want to consume the directional keys to navigate within your UI for candidate + selection during composition. You may also want to trap the back key to dismiss any popups originating from the input method window.
To intercept hardware keys, override @@ -483,45 +412,36 @@ dismiss any popups SoftKeyboard sample app for an example.
- Remember to call the super() method for keys you don't want to
-handle yourself.
+ Remember to call the super() method for keys you don't want to handle yourself.
- Subtypes allow the IME to expose multiple input modes and languages -supported by an IME. A subtype can represent: + Subtypes allow the IME to expose multiple input modes and languages supported by an IME. A + subtype can represent:
- Basically, the mode can be any text such as "keyboard", "voice", and so -forth. A subtype can also expose a combination of these. + Basically, the mode can be any text such as "keyboard", "voice", and so forth. A subtype can + also expose a combination of these.
- Subtype information is used for an IME switcher dialog that's available -from the notification - bar and also for IME settings. The information also allows the framework to -bring up a - specific subtype of an IME directly. When you build an IME, use the subtype -facility, because - it helps the user identify and switch between different IME languages and -modes. -
-
- You define subtypes in one of the input method's XML resource files, using
-the
- <subtype> element. The following snippet defines an IME
-with two
- subtypes: a keyboard subtype for the US English locale, and another
-keyboard subtype for the
+ Subtype information is used for an IME switcher dialog that's available from the notification
+ bar and also for IME settings. The information also allows the framework to bring up a
+ specific subtype of an IME directly. When you build an IME, use the subtype facility, because
+ it helps the user identify and switch between different IME languages and modes.
+
+ You define subtypes in one of the input method's XML resource files, using the
+ <subtype> element. The following snippet defines an IME with two
+ subtypes: a keyboard subtype for the US English locale, and another keyboard subtype for the
French language locale for France:
@@ -546,10 +466,8 @@ keyboard subtype for the />
- To ensure that your subtypes are labeled correctly in the UI, use %s to get -a subtype label - that is the same as the subtype’s locale label. This is demonstrated in -the next two snippets. + To ensure that your subtypes are labeled correctly in the UI, use %s to get a subtype label + that is the same as the subtype’s locale label. This is demonstrated in the next two snippets. The first snippet shows part of the input method's XML file:
@@ -560,10 +478,8 @@ the next two snippets.
android:imeSubtypeMode="keyboard" />
- The next snippet is part of the IME's strings.xml file. The
-string
- resource label_subtype_generic, which is used by the input
-method UI definition to
+ The next snippet is part of the IME's strings.xml file. The string
+ resource label_subtype_generic, which is used by the input method UI definition to
set the subtype's label, is defined as:
@@ -575,12 +491,9 @@ method UI definition toChoosing IME subtypes from the notification bar
- The Android system manages all subtypes exposed by all IMEs. IME subtypes -are - treated as modes of the IME they belong to. In the notification bar, a user -can select an - available subtype for the currently-set IME, as shown in the following -screenshot: + The Android system manages all subtypes exposed by all IMEs. IME subtypes are + treated as modes of the IME they belong to. In the notification bar, a user can select an + available subtype for the currently-set IME, as shown in the following screenshot:
![]()
Choosing IME subtypes from System Settings
- A user can control how subtypes are used in the “Language & input” -settings panel in the - System Settings area. In the + A user can control how subtypes are used in the “Language & input” settings panel in the + System Settings area. In the + SoftKeyboard sample app, the file
+into an IME without a switching key, he or she may get stuck in that IME, unable to switch out of it easily.InputMethodSettingsFragment.javacontains an implementation that facilitates a subtype enabler in the IME settings. Refer to the @@ -617,15 +530,14 @@ alt=""Switching among IME Subtypes
-You can allow users to switch easily among multiple IME subtypes by providing -a switching key, such as the globe-shaped language icon, as part of the keyboard. Doing so greatly -improves the keyboard's usability, and can help avoid user frustration. +
You can allow users to switch easily among multiple IME subtypes by providing a switching key, +such as the globe-shaped language icon, as part of the keyboard. Doing so greatly improves the +keyboard's usability, and can help avoid user frustration. To enable such switching, perform the following steps:
-
- Declare
supportsSwitchingToNextInputMethod = "true"in the -input method's XML resource files. Your declaration - should look similar to the following snippet: +- Declare
supportsSwitchingToNextInputMethod = "true"in the input method's XML + resource files. Your declaration should look similar to the following snippet:<input-method xmlns:android="http://schemas.android.com/apk/res/android" android:settingsActivity="com.example.softkeyboard.Settings" @@ -646,8 +558,7 @@ input method's XML resource files. Your declaration Caution: Prior to Android 5.0 (API level 21), {@link android.view.inputmethod.InputMethodManager#switchToNextInputMethod switchToNextInputMethod()} is not aware of thesupportsSwitchingToNextInputMethodattribute. If the user switches -into an IME without a switching key, he or she may get stuck in that IME, unable to switch out of it -easily.@@ -662,31 +573,23 @@ easily.
Provide a way for users to set options directly from the IME's UI.