Android输入法开发

1. 概念

* IMF: 输入法框架(Input Method Framework)

* IM: 输入法(Input Method)

* IMS: 输入法服务(Input Method Service)

* IMMS: 输入法服务管理器(Input Method Manager Service), system process的一部分,系统中只有一个该服务的实例

* IMM: 输入法管理器(Input Method Manager), 每个客户端进程包含一个该实例

* IME: 泛指一个具体的输入法APK,(Input Method Engine),包括其内部的IMS和各种Binder

2. 核心思想

 * 以Service方式运行具体的输入法

 * 在Service中创建输入法窗口,并把输入内容传递到EditText框中

3. IME两个Binder

 * IMS对应的Binder, IMMS通过该Binder去控制输入法,如: 显示、隐藏等

 * 专门供客户端调用的Binder, 该对象用于 在输入的过程中,客户端 将事件 传给输入法

4. IME几个要素

4.1 IME 与 EditText框 交互 —— InputConnection

4.2 IME 与 用户 交互

    * InputView: 获取 用户输入

    * Candidate View:根据用户输入形成候选词栏 给用户反馈

5. 动手写一个IME

    * 新建一个工程CarloZ IME, 创建一个Java类 CarloZIME.java, 让它继承 InputMethodService;

    * 新建一个SettingActivity,作为IME的设定

    * 在res/xml 下新建 method.xml, 将下面的代码 修改以后拷贝进去(im_is_default 默认是true)

<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright (C) 2009 The Android Open Source Project

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->
<!-- The attributes in this XML file provide configuration information -->
<!-- for the Search Manager. -->
<input-method xmlns:android="http://schemas.android.com/apk/res/android"
    android:isDefault="@bool/im_is_default"
    android:settingsActivity="com.carloz.inputmethod.setting.CarloZIMESettingActivity" >

</input-method>

    * 在AndroidManifest.xml中配置如下

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.carloz.inputmethod">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme">
        <service
            android:name="com.carloz.inputmethod.CarloZIME"
            android:label="@string/app_name"
            android:permission="android.permission.BIND_INPUT_METHOD">
            <intent-filter android:priority="1">
                <action android:name="android.view.InputMethod" />
            </intent-filter>
            <meta-data
                android:name="android.view.im"
                android:resource="@xml/method" />
        </service>

        <activity
            android:name=".setting.CarloZIMESettingActivity"
            android:label="@string/title_activity_carlo_zimesetting">
        </activity>

    </application>

</manifest>

    此时一个最简单的输入法就配置完了

    问题 1: 如何与EditText框 交互

    问题2: 如何获取用户输入

接下来的的我们来解决这俩问题

6. IME 与 EditText交互 —— InputConnection

    因为CarloZIME.java继承了 InputMethodService, 所以它拥有一个方法 getCurrentInputConnection()

    前面我们说过,InputConnection 是用来跟 EditText框交互的,说到这里你肯定已经懂了,没错,就是这样

InputConnection ic = getCurrentInputConnection();
ic.commitText("Hello CarloZ", 0);

   在合适的地方调用上述代码,就会向EditText框中 提交 Hello CarloZ 这个字符串。

    InputConnection 是一个接口,它与EditText交互的方式可以分为3种: 读取,插入,替换

      (1) 获取 EditText 框中已有的字符, 方式分为 以相对光标的位置获取使用绝对位置获取

             * getTextBeforeCursor(n, flag); 获取光标前面的n个字符

             * getTextAfterCursor(n, flag); 获取光标后面的n个字符

             * getExtractedText(request, flags); 获取当前Edit框所有文字

             * setSelection(start, end); 设置绝对位置,从start到end处

             * getSelectedText(flags); 获取绝对区域的文字,该区域由setSelection决定

      (2)向EditText框中 添加删除 字符

             * deleteSurroudingText(left, right): 删除当前光标处 前面left个字符 和 后面 right个字符

             * commitText(text, pos); 传递text给 EditText, 并且移动 光标到pos处

             * commitCompletion(CompletionInfo text); 完成提交,一般是切换到另一个EditText框之前调用,从而使得客户端在此做点什么

      (3)替换 EditText中的字符

             * setComposingRegion(start, end); 设置替换区域为 从 start到end处

             * setComposingText(text, pos); 把替换区域的文字替换为 text,并把光标移动到pos 处

             * finishComposingText(); 可以重复设置替换区域并进行替换,完成后,使用该API 通知客户端

      (4)特殊功能 getCursorCapsMode(reqModes), 用于获取 当前 光标处的大写模式

7. 与 用户交互

    现在我们的IME还没有View, 所以 虽然输入法在运行,但是你什么都看不到,用户自然也就无法 输入任何东西

原文地址:https://www.cnblogs.com/carlo/p/4737523.html