做为一个桌面环境,输入法是必不可少的,输入法的切换也应该按照桌面的使用方式,control + shift 或者 control + space 进行切换,OpenFDE又是一个安卓桌面,所以需要对其输入法的切换进行改造,笔者暂时只实现了快捷键切换系统输入法,然而实际上,安卓的输入法与桌面使用方式还有一些不同之处,包括配置,键盘,提示词等等。
首先,从系统角度来认识一下安卓的输入法框架,他包含哪些内容,各模块之间又是什么关系,有了基本认识以后,再对比需求,尝试功能实现方式。
输入法管理服务的整体框架
输入法框架包含以下部分:
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就是唤起来输入法,当然安卓也提供了软键盘的控制,怎么显示,显不显示。
以下是显示/隐藏输入法的时序图:
以上只是概述了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才是真正使用的输入法。
可以通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,如果在应用进程也是不能直接使用的。
添加评论