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