| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 1 | page.title=Creating an Input Method |
| Joe Fernandez | 33baa5a | 2013-11-14 11:41:19 -0800 | [diff] [blame] | 2 | page.tags=ime,keyboard,inputmethodservice |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 3 | @jd:body |
| 4 | |
| 5 | <div id="qv-wrapper"> |
| 6 | <div id="qv"> |
| David Friedman | 86efa01 | 2014-07-22 00:22:00 -0700 | [diff] [blame] | 7 | <h2>In This Document</h2> |
| 8 | <ol> |
| David Friedman | e802d54 | 2014-10-08 10:38:31 -0700 | [diff] [blame] | 9 | <li><a href="#InputMethodLifecycle">The IME Lifecycle</a></li> |
| 10 | <li><a href="#DefiningIME">Declaring IME Components in the Manifest</a></li> |
| 11 | <li><a href="#IMEAPI">The Input Method API</a></li> |
| 12 | <li><a href="#IMEUI">Designing the Input Method UI</a></li> |
| 13 | <li><a href="#SendText">Sending Text to the Application</a></li> |
| 14 | <li><a href="#IMESubTypes">Creating an IME Subtype</a></li> |
| 15 | <li><a href="#Switching">Switching among IME Subtypes</a></li> |
| 16 | <li><a href="#GeneralDesign">General IME Considerations</a></li> |
| David Friedman | 86efa01 | 2014-07-22 00:22:00 -0700 | [diff] [blame] | 17 | </ol> |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 18 | <h2>See also</h2> |
| 19 | <ol> |
| 20 | <li> |
| 21 | <a href="http://android-developers.blogspot.com/2009/04/updating-applications-for-on-screen.html">Onscreen Input Methods</a> |
| 22 | </li> |
| David Friedman | e802d54 | 2014-10-08 10:38:31 -0700 | [diff] [blame] | 23 | </ol> |
| 24 | |
| 25 | <h2>Sample</h2> |
| 26 | <ol> |
| 27 | <li><a href="https://android.googlesource.com/platform/development/+/master/samples/SoftKeyboard/"> |
| 28 | SoftKeyboard</a> |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 29 | </li> |
| 30 | </ol> |
| David Friedman | e802d54 | 2014-10-08 10:38:31 -0700 | [diff] [blame] | 31 | |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 32 | </div> |
| 33 | </div> |
| 34 | <p> |
| David Friedman | 86efa01 | 2014-07-22 00:22:00 -0700 | [diff] [blame] | 35 | An input method editor (IME) is a user control that enables users to enter text. Android |
| David Friedman | e802d54 | 2014-10-08 10:38:31 -0700 | [diff] [blame] | 36 | provides an extensible input-method framework that allows applications to provide users |
| 37 | alternative input methods, such as on-screen keyboards or even speech input. After installing |
| 38 | the desired IMEs, a user can select which one to use from the system settings, and use it |
| 39 | across the entire system; only one IME may be enabled at a time. |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 40 | </p> |
| 41 | <p> |
| 42 | To add an IME to the Android system, you create an Android application |
| David Friedman | 86efa01 | 2014-07-22 00:22:00 -0700 | [diff] [blame] | 43 | containing a class that extends {@link android.inputmethodservice.InputMethodService}. In |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 44 | addition, you usually create a "settings" activity that passes options to the IME service. You |
| 45 | can also define a settings UI that's displayed as part of the system settings. |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 46 | </p> |
| David Friedman | e802d54 | 2014-10-08 10:38:31 -0700 | [diff] [blame] | 47 | <p>This guide covers the following:</p> |
| 48 | <ul> |
| 49 | <li>The IME lifecycle</li> |
| 50 | <li>Declaring IME components in the application manifest</li> |
| 51 | <li>The IME API</li> |
| 52 | <li>Designing an IME UI</li> |
| 53 | <li>Sending text from an IME to an application</li> |
| 54 | <li>Working with IME subtypes</li> |
| 55 | </ul> |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 56 | <p> |
| David Friedman | 86efa01 | 2014-07-22 00:22:00 -0700 | [diff] [blame] | 57 | If you haven't worked with IMEs before, you should read the introductory article |
| David Friedman | e802d54 | 2014-10-08 10:38:31 -0700 | [diff] [blame] | 58 | <a href="http://android-developers.blogspot.com/2009/04/updating-applications-for-on-screen.html">Onscreen Input Methods</a> |
| 59 | first. |
| 60 | Also, the <a href="https://android.googlesource.com/platform/development/+/master/samples/SoftKeyboard/"> |
| 61 | SoftKeyboard</a> sample app included in the SDK contains sample code that you can modify to |
| 62 | start building your own IME. |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 63 | </p> |
| 64 | <h2 id="InputMethodLifecycle">The IME Lifecycle</h2> |
| 65 | <p> |
| 66 | The following diagram describes the life cycle of an IME: |
| 67 | </p> |
| David Friedman | e802d54 | 2014-10-08 10:38:31 -0700 | [diff] [blame] | 68 | <img src="{@docRoot}resources/articles/images/inputmethod_lifecycle_image.png" alt="" height="845" id="figure1" /> |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 69 | <p class="img-caption"> |
| 70 | <strong>Figure 1.</strong> The life cycle of an IME. |
| 71 | </p> |
| 72 | <p> |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 73 | The following sections describe how to implement the UI and code associated with an IME that |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 74 | follows this lifecycle. |
| 75 | </p> |
| 76 | <h2 id="DefiningIME">Declaring IME Components in the Manifest</h2> |
| 77 | <p> |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 78 | In the Android system, an IME is an Android application that contains a special IME service. |
| 79 | The application's manifest file must declare the service, request the necessary permissions, |
| 80 | provide an intent filter that matches the action <code>action.view.InputMethod</code>, and |
| 81 | provide metadata that defines characteristics of the IME. In addition, to provide a settings |
| 82 | interface that allows the user to modify the behavior of the IME, you can define a "settings" |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 83 | activity that can be launched from System Settings. |
| 84 | </p> |
| 85 | <p> |
| David Friedman | e802d54 | 2014-10-08 10:38:31 -0700 | [diff] [blame] | 86 | The following snippet declares an IME service. It requests the permission |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 87 | {@link android.Manifest.permission#BIND_INPUT_METHOD} to allow the service to connect the IME |
| 88 | to the system, sets up an intent filter that matches the action |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 89 | <code>android.view.InputMethod</code>, and defines metadata for the IME: |
| 90 | </p> |
| 91 | <pre> |
| 92 | <!-- Declares the input method service --> |
| 93 | <service android:name="FastInputIME" |
| 94 | android:label="@string/fast_input_label" |
| 95 | android:permission="android.permission.BIND_INPUT_METHOD"> |
| 96 | <intent-filter> |
| 97 | <action android:name="android.view.InputMethod" /> |
| 98 | </intent-filter> |
| David Friedman | e802d54 | 2014-10-08 10:38:31 -0700 | [diff] [blame] | 99 | <meta-data android:name="android.view.im" |
| 100 | android:resource="@xml/method" /> |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 101 | </service> |
| 102 | </pre> |
| 103 | <p> |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 104 | This next snippet declares the settings activity for the IME. It has an intent filter for |
| 105 | {@link android.content.Intent#ACTION_MAIN} that indicates this activity is the main entry point |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 106 | for the IME application:</p> |
| 107 | <pre> |
| 108 | <!-- Optional: an activity for controlling the IME settings --> |
| David Friedman | 86efa01 | 2014-07-22 00:22:00 -0700 | [diff] [blame] | 109 | <activity android:name="FastInputIMESettings" |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 110 | android:label="@string/fast_input_settings"> |
| 111 | <intent-filter> |
| 112 | <action android:name="android.intent.action.MAIN"/> |
| 113 | </intent-filter> |
| 114 | </activity> |
| 115 | </pre> |
| 116 | <p> |
| 117 | You can also provide access to the IME's settings directly from its UI. |
| 118 | </p> |
| 119 | <h2 id="IMEAPI">The Input Method API</h2> |
| 120 | <p> |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 121 | Classes specific to IMEs are found in the {@link android.inputmethodservice} and |
| 122 | {@link android.view.inputmethod} packages. The {@link android.view.KeyEvent} class is |
| 123 | important for handling keyboard characters. |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 124 | </p> |
| 125 | <p> |
| David Friedman | 86efa01 | 2014-07-22 00:22:00 -0700 | [diff] [blame] | 126 | The central part of an IME is a service component, a class that extends |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 127 | {@link android.inputmethodservice.InputMethodService}. In addition to implementing the |
| 128 | normal service lifecycle, this class has callbacks for providing your IME's UI, handling user |
| 129 | input, and delivering text to the field that currently has focus. By default, the |
| 130 | {@link android.inputmethodservice.InputMethodService} class provides most of the implementation |
| 131 | for managing the state and visibility of the IME and communicating with the current input |
| 132 | field. |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 133 | </p> |
| 134 | <p> |
| 135 | The following classes are also important: |
| 136 | </p> |
| 137 | <dl> |
| 138 | <dt>{@link android.view.inputmethod.BaseInputConnection}</dt> |
| 139 | <dd> |
| 140 | Defines the communication channel from an {@link android.view.inputmethod.InputMethod} |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 141 | back to the application that is receiving its input. You use it to read text around the |
| 142 | cursor, commit text to the text box, and send raw key events to the application. |
| 143 | Applications should extend this class rather than implementing the base interface |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 144 | {@link android.view.inputmethod.InputConnection}. |
| 145 | </dd> |
| 146 | <dt>{@link android.inputmethodservice.KeyboardView}</dt> |
| 147 | <dd> |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 148 | An extension of {@link android.view.View} that renders a keyboard and responds to user |
| David Friedman | 86efa01 | 2014-07-22 00:22:00 -0700 | [diff] [blame] | 149 | input events. The keyboard layout is specified by an instance of |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 150 | {@link android.inputmethodservice.Keyboard}, which you can define in an XML file. |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 151 | </dd> |
| 152 | </dl> |
| 153 | <h2 id="IMEUI">Designing the Input Method UI</h2> |
| 154 | <p> |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 155 | There are two main visual elements for an IME: the <strong>input</strong> view and the |
| 156 | <strong>candidates</strong> view. You only have to implement the elements that are relevant to |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 157 | the input method you're designing. |
| 158 | </p> |
| 159 | <h3 id="InputView">Input view</h3> |
| 160 | <p> |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 161 | The input view is the UI where the user inputs text in the form of keyclicks, handwriting or |
| 162 | gestures. When the IME is displayed for the first time, the system calls the |
| 163 | {@link android.inputmethodservice.InputMethodService#onCreateInputView()} callback. In your |
| 164 | implementation of this method, you create the layout you want to display in the IME |
| 165 | window and return the layout to the system. This snippet is an example of implementing the |
| 166 | {@link android.inputmethodservice.InputMethodService#onCreateInputView()} method: |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 167 | <pre> |
| David Friedman | 86efa01 | 2014-07-22 00:22:00 -0700 | [diff] [blame] | 168 | @Override |
| 169 | public View onCreateInputView() { |
| 170 | MyKeyboardView inputView = |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 171 | (MyKeyboardView) getLayoutInflater().inflate( R.layout.input, null); |
| David Friedman | 86efa01 | 2014-07-22 00:22:00 -0700 | [diff] [blame] | 172 | |
| David Friedman | e802d54 | 2014-10-08 10:38:31 -0700 | [diff] [blame] | 173 | inputView.setOnKeyboardActionListener(this); |
| 174 | inputView.setKeyboard(mLatinKeyboard); |
| David Friedman | 86efa01 | 2014-07-22 00:22:00 -0700 | [diff] [blame] | 175 | |
| 176 | return mInputView; |
| 177 | } |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 178 | </pre> |
| 179 | <p> |
| David Friedman | e802d54 | 2014-10-08 10:38:31 -0700 | [diff] [blame] | 180 | In this example, {@code MyKeyboardView} is an instance of a custom |
| 181 | implementation of |
| David Friedman | 86efa01 | 2014-07-22 00:22:00 -0700 | [diff] [blame] | 182 | {@link android.inputmethodservice.KeyboardView} that renders a |
| David Friedman | e802d54 | 2014-10-08 10:38:31 -0700 | [diff] [blame] | 183 | {@link android.inputmethodservice.Keyboard}. If you’re building a |
| 184 | traditional QWERTY keyboard, |
| 185 | see the <a href="https://android.googlesource.com/platform/development/+/master/samples/SoftKeyboard/> |
| 186 | SoftKeyboard</a> sample app for an example of how to extend the {@link android.inputmethodservice.KeyboardView} |
| 187 | class. |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 188 | </p> |
| 189 | <h3 id="CandidateView">Candidates view</h3> |
| 190 | <p> |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 191 | The candidates view is the UI where the IME displays potential word corrections or |
| David Friedman | 86efa01 | 2014-07-22 00:22:00 -0700 | [diff] [blame] | 192 | suggestions for the user to select. In the IME lifecycle, the system calls |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 193 | {@link android.inputmethodservice.InputMethodService#onCreateCandidatesView()} when it's ready |
| 194 | to display the candidates view. In your implementation of this method, return a layout that |
| 195 | shows word suggestions, or return null if you don’t want to show anything. A null response is |
| 196 | the default behavior, so you don’t have to implement this if you don’t provide suggestions.</p> |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 197 | <p> |
| David Friedman | 86efa01 | 2014-07-22 00:22:00 -0700 | [diff] [blame] | 198 | For an example implementation that provides user suggestions, see the |
| David Friedman | e802d54 | 2014-10-08 10:38:31 -0700 | [diff] [blame] | 199 | <a href="https://android.googlesource.com/platform/development/+/master/samples/SoftKeyboard/"> |
| 200 | SoftKeyboard</a> sample app. |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 201 | </p> |
| 202 | <h3 id="DesignConsiderations">UI design considerations</h3> |
| 203 | <p> |
| 204 | This section describes some specific UI design considerations for IMEs. |
| 205 | </p> |
| 206 | <h4>Handling multiple screen sizes</h4> |
| 207 | <p> |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 208 | The UI for your IME must be able to scale for different screen sizes, and it also |
| 209 | must handle both landscape and portrait orientations. In non-fullscreen IME mode, leave |
| 210 | sufficient space for the application to show the text field and any associated context, so that |
| 211 | no more than half the screen is occupied by the IME. In fullscreen IME mode this is not an |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 212 | issue. |
| 213 | </p> |
| 214 | <h4>Handling different input types</h4> |
| 215 | <p> |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 216 | Android text fields allow you to set a specific input type, such as free-form text, numbers, |
| 217 | URLs, email addresses, and search strings. When you implement a new IME, you need to detect |
| 218 | the input type of each field and provide the appropriate interface for it. However, you |
| 219 | don't have to set up your IME to check that the user entered text valid for the input type; |
| 220 | that's the responsibility of the application that owns the text field. |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 221 | </p> |
| 222 | <p> |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 223 | For example, here are screenshots of the interfaces that the Latin IME provided with the |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 224 | Android platform provides for text and phone number inputs: |
| 225 | </p> |
| David Friedman | e802d54 | 2014-10-08 10:38:31 -0700 | [diff] [blame] | 226 | <img src="{@docRoot}resources/articles/images/inputmethod_text_type_screenshot.png" alt="" height="142" id="figure2" /> |
| 227 | <img src="{@docRoot}resources/articles/images/inputmethod_numeric_type_screenshot.png" alt="" height="120" id="figure2a" /> |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 228 | <p class="img-caption"> |
| 229 | <strong>Figure 2.</strong> Latin IME input types. |
| 230 | </p> |
| 231 | <p> |
| David Friedman | 86efa01 | 2014-07-22 00:22:00 -0700 | [diff] [blame] | 232 | When an input field receives focus and your IME starts, the system calls |
| David Friedman | e802d54 | 2014-10-08 10:38:31 -0700 | [diff] [blame] | 233 | {@link android.inputmethodservice.InputMethodService#onStartInputView(EditorInfo, boolean) onStartInputView()}, |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 234 | passing in an {@link android.view.inputmethod.EditorInfo} object that contains details about |
| 235 | the input type and other attributes of the text field. In this object, the |
| 236 | {@link android.view.inputmethod.EditorInfo#inputType} field contains the text field's input |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 237 | type. |
| 238 | </p> |
| 239 | <p> |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 240 | The {@link android.view.inputmethod.EditorInfo#inputType} field is an <code>int</code> |
| 241 | that contains bit patterns for various input type settings. To test it for the text field's |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 242 | input type, mask it with the constant {@link android.text.InputType#TYPE_MASK_CLASS}, like |
| 243 | this: |
| 244 | </p> |
| 245 | <pre> |
| David Friedman | 86efa01 | 2014-07-22 00:22:00 -0700 | [diff] [blame] | 246 | inputType & InputType.TYPE_MASK_CLASS |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 247 | </pre> |
| 248 | <p> |
| 249 | The input type bit pattern can have one of several values, including: |
| 250 | </p> |
| 251 | <dl> |
| 252 | <dt>{@link android.text.InputType#TYPE_CLASS_NUMBER}</dt> |
| 253 | <dd> |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 254 | A text field for entering numbers. As illustrated in the previous screen shot, the |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 255 | Latin IME displays a number pad for fields of this type. |
| 256 | </dd> |
| 257 | <dt>{@link android.text.InputType#TYPE_CLASS_DATETIME}</dt> |
| 258 | <dd> |
| 259 | A text field for entering a date and time. |
| 260 | </dd> |
| 261 | <dt>{@link android.text.InputType#TYPE_CLASS_PHONE}</dt> |
| 262 | <dd> |
| 263 | A text field for entering telephone numbers. |
| 264 | </dd> |
| 265 | <dt>{@link android.text.InputType#TYPE_CLASS_TEXT}</dt> |
| 266 | <dd> |
| 267 | A text field for entering all supported characters. |
| 268 | </dd> |
| 269 | </dl> |
| 270 | <p> |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 271 | These constants are described in more detail in the reference documentation for |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 272 | {@link android.text.InputType}. |
| 273 | </p> |
| 274 | <p> |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 275 | The {@link android.view.inputmethod.EditorInfo#inputType} field can contain other bits that |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 276 | indicate a variant of the text field type, such as: |
| 277 | </p> |
| 278 | <dl> |
| 279 | <dt>{@link android.text.InputType#TYPE_TEXT_VARIATION_PASSWORD}</dt> |
| 280 | <dd> |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 281 | A variant of {@link android.text.InputType#TYPE_CLASS_TEXT} for entering passwords. The |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 282 | input method will display dingbats instead of the actual text. |
| 283 | </dd> |
| 284 | <dt>{@link android.text.InputType#TYPE_TEXT_VARIATION_URI}</dt> |
| 285 | <dd> |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 286 | A variant of {@link android.text.InputType#TYPE_CLASS_TEXT} for entering web URLs and |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 287 | other Uniform Resource Identifiers (URIs). |
| 288 | </dd> |
| 289 | <dt>{@link android.text.InputType#TYPE_TEXT_FLAG_AUTO_COMPLETE}</dt> |
| 290 | <dd> |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 291 | A variant of {@link android.text.InputType#TYPE_CLASS_TEXT} for entering text that the |
| 292 | application "auto-completes" from a dictionary, search, or other facility. |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 293 | </dd> |
| 294 | </dl> |
| 295 | <p> |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 296 | Remember to mask {@link android.view.inputmethod.EditorInfo#inputType} with the appropriate |
| 297 | constant when you test for these variants. The available mask constants are listed in the |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 298 | reference documentation for {@link android.text.InputType}. |
| 299 | </p> |
| 300 | <p class="caution"> |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 301 | <strong>Caution:</strong> In your own IME, make sure you handle text correctly when you send it |
| 302 | to a password field. Hide the password in your UI both in the input view and in the candidates |
| 303 | view. Also remember that you shouldn't store passwords on a device. To learn more, see the |
| 304 | <a href="{@docRoot}guide/practices/security.html">Designing for Security</a> guide. |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 305 | </p> |
| 306 | <h2 id="SendText">Sending Text to the Application</h2> |
| 307 | <p> |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 308 | As the user inputs text with your IME, you can send text to the application by sending |
| 309 | individual key events or by editing the text around the cursor in the application's text |
| David Friedman | 86efa01 | 2014-07-22 00:22:00 -0700 | [diff] [blame] | 310 | field. In either case, you use an instance of {@link android.view.inputmethod.InputConnection} |
| 311 | to deliver the text. To get this instance, call |
| David Friedman | e802d54 | 2014-10-08 10:38:31 -0700 | [diff] [blame] | 312 | {@link android.inputmethodservice.InputMethodService#getCurrentInputConnection InputMethodService.getCurrentInputConnection()}. |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 313 | </p> |
| 314 | <h3 id="EditingCursor">Editing the text around the cursor</h3> |
| 315 | <p> |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 316 | When you're handling the editing of existing text in a text field, some of the more useful |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 317 | methods in {@link android.view.inputmethod.BaseInputConnection} are: |
| 318 | </p> |
| 319 | <dl> |
| 320 | <dt> |
| David Friedman | e802d54 | 2014-10-08 10:38:31 -0700 | [diff] [blame] | 321 | {@link android.view.inputmethod.BaseInputConnection#getTextBeforeCursor(int, int) getTextBeforeCursor()}</dt> |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 322 | <dd> |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 323 | Returns a {@link java.lang.CharSequence} containing the number of requested characters |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 324 | before the current cursor position. |
| 325 | </dd> |
| 326 | <dt> |
| David Friedman | e802d54 | 2014-10-08 10:38:31 -0700 | [diff] [blame] | 327 | {@link android.view.inputmethod.BaseInputConnection#getTextAfterCursor(int, int) getTextAfterCursor()} |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 328 | </dt> |
| 329 | <dd> |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 330 | Returns a {@link java.lang.CharSequence} containing the number of requested characters |
| 331 | following the current cursor position. |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 332 | </dd> |
| 333 | <dt> |
| David Friedman | e802d54 | 2014-10-08 10:38:31 -0700 | [diff] [blame] | 334 | {@link android.view.inputmethod.BaseInputConnection#deleteSurroundingText(int, int) deleteSurroundingText()} |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 335 | </dt> |
| 336 | <dd> |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 337 | Deletes the specified number of characters before and following the current cursor |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 338 | position. |
| 339 | </dd> |
| 340 | <dt> |
| David Friedman | e802d54 | 2014-10-08 10:38:31 -0700 | [diff] [blame] | 341 | {@link android.view.inputmethod.BaseInputConnection#commitText(CharSequence, int) commitText()} |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 342 | </dt> |
| 343 | <dd> |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 344 | Commit a {@link java.lang.CharSequence} to the text field and set a new cursor |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 345 | position. |
| 346 | </dd> |
| 347 | </dl> |
| 348 | <p> |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 349 | For example, the following snippet shows how to replace the four characters to the left of the |
| 350 | cursor with the text "Hello!": |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 351 | </p> |
| 352 | <pre> |
| 353 | InputConnection ic = getCurrentInputConnection(); |
| David Friedman | 86efa01 | 2014-07-22 00:22:00 -0700 | [diff] [blame] | 354 | |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 355 | ic.deleteSurroundingText(4, 0); |
| David Friedman | 86efa01 | 2014-07-22 00:22:00 -0700 | [diff] [blame] | 356 | |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 357 | ic.commitText("Hello", 1); |
| David Friedman | 86efa01 | 2014-07-22 00:22:00 -0700 | [diff] [blame] | 358 | |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 359 | ic.commitText("!", 1); |
| 360 | </pre> |
| 361 | <h3 id="ComposeThenCommit">Composing text before committing</h3> |
| 362 | <p> |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 363 | If your IME does text prediction or requires multiple steps to compose a glyph or |
| 364 | word, you can show the progress in the text field until the user commits the word, and then you |
| 365 | can replace the partial composition with the completed text. You may give special treatment to |
| David Friedman | e802d54 | 2014-10-08 10:38:31 -0700 | [diff] [blame] | 366 | the text by adding a "span" to it when you pass it to |
| 367 | {@link android.view.inputmethod.InputConnection#setComposingText setComposingText()}. |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 368 | </p> |
| 369 | <p> |
| 370 | The following snippet shows how to show progress in a text field: |
| 371 | </p> |
| 372 | <pre> |
| 373 | InputConnection ic = getCurrentInputConnection(); |
| 374 | |
| 375 | ic.setComposingText("Composi", 1); |
| 376 | ... |
| 377 | |
| 378 | ic.setComposingText("Composin", 1); |
| 379 | |
| 380 | ... |
| 381 | |
| 382 | ic.commitText("Composing ", 1); |
| 383 | </pre> |
| 384 | <p> |
| 385 | The following screenshots show how this appears to the user: |
| 386 | </p> |
| David Friedman | e802d54 | 2014-10-08 10:38:31 -0700 | [diff] [blame] | 387 | <img src="{@docRoot}resources/articles/images/inputmethod_composing_text_1.png" |
| 388 | alt="" height="54" |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 389 | id="figure3a" /> |
| David Friedman | e802d54 | 2014-10-08 10:38:31 -0700 | [diff] [blame] | 390 | <img src="{@docRoot}resources/articles/images/inputmethod_composing_text_2.png" |
| 391 | alt="" height="53" |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 392 | id="figure3b" /> |
| David Friedman | e802d54 | 2014-10-08 10:38:31 -0700 | [diff] [blame] | 393 | <img src="{@docRoot}resources/articles/images/inputmethod_composing_text_3.png" |
| 394 | alt="" height="31" |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 395 | id="figure3c" /> |
| 396 | <p class="img-caption"> |
| 397 | <strong>Figure 3.</strong> Composing text before committing. |
| 398 | </p> |
| 399 | <h3 id="HardwareKeyEvents">Intercepting hardware key events</h3> |
| 400 | <p> |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 401 | Even though the input method window doesn't have explicit focus, it receives hardware key |
| 402 | events first and can choose to consume them or forward them along to the application. For |
| 403 | example, you may want to consume the directional keys to navigate within your UI for candidate |
| 404 | selection during composition. You may also want to trap the back key to dismiss any popups |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 405 | originating from the input method window.</p> |
| 406 | <p> |
| David Friedman | 86efa01 | 2014-07-22 00:22:00 -0700 | [diff] [blame] | 407 | To intercept hardware keys, override |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 408 | {@link android.inputmethodservice.InputMethodService#onKeyDown(int, KeyEvent) onKeyDown()} |
| David Friedman | 86efa01 | 2014-07-22 00:22:00 -0700 | [diff] [blame] | 409 | and {@link android.inputmethodservice.InputMethodService#onKeyUp(int, KeyEvent) onKeyUp()}. |
| David Friedman | e802d54 | 2014-10-08 10:38:31 -0700 | [diff] [blame] | 410 | See the |
| 411 | <a href="https://android.googlesource.com/platform/development/+/master/samples/SoftKeyboard/"> |
| 412 | SoftKeyboard</a> sample app for an example. |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 413 | </p> |
| 414 | <p> |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 415 | Remember to call the <code>super()</code> method for keys you don't want to handle yourself. |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 416 | </p> |
| 417 | <h2 id="IMESubTypes">Creating an IME Subtype</h2> |
| 418 | <p> |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 419 | Subtypes allow the IME to expose multiple input modes and languages supported by an IME. A |
| 420 | subtype can represent: |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 421 | </p> |
| 422 | <ul> |
| 423 | <li>A locale such as en_US or fr_FR</li> |
| 424 | <li>An input mode such as voice, keyboard, or handwriting</li> |
| 425 | <li> |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 426 | Other input styles, forms, or properties specific to the IME, such as 10-key or qwerty |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 427 | keyboard layouts. |
| 428 | </li> |
| 429 | </ul> |
| 430 | <p> |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 431 | Basically, the mode can be any text such as "keyboard", "voice", and so forth. A subtype can |
| 432 | also expose a combination of these. |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 433 | </p> |
| David Friedman | e802d54 | 2014-10-08 10:38:31 -0700 | [diff] [blame] | 434 | |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 435 | <p> |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 436 | Subtype information is used for an IME switcher dialog that's available from the notification |
| 437 | bar and also for IME settings. The information also allows the framework to bring up a |
| 438 | specific subtype of an IME directly. When you build an IME, use the subtype facility, because |
| 439 | it helps the user identify and switch between different IME languages and modes. |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 440 | </p> |
| 441 | <p> |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 442 | You define subtypes in one of the input method's XML resource files, using the |
| 443 | <code><subtype></code> element. The following snippet defines an IME with two |
| 444 | subtypes: a keyboard subtype for the US English locale, and another keyboard subtype for the |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 445 | French language locale for France: |
| 446 | </p> |
| 447 | <pre> |
| 448 | <input-method xmlns:android="http://schemas.android.com/apk/res/android" |
| 449 | android:settingsActivity="com.example.softkeyboard.Settings" |
| 450 | android:icon="@drawable/ime_icon" |
| 451 | <subtype android:name="@string/display_name_english_keyboard_ime" |
| 452 | android:icon="@drawable/subtype_icon_english_keyboard_ime" |
| 453 | android:imeSubtypeLanguage="en_US" |
| 454 | android:imeSubtypeMode="keyboard" |
| 455 | android:imeSubtypeExtraValue="somePrivateOption=true" |
| 456 | /> |
| 457 | <subtype android:name="@string/display_name_french_keyboard_ime" |
| 458 | android:icon="@drawable/subtype_icon_french_keyboard_ime" |
| 459 | android:imeSubtypeLanguage="fr_FR" |
| 460 | android:imeSubtypeMode="keyboard" |
| 461 | android:imeSubtypeExtraValue="foobar=30,someInternalOption=false" |
| 462 | /> |
| 463 | <subtype android:name="@string/display_name_german_keyboard_ime" |
| 464 | ... |
| 465 | /> |
| 466 | /> |
| 467 | </pre> |
| 468 | <p> |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 469 | To ensure that your subtypes are labeled correctly in the UI, use %s to get a subtype label |
| 470 | that is the same as the subtype’s locale label. This is demonstrated in the next two snippets. |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 471 | The first snippet shows part of the input method's XML file: |
| 472 | </p> |
| 473 | <pre> |
| 474 | <subtype |
| 475 | android:label="@string/label_subtype_generic" |
| 476 | android:imeSubtypeLocale="en_US" |
| 477 | android:icon="@drawable/icon_en_us" |
| 478 | android:imeSubtypeMode="keyboard" /> |
| 479 | </pre> |
| 480 | <p> |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 481 | The next snippet is part of the IME's <code>strings.xml</code> file. The string |
| 482 | resource <code>label_subtype_generic</code>, which is used by the input method UI definition to |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 483 | set the subtype's label, is defined as: |
| 484 | </p> |
| 485 | <pre> |
| 486 | <string name="label_subtype_generic">%s</string> |
| 487 | </pre> |
| 488 | <p> |
| David Friedman | e802d54 | 2014-10-08 10:38:31 -0700 | [diff] [blame] | 489 | This setting causes the subtype’s display name to match the locale setting. |
| 490 | For example, in any English locale, the display name is “English (United States)”. |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 491 | </p> |
| 492 | <h3 id="SubtypeProcessing">Choosing IME subtypes from the notification bar</h3> |
| 493 | <p> |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 494 | The Android system manages all subtypes exposed by all IMEs. IME subtypes are |
| 495 | treated as modes of the IME they belong to. In the notification bar, a user can select an |
| 496 | available subtype for the currently-set IME, as shown in the following screenshot: |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 497 | </p> |
| David Friedman | e802d54 | 2014-10-08 10:38:31 -0700 | [diff] [blame] | 498 | <img |
| 499 | src="{@docRoot}resources/articles/images/inputmethod_subtype_notification.png" |
| 500 | alt="" |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 501 | height="85" id="figure4" /> |
| 502 | <p class="img-caption"> |
| David Friedman | e802d54 | 2014-10-08 10:38:31 -0700 | [diff] [blame] | 503 | <strong>Figure 4.</strong> Choosing an IME subtype from the notification |
| 504 | bar. |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 505 | </p> |
| David Friedman | e802d54 | 2014-10-08 10:38:31 -0700 | [diff] [blame] | 506 | <img |
| 507 | src="{@docRoot}resources/articles/images/inputmethod_subtype_preferences.png" |
| 508 | alt="" |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 509 | height="165" id="figure5" /> |
| 510 | <p class="img-caption"> |
| 511 | <strong>Figure 5.</strong> Setting subtype preferences in System Settings. |
| 512 | </p> |
| 513 | <h3 id="SubtypeSettings">Choosing IME subtypes from System Settings</h3> |
| 514 | <p> |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 515 | A user can control how subtypes are used in the “Language & input” settings panel in the |
| 516 | System Settings area. In the |
| 517 | <a href="https://android.googlesource.com/platform/development/+/master/samples/SoftKeyboard/"> |
| David Friedman | e802d54 | 2014-10-08 10:38:31 -0700 | [diff] [blame] | 518 | SoftKeyboard</a> sample app, the file <code>InputMethodSettingsFragment.java</code> contains an |
| 519 | implementation that facilitates a subtype enabler in the IME settings. Refer to the |
| 520 | <a href="https://android.googlesource.com/platform/development/+/master/samples/SoftKeyboard/"> |
| 521 | SoftKeyboard</a> sample app in the Android SDK for more information about how to support |
| 522 | Input Method Subtypes in your IME. |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 523 | </p> |
| David Friedman | e802d54 | 2014-10-08 10:38:31 -0700 | [diff] [blame] | 524 | <img src="{@docRoot}resources/articles/images/inputmethod_subtype_settings.png" |
| 525 | alt="" |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 526 | height="210" id="figure6" /> |
| 527 | <p class="img-caption"> |
| 528 | <strong>Figure 6.</strong> Choosing a language for the IME. |
| 529 | </p> |
| David Friedman | 86efa01 | 2014-07-22 00:22:00 -0700 | [diff] [blame] | 530 | |
| David Friedman | e802d54 | 2014-10-08 10:38:31 -0700 | [diff] [blame] | 531 | <h2 id="Switching">Switching among IME Subtypes</h2> |
| 532 | |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 533 | <p>You can allow users to switch easily among multiple IME subtypes by providing a switching key, |
| 534 | such as the globe-shaped language icon, as part of the keyboard. Doing so greatly improves the |
| 535 | keyboard's usability, and can help avoid user frustration. |
| David Friedman | e802d54 | 2014-10-08 10:38:31 -0700 | [diff] [blame] | 536 | To enable such switching, perform the following steps:</p> |
| 537 | <p> |
| 538 | <ol> |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 539 | <li>Declare <code>supportsSwitchingToNextInputMethod = "true"</code> in the input method's XML |
| 540 | resource files. Your declaration should look similar to the following snippet: |
| David Friedman | e802d54 | 2014-10-08 10:38:31 -0700 | [diff] [blame] | 541 | <pre> |
| 542 | <input-method xmlns:android="http://schemas.android.com/apk/res/android" |
| 543 | android:settingsActivity="com.example.softkeyboard.Settings" |
| 544 | android:icon="@drawable/ime_icon" |
| 545 | android:supportsSwitchingToNextInputMethod="true"> |
| 546 | </pre></li> |
| 547 | <li>Call the {@link android.view.inputmethod.InputMethodManager#shouldOfferSwitchingToNextInputMethod shouldOfferSwitchingToNextInputMethod()} method.</li> |
| 548 | <li>If the method returns true, display a switching key.</li> |
| 549 | <li>When the user taps the switching key, call |
| 550 | {@link android.view.inputmethod.InputMethodManager#switchToNextInputMethod switchToNextInputMethod()}, |
| 551 | passing false to the second parameter. A value of false tells the system to treat all subtypes |
| 552 | equally, regardless of what IME they belong to. Specifying true requires the system to cycle |
| 553 | through subtypes in the current IME.</li> |
| 554 | </ol> |
| 555 | </p> |
| 556 | |
| 557 | <p class="caution"> |
| 558 | <strong>Caution:</strong> Prior to Android 5.0 (API level 21), |
| 559 | {@link android.view.inputmethod.InputMethodManager#switchToNextInputMethod switchToNextInputMethod()} |
| 560 | is not aware of the <code>supportsSwitchingToNextInputMethod</code> attribute. If the user switches |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 561 | into an IME without a switching key, he or she may get stuck in that IME, unable to switch out of it easily.</p> |
| David Friedman | e802d54 | 2014-10-08 10:38:31 -0700 | [diff] [blame] | 562 | |
| 563 | <p> |
| 564 | |
| 565 | </p> |
| 566 | |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 567 | <h2 id="GeneralDesign">General IME Considerations</h2> |
| 568 | <p> |
| 569 | Here are some other things to consider as you're implementing your IME: |
| 570 | </p> |
| 571 | <ul> |
| 572 | <li> |
| 573 | Provide a way for users to set options directly from the IME's UI. |
| 574 | </li> |
| 575 | <li> |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 576 | Because multiple IMEs may be installed on the device, provide a way for the user to switch to a |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 577 | different IME directly from the input method UI. |
| 578 | </li> |
| 579 | <li> |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 580 | Bring up the IME's UI quickly. Preload or load on demand any large resources so that users |
| 581 | see the IME as soon as they tap on a text field. Cache resources and views for subsequent |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 582 | invocations of the input method. |
| 583 | </li> |
| 584 | <li> |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 585 | Conversely, you should release large memory allocations soon after the input method window is |
| 586 | hidden, so that applications can have sufficient memory to run. Consider using a delayed |
| 587 | message to release resources if the IME is in a hidden state for a few seconds. |
| David Friedman | 86efa01 | 2014-07-22 00:22:00 -0700 | [diff] [blame] | 588 | </li> |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 589 | <li> |
| David Friedman | 0fa6edc | 2014-10-27 18:19:55 -0700 | [diff] [blame] | 590 | Make sure that users can enter as many characters as possible for the language or locale |
| 591 | associated with the IME. Remember that users may use punctuation in passwords or user |
| 592 | names, so your IME has to provide many different characters to allow users to enter a |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 593 | password and get access to the device. |
| 594 | </li> |
| David Friedman | e802d54 | 2014-10-08 10:38:31 -0700 | [diff] [blame] | 595 | </ul> |