Talking about Android Input Method (IME) Architecture

Introduction:

An input method (IME) is a user control that enables a user to enter text. Android
provides an extensible input method framework. With this framework, apps can provide users with alternative input methods, such as an on-screen keyboard or even voice input. After installing the desired IME
, the user can select the IME to use from the system settings and use that IME throughout the system; only one IME can be enabled at a time.
How to develop a simple input method, you must first understand the input method framework IMF that comes with Android

1. IME life cycle:


The essence of the input method is a Service. Assuming that the user has just started an APP, when the focus enters the text edit box for the first time, Android will notify the Service to start initialization, as shown in the life cycle diagram:

  • First execute the onCreate method, which does some initialization of the string variable separator.

  • Secondly, execute the onCreateInputView method. When displaying the area input by the user, the Android framework will call this method. This method initializes the inputview, reads the layout file information, sets the onKeyboardActionListener, and initially sets the keyboard.

  • Then execute the onCreateCandidatesView method, which is called by the framework when the view of some candidate words is to be displayed, similar to the onCreateInputView method above, where the candidate view is initialized.

  • Finally, execute the onStartInputView method to re-associate the inputview with the current keyboard.

2. Architecture diagram of Android input method:

insert image description here
The meaning of some terms in the figure is explained:

  • IMMS: input method management service InputMethodManagerService
  • IMM: input method management InputMethodManager
  • IMS: Input Method Service InputMethodService

3. Some components in the framework use

In the Android system, an IME is an Android application that includes 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 defining the IME characteristics.

BIND_MIDI_DEVICE_SERVICE permission
insert image description here

The following code snippet declares an IME service:

<!-- 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>

Activity that controls IME settings

<!-- 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>

input method API


IME- specific classes are provided in the android.inputmethodservice and android.view.inputmethod packages . The KeyEvent class is very important for handling keyboard characters.

KeyboardView

An extension to View for rendering the keyboard and responding to user input events. The keyboard layout is specified by an instance of Keyboard, which can be defined in an XML file

BaseInputConnection

Defines the communication channel from the InputMethod
back to the application that received its input. You can use this class to read the text around the cursor, submit the text to a textbox, and then send raw keypress events to your application. Applications should extend this class instead of implementing the base interface
InputConnection.

Design input method interface:

input view

An input view is an interface where the user enters text in the form of keystrokes, handwriting, or gestures. When the IME is first displayed, the system calls the onCreateInputView()
callback.

  • onCreateInputView creates the keyboard area view and returns the layout layout.

Candidate attempt

Candidate view is the interface where the IME displays possible word corrections or text suggestions for the user to choose from. During the IME lifecycle, the system calls
onCreateCandidatesView() when the candidate views are ready to be displayed.

  • onCreateCandidatesView creates a view of the candidate frame area and returns the layout layout. This view is not necessary. If you do not want to display any content, you can return Null. In fact, the response of Null is the default behavior, and this method does not need to be implemented.

4. Write a simple input method

In 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" />
    //输入法设置界面

Here's how some of the functions work

1. Move the cursor left and right

/**
	 * 输入框的光标向右移动
	 */
	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. Text input to EditText

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

3. The input method display does not occupy the full screen

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

Hong Rongjian
Original address: https://blog.csdn.net/m0_56202936/article/details/128056382

Guess you like

Origin blog.csdn.net/fjnu_se/article/details/128179769