浅谈Android输入法(IME)架构

简介:

输入法 (IME) 是一种可让用户输入文本的用户控件。Android
提供了一种可扩展的输入法框架。借助该框架,应用可以为用户提供备选输入法,例如屏幕键盘,甚至语音输入。安装所需的 IME
后,用户可以从系统设置中选择要使用的 IME,并在整个系统中使用该 IME;同时只能启用一个 IME。
如何开发一个简单的输入法,这得先了解一下Android中自带的输入法框架IMF

1.IME生命周期:


输入法本质就是一个Service,假设用户现在刚刚启动一个APP,焦点首次进入文本编辑框时,Android就会通知Service开始进行初始化,便有了生命周期图中所示的:

  • 首先执行onCreate方法,该方法做了一些字符串变量分隔符的初始化。

  • 其次执行onCreateInputView方法,在要显示用户输入的区域时,Android自带框架会调用这个方法,该方法对inputview进行初始化,读取布局文件信息,设置onKeyboardActionListener,并初始设置keyboard。

  • 然后执行onCreateCandidatesView方法,在要显示一些候选词的视图时由框架调用,和上面的onCreateInputView方法类似,在这里是对candidateview进行初始化。

  • 最后执行onStartInputView方法,将 inputview跟当前的keyboard重新关联起来。

2.Android输入法架构图:

在这里插入图片描述
图中一些名词含义解释:

  • IMMS:输入法管理服务InputMethodManagerService
  • IMM:输入法管理 InputMethodManager
  • IMS:输入法服务 InputMethodService

3.框架中部分组件使用

在 Android 系统中,IME 是包含一项特殊 IME 服务的 Android 应用。
应用的清单文件必须声明该服务,请求必需的权限,提供一个与操作 action.view.InputMethod 匹配的 Intent
过滤器,并提供定义 IME 特征的元数据。

BIND_MIDI_DEVICE_SERVICE权限
在这里插入图片描述

以下代码段声明了一项 IME 服务:

<!-- Declares the input method service -->
<service android:name="FastInputIME"
    android:label="@string/fast_input_label"
    android:permission="android.permission.BIND_INPUT_METHOD">
    ***//请求BIND_MIDI_DEVICE_SERVICE让此服务可以将IME连接到系统***
    <intent-filter>
   //设置一个与InputMethod操作匹配的intent过滤器
        <action android:name="android.view.InputMethod" />
        
    </intent-filter>
    ***//定义此IME的元数据***
    <meta-data android:name="android.view.im"
               android:resource="@xml/method" />
</service>

控制IME 设置的 Activity

<!-- Optional: an activity for controlling the IME settings -->
<activity android:name="FastInputIMESettings"
    android:label="@string/fast_input_settings">
    <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
    </intent-filter>
</activity>

输入法API

android.inputmethodservice 和 android.view.inputmethod 软件包中提供了 IME
专用的类。KeyEvent 类对于处理键盘字符非常重要。

KeyboardView

用于呈现键盘和响应用户输入事件的 View 的扩展。键盘布局由 Keyboard 的实例指定,可以在 XML 文件中定义该实例

BaseInputConnection

定义从 InputMethod
返回到接收其输入的应用的通信渠道。可以使用该类读取光标周围的文本,将文本提交至文本框,然后将原始按键事件发送到应用。应用应扩展该类,而不是实现基接口
InputConnection。

设计输入法界面:

输入视图

输入视图是指用户以点击按键、手写或手势的形式输入文本的界面。当 IME 首次显示时,系统会调用 onCreateInputView()
回调。

  • onCreateInputView 创建键盘区域视图,返回 layout 布局.

候选试图

候选视图是指 IME 显示可能的字词更正或文字建议供用户选择的界面。在 IME 生命周期中,系统会在准备好显示候选视图时调用
onCreateCandidatesView()。

  • onCreateCandidatesView 创建候选框区域视图,返回 layout 布局.该视图是非必要的,如果不想显示任何内容可以返回Null,事实上,Null的响应是默认行为,该方法可以不实现。

4.编写一个简单的输入法

在AndroidManifest.xml中:

<!-- 输入法服务 -->
<service
    android:name="com.....自定义InputMethodService"
    android:label="@string/app_name"
    android:permission="android.permission.BIND_INPUT_METHOD" >//请求权限绑定输入法,请求 InputMethodService 服务,只有系统才能使用。
    <intent-filter>
        <action android:name="android.view.InputMethod" />
    </intent-filter>
    <meta-data
        android:name="android.view.im"
        android:resource="@xml/method" />
</service>
<!-- 输入法设置界面 -->
<activity android:name="com.....setting.自定义SettingsActivity" >
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
    </intent-filter>
</activity>

method.xml

<input-method xmlns:android="http://schemas.android.com/apk/res/android"
    android:isDefault="true"
    
    android:settingsActivity="com.....setting.自定义SettingsActivity" />
    //输入法设置界面

以下是部分功能的方法

1.光标的左右移动

/**
	 * 输入框的光标向右移动
	 */
	public void setCursorRightMove() {
    
    
		int cursorPos = getSelectionStart();
		cursorPos++;
		getCurrentInputConnection().setSelection(cursorPos, cursorPos);
	}

	/**
	 * 输入框的光标向左移动
	 */
	public void setCursorLeftMove() {
    
    
		int cursorPos = getSelectionStart();
		cursorPos--;
		if (cursorPos < 0)
			cursorPos = 0;
		getCurrentInputConnection().setSelection(cursorPos, cursorPos);
	}

2.文字输入到EditText

	/**
	 * 文字输入到EditText
	 */
public void commitResultText(String resultText) {
    
    
    InputConnection ic = getCurrentInputConnection();
    if (null != ic && !TextUtils.isEmpty(resultText)) {
    
    
	    ic.commitText(resultText, 1);
    }
}

3.输入法显示不占据全屏

	/**
	 * 输入法显示不占据全屏
	 */
@Override
public boolean onEvaluateFullscreenMode() {
    
    
    return false;
}

洪荣键
原文地址:https://blog.csdn.net/m0_56202936/article/details/128056382

猜你喜欢

转载自blog.csdn.net/fjnu_se/article/details/128179769