「这是我参与2022首次更文挑战的第1天,活动详情查看:2022首次更文挑战」
故事的起源
有一个医疗系统,类似于餐饮店里的点餐系统,都是把APP作为launcher(安卓系统桌面启动器) 启动。这种系统一般都要求不能跳出APP,并对系统上方的状态栏和下方的导航栏做一个隐藏。毕竟,系统的返回键和home键肯定是不能让用户使用的。
目前遇到了一个问题,5.1及之后的Android系统,其内置的输入法(即预装输入法),不支持中文,而用户需求是需要中文输入的,解决办法:
- 使用第三方输入法
- 自己写个输入法
选择第1条路,使用第三方输入法。在第三方输入法调研中发现,目前市场上的输入法五花八门,功能丰富多彩,总有一个按钮能让使用输入法的用户跳出APP。以google拼音输入法为例,设置-右上角按钮-简介-服务条款,会调起系统浏览器(即跳出APP);设置-字典-编辑自定义短语,进入该页面后无返回键返回APP等。解决办法:
- 使用xposed拦截输入法的intent请求,禁止对方调起浏览器及进入编辑自定义短语界面。
- 选择第2条路,自己写个输入法
这两种办法我都试了下,xposed拦截输入法的intent请求请看这里。
本文只对自定义输入法进行阐述。
知识储备
在开始自定义输入法之前,我们先要明确几个概念。
1.关于Android系统内置输入法
推荐两个很棒的阅读系统源码的网站:
在源码的/packages/inputmethods这个目录下面,我们可以看到android系统的内置输入法。
如下图所示,4.4内置了三套输入法,分别为LatinIME、PinyinIME和OpenWnn。
而自5.1起就只剩下了LatinIME和OpenWnn,放弃了对PinyinIME(中文输入法)的支持。
- OpenWnn是一家日本公司开发的开源输入法框架,涉及中文、日文、韩文。因此你打开一个模拟器时,会发现其中有一个japanese ime的输入法,其服务名为openwnn,这个就是openwnn的日文输入法。
- LatinIME虚拟键盘
- PinyinIMEGoogle 拼音输入法
另外,10.0还内置了Leanback IME输入法,为Google所开发,适用于AndroidTV(AndroidTV和手机的区别是,Android键盘适用于触摸设备,而Android TV则完全不同)
关于AndroidTV输入法支持可以看这里:屏幕键盘 、Android Input
2、关于AOSP
AOSP相关入口
github上的AOSP项目库
在Android系统中查看内置输入法的时候,能看到一个AOSP的字样,那么什么是AOSP输入法呢?
首先我们要明确一个概念。什么是AOSP?
Android 是一个基于 Linux 的、由 Google 主导的开源系统,主要设计用于智能手机和平板电脑等触摸屏移动设备。它于2007年11月推出,并于2008年9月推出了首款商用Android设备。
它是免费的开源软件,它的源代码被称为Android Open Source Project,即我们刚才所提到的AOSP。
也就是说,Android的源代码即AOSP。那么Android源代码中所内置的那些输入法都可以称为AOSP输入法,比如LatinIME、PinyinIME、OpenWnn。
3、关于GMS
这个标题就扯得有点远了,与输入法没有关系,纯粹记录一下。
前文提到,Android的源代码即AOSP,那么像是Google啊华为啊小米啊这些定制的Android操作系统又是怎么回事呢?
是这样的,大多数Android设备除了AOSP,都附带了预安装的其他专有软件,最著名的是Google移动服务(GMS),其中包括核心应用,例如Google Chrome,数字分发平台Google Play和相关的Google Play服务开发平台。
严格意义上来说,Android=AOSP+GMS。 又由于某些原因,国内无法使用 GMS,所以国内的各种定制 ROM 都是 AOSP
的定制修改加上自家的移动服务,比如 MIUI、ColorOS 等。
解决问题:创建输入法
输入法开发有两个部分的工作要做,其一是与操作系统提供的输入法框架集成,其二是把用户的输入字符串转换成输出候选词列表。
public class KeyboardLayout extends LinearLayout {
private KeyboardView mKeyboardView;
private Keyboard mKeyboard;
public KeyboardLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initKeyboard(context, attrs);
}
private void initKeyboard(Context context, AttributeSet attrs){
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.keyboard);
if (a.hasValue(R.styleable.keyboard_xml)) {
//从xml文件中获取键盘布局
int xmlid = a.getResourceId(R.styleable.keyboard_xml,0);
mKeyboard = new Keyboard(context, xmlid);
mKeyboardView = (KeyboardView)LayoutInflater.from(context).inflate(R.layout.keyboardview, null);
//为键盘视图设置自定义的键盘布局
mKeyboardView.setKeyboard(mKeyboard);
mKeyboardView.setEnabled(true);
mKeyboardView.setPreviewEnabled(false);
addView(mKeyboardView);
}
}
}
复制代码