因项目(Android 4.3)需求需要修改默认输入法,本来想的是,这个应该很简单的撒。随google之~,发现网上主要罗列出以下这种方法:
在 frameworksasecore
es
esvaluesconfig.xml 添加一个属性:
<!--leo add-->
<string name="config_default_input_method">com.android.inputmethod.pinyin/.PinyinIME</string>
在frameworksaseservicesjavacomandroidserverInputMethodManagerService.java
的方法buildInputMethodListLocked()里添加:
String defaultIme = Settings.Secure.getString(mContext
.getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);
if ( defaultIme == null )
{
final Resources res = mContext.getResources();
try
{
//frameworksasecore
es
esvaluesconfig.xml
String myIME = res.getString( com.android.internal.R.string.config_default_input_method );
if ( myIME != null && myIME.length() > 0 )
{
Settings.Secure.putString( mContext.getContentResolver(),
Settings.Secure.DEFAULT_INPUT_METHOD,
myIME );
}
}
catch ( Exception e )
{
}
}
但是在自己的源码中修改后,刷机调试发现木有作用,而且这种直接修改源代码是不是不好呢?
后来发现这是4.2的源码,是不是4.3的不一样呢。好吧,木有办法 从源码开始分析吧!(前辈指导,google没有,就看源码)
通过log跟踪,发现系统第一次初始化的时候会调用以下的函数,并且以后的开机中该函数不会在被调用,而下面的函数功能是重置可用的输入法选现(在frameworks/base/core/java/com/android/internal/inputmethod/InputMethodUtils.java 中)
private void resetDefaultImeLocked(Context context) {
// Do not reset the default (current) IME when it is a 3rd-party IME
if (mCurMethodId != null
&& !InputMethodUtils.isSystemIme(mMethodMap.get(mCurMethodId))) {
return;
}
InputMethodInfo defIm = null;
for (InputMethodInfo imi : mMethodList) {
if (defIm == null) {
if (InputMethodUtils.isValidSystemDefaultIme(
mSystemReady, imi, context)) {
defIm = imi;
Slog.i(TAG, "Selected default: " + imi.getId());
}
}
}
if (defIm == null && mMethodList.size() > 0) {
defIm = InputMethodUtils.getMostApplicableDefaultIME(
mSettings.getEnabledInputMethodListLocked());
Slog.i(TAG, "No default found, using " + defIm.getId());
}
注意黄色加粗的部分,当系统暂无默认输入法时,选取适用性最广的输入法(卧草,还带这样的),并调用InputMethodUtils.getMostApplicableDefaultIME函数 ,好吧继续看下面的函数:
public static InputMethodInfo getMostApplicableDefaultIME(
List<InputMethodInfo> enabledImes) {
if (enabledImes != null && enabledImes.size() > 0) {
// We'd prefer to fall back on a system IME, since that is safer.
int i = enabledImes.size();
int firstFoundSystemIme = -1;
while (i > 0) {
i--;
final InputMethodInfo imi = enabledImes.get(i);
if (InputMethodUtils.isSystemImeThatHasEnglishKeyboardSubtype(imi)
&& !imi.isAuxiliaryIme()) {
Return imi;
}
if (firstFoundSystemIme < 0 && InputMethodUtils.isSystemIme(imi)
&& !imi.isAuxiliaryIme()) {
firstFoundSystemIme = i;
}
}
return enabledImes.get(Math.max(firstFoundSystemIme, 0));
同样的请注意黄色地方的代码(红色部分表明是否是一个合法的系统输入法,同时还含有英文亚键盘等特性,普通的输入法无特性,而AOSP键盘却有此特性,系统会直接return 该输入法)。好吧,就你了!既然你这么规定,那我就强制改呗,所以若要修改默认输入,可在此处修改,当系统检测到AOSP键盘时,不直接返回,而是继续检测系统的可用的键盘(当系统第一次启动时,一般只有系统键盘可用,所以应该将所有的输入法设置为可用,修改以下的函数:
public void enableAllIMEsIfThereIsNoEnabledIME() {
if (!TextUtils.isEmpty(getEnabledInputMethodsStr())) {
StringBuilder sb = new StringBuilder();
final int N = mMethodList.size();
for (int i = 0; i < N; i++) {
InputMethodInfo imi = mMethodList.get(i);
Slog.i(TAG, "Adding: " + imi.getId());
if (i > 0) sb.append(':');
sb.append(imi.getId());
}
putEnabledInputMethodsStr(sb.toString());
}
}
判断条件如下:
if (InputMethodUtils.isSystemImeThatHasEnglishKeyboardSubtype(imi)
&& !imi.isAuxiliaryIme()) {
continue;
}
编译系统,烧写,启动可以看到默认的输入法从传统的android自带,变成了你想要输入法。
PS:新手,刚写这种分析流程文章
下一篇 Max Sum