转至元数据结尾
转至元数据起始

做为一个桌面环境,输入法是必不可少的,输入法的切换也应该按照桌面的使用方式,control + shift 或者 control + space 进行切换,OpenFDE又是一个安卓桌面,所以需要对其输入法的切换进行改造,笔者暂时只实现了快捷键切换系统输入法,然而实际上,安卓的输入法与桌面使用方式还有一些不同之处,包括配置,键盘,提示词等等。

首先,从系统角度来认识一下安卓的输入法框架,他包含哪些内容,各模块之间又是什么关系,有了基本认识以后,再对比需求,尝试功能实现方式。

输入法管理服务的整体框架

image-20240218-094053.png

输入法框架包含以下部分:

InputMethodManagerService

输入法系统服务(InputMethodManagerService),简称IMMS,由SystemServer启动,所以也是运行在system_server进程。MultiClientInputMethodManagerService是多会话输入法管理服务,主要应用在多屏设备上,支持每个会话使用不同的输入法功能。

源码位于 frameworks/base/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java

系统输入法的主要逻辑全都在这个类里面实现,包含了输入法的所有管理功能:

com.android.server.inputmethod.InputMethodManagerService#setInputMethodLocked //设置输入法

com.android.server.inputmethod.InputMethodManagerService#switchToNextInputMethod //切换输入法

com.android.server.inputmethod.InputMethodManagerService#showInputMethodMenu //显示输入法菜单

com.android.server.inputmethod.InputMethodManagerService#onShellCommand //响应shell命令

InputMethodService

输入法服务(InputMethodService),简称IMS,三方输入法要继承实现这个类,当你要自己开发一个输入法的时候,就是通过继承这个service,注册到系统,提供其他应用使用,具体可参考官方文档。他是由IMMS启动,启动函数是startInputOrWindowGainedFocus,这个主要由InputMethodManager控制。

源码位于 frameworks/base/core/java/android/inputmethodservice/InputMethodService.java

输入法服务是输入法的具体实现,包含了每个输入法的所有功能:

android.inputmethodservice.InputMethodService#onCreateInputView //输入法键盘view

android.inputmethodservice.InputMethodService#onCreateCandidatesView //提示词view

android.inputmethodservice.InputMethodService#getCurrentInputConnection //处理文本的InputConnection

android.inputmethodservice.InputMethodService#switchInputMethod(java.lang.String, android.view.inputmethod.InputMethodSubtype) //切换输入法,后文会讲解

InputMethodManager

输入法管理器(InputMethodManager),简称IMM,熟悉安卓架构的同学都理解,xxxManager是系统服务暴露给应用端的功能接口,使用系统服务基本功能在这个类里面就可以调用,但是又应该都理解,使用xxxManager限制非常多(也是因为各种hook技术),当你有一个需求的时候他大概率不能满足。APP一般会使用这个类来处理输入法,包含输入法唤起,软键盘,切换弹框等功能:

android.view.inputmethod.InputMethodManager#showInputMethodPicker //输入法切换弹框

android.view.inputmethod.InputMethodManager#showSoftInput(android.view.View, int) //显示软键盘,唤起输入法

对于没有键盘的手机来说,软键盘是必不可少的,showsoftinput就是唤起来输入法,当然安卓也提供了软键盘的控制,怎么显示,显不显示。

以下是显示/隐藏输入法的时序图:

image-20240218-094533.png

以上只是概述了Android输入法的整体框架功能,具体调用逻辑,实现细节可以从源码中再做研究,或者可以参考这个链接

输入法调试方法

输入法的安装会注册service,会由PackageManager管理,使用状态保存在系统数据库settings(现版本已保存在xml),输入法相关的数据保存在存储位置:/data/system/users/0/settings_secure.xml。

enabled_input_methods 已使能输入法
<setting id="1638" name="default_input_method" value="com.android.inputmethod.latin/.LatinIME" package="android" defaultValue="com.android.inputmethod.latin/.LatinIME" defaultSysSet="true" preserve_in_restore="true" />
  
default_input_method  默认输入法
<setting id="1374" name="enabled_input_methods" value="com.android.inputmethod.latin/.LatinIME:com.iflytek.inputmethod/.FlyIME" package="android" defaultValue="com.android.inputmethod.latin/.LatinIME:com.iflytek.inputmethod/.FlyIME" defaultSysSet="true" preserve_in_restore="true" />

enabled_input_methods是在设置里面管理屏幕键盘打开开关,打开之后,才能设置为default_input_method,而default_input_method才是真正使用的输入法。

image-20240218-094632.png

可以通adb命令设置使能输入法和默认输入法;

  • 查询使能的输入法

C:\Users\huyan> adb shell ime list -s
com.android.inputmethod.latin/.LatinIME
all.one.test/.AndroidInputMethodService
com.iflytek.inputmethod/.FlyIME
C:\Users\huyan> adb shell settings get secure enabled_input_methods
com.android.inputmethod.latin/.LatinIME:all.one.test/.AndroidInputMethodService:com.iflytek.inputmethod/.FlyIME

设置默认输入法

adb shell settings put secure default_input_method com.iflytek.inputmethod/.FlyIME

查询默认输入法

C:\Users\huyan> adb shell settings get secure default_input_method
com.iflytek.inputmethod/.FlyIME

这些命令的执行逻辑在上面说到的com.android.server.inputmethod.InputMethodManagerService#onShellCommand,如果在应用进程也是不能直接使用的。