您的位置:首页 > 移动开发 > Android开发

Android 4.3 源码下如何修改默认输入法

2014-09-26 16:07 417 查看
因项目(Android 4.3)需求需要修改默认输入法,本来想的是,这个应该很简单的撒。随google之~,发现网上主要罗列出以下这种方法:

在 frameworks\base\core\res\res\values\config.xml 添加一个属性:

   <!--leo add-->

   <string name="config_default_input_method">com.android.inputmethod.pinyin/.PinyinIME</string>

  在frameworks\base\services\java\com\android\server\InputMethodManagerService.java

   的方法buildInputMethodListLocked()里添加:

  String defaultIme = Settings.Secure.getString(mContext

   .getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);

   if ( defaultIme == null )

   {

   final Resources res = mContext.getResources();

   try

   {

   //frameworks\base\core\res\res\values\config.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());

   }

   }

把所有的输入法设置为可用的。则再上一个函数中就可以找你想要的输入法了,那么在上一个函数加一个判断条件,判断循环的输入法是否为你想要默认的输入法,是的话就设置:

  firstFoundSystemIme = i;

  判断条件如下:

if (InputMethodUtils.isSystemImeThatHasEnglishKeyboardSubtype(imi)

   && !imi.isAuxiliaryIme()) {

continue;

   }

for(int m = 0; m < enabledImes.size(); m ++){

   if(enabledImes.get(m).getId()== "你想要设置的输入法包名")

   firstFoundSystemIme = m;

   }

  

  此处可修改为其他的输入法。

  

  编译系统,烧写,启动可以看到默认的输入法从传统的android自带,变成了你想要输入法。

PS:新手,刚写这种分析流程文章
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: