Android默认输入法语言的修改以及SettingsProvider作用


Android源码中默认的有三种输入法:英文,中文,日文。对应的工程代码路径为:
<android_root>/packages/inputmethods/LatinIME/
<android_root>/packages/inputmethods/OpenWnn/
<android_root>/packages/inputmethods/PinyinIME/

一般情况下,默认都是选择的LatinIME输入法,但是Android系统默认都是选择系统语言作为输入法,比如我们要用中文输入法,
就需要切换系统语言为中文,或不勾选系统语言,主动勾选中文,但是我们怎么修改默认的语言输入法呢?
主要要关注3个模块代码:
(1) Setting源码
(2) SettingsProvider源码
(3) LatinIME输入法源码

方法一:(修改默认输入法语言为英文和泰文,亲测ok)
(1) 修改 packages\inputmethods\LatinIME\java\AndroidManifest.xml,增加

复制代码
 <uses-permission android:name="android.permission.WRITE_SETTINGS" />
 <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
 <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
 
 <receiver android:name="LatinImeReceiver" android:enabled="true">
  <intent-filter>
   <action android:name="android.intent.action.BOOT_COMPLETED" />
   </intent-filter>
 </receiver>
复制代码

 


(2) 在packages\inputmethods\LatinIME\java\src\com\android\inputmethod\latin目录增加LatinImeReceiver.java文件,源码如下

复制代码
package com.android.inputmethod.latin;
  
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.provider.Settings;
import android.util.Log;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodManager;
import android.view.inputmethod.InputMethodSubtype;
import android.text.TextUtils;
import android.content.SharedPreferences.Editor; 
import android.preference.PreferenceManager; 

public class LatinImeReceiver extends BroadcastReceiver {
    private static final String TAG = LatinImeReceiver.class.getSimpleName();
    
    private static final String[] DEFAULT_LATIN_IME_LANGUAGES = {"en_US","th"};//默认开启输入法的语言
    
    @Override
    public void onReceive(Context context, Intent intent) {
    // Set the default input language at the system boot completed.
        
        if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
            Log.i(TAG,"onReceive:ACTION_BOOT_COMPLETED");
            SharedPreferences sp = context.getSharedPreferences("default_input_language_config", Context.MODE_PRIVATE);
            boolean hasSet = sp.getBoolean("has_set", false);
         
            if (!hasSet) {
                setDefaultSubtypes(context);
                sp.edit().putBoolean("has_set", true).commit();
            }
        }
    }
     
    /**
    * M: Set the default IME subtype.
    */
      
    private void setDefaultSubtypes(Context context) {  
        Log.i(TAG,"setDefaultSubtypes");
        final String serviceName = "com.android.inputmethod.latin/.LatinIME";
        final String currentPackageName = "com.android.inputmethod.latin";
        final String enable = Settings.Secure.getString(context.getContentResolver(), 
                                                    Settings.Secure.ENABLED_INPUT_METHODS);
        Log.i(TAG,"enable="+enable);//com.android.inputmethod.latin/.LatinIME
        
        final InputMethodManager imm = (InputMethodManager) context.getSystemService( Context.INPUT_METHOD_SERVICE);
        final StringBuilder builder = new StringBuilder();
             
        // Get sub type hash code
        for (InputMethodInfo info : imm.getInputMethodList()) {
            if (currentPackageName.equals(info.getPackageName())) {
                Log.i(TAG,"info.getSubtypeCount()="+info.getSubtypeCount());//55
                for (int i = 0; i < info.getSubtypeCount(); i++) {  
                    final InputMethodSubtype subtype = info.getSubtypeAt(i); 
                    final String locale = subtype.getLocale().toString();
                    Log.i(TAG,"locale="+locale);
                    if (isDefaultLocale(locale)) {
                        Log.i(TAG, "default enabled subtype locale = " + locale);
                        builder.append(';');
                        builder.append(subtype.hashCode());
                    }
                }
                break;
            }
        }
      
        // Insert the sub type 
        if (builder.length() > 0 && !TextUtils.isEmpty(enable)) {
            final String subtype = builder.toString();     
            builder.setLength(0);      
            final int index = enable.indexOf(serviceName) + serviceName.length();    
            
            if (enable.length() > index) {      
                builder.append(enable.substring(0, index));     
                builder.append(subtype);      
                builder.append(enable.substring(index));     
            } else if (enable.length() == index) {     
                builder.append(enable);     
                builder.append(subtype);     
            } else {     
                return;     
            }
        } 
        else {  
            Log.w(TAG, "Build Latin IME subtype failed: " + " builder length = " + builder.length()     + 
                    "; enable isEmpty :" + TextUtils.isEmpty(enable));     
            return;     
        }
          
        
        /*android/packages/inputmethods/LatinIME/java/res/xml/method.xml
            -921088104;529847764分别代表en_US和th
        */
        Log.i(TAG,"commoit:"+builder.toString());//com.android.inputmethod.latin/.LatinIME;-921088104;529847764
        
        // Commit the result  
        android.provider.Settings.Secure.putString(context.getContentResolver(),  
                                android.provider.Settings.Secure.ENABLED_INPUT_METHODS, builder.toString()); 
        String lastInputMethodId = Settings.Secure.getString(context.getContentResolver(), 
                                                    Settings.Secure.DEFAULT_INPUT_METHOD); 
        Log.w(TAG, "DEFAULT_INPUT_METHOD = " + lastInputMethodId); //com.android.inputmethod.latin/.LatinIME
        
        if(lastInputMethodId.equals(serviceName)) {  
            Log.w(TAG, "DEFAULT_INPUT_METHOD = com.android.inputmethod.latin/.LatinIME" );
            
            for (InputMethodInfo info : imm.getInputMethodList()) {
                if (currentPackageName.equals(info.getPackageName())) {
                    for (int i = 0; i < info.getSubtypeCount(); i++) { 
                        final InputMethodSubtype subtype = info.getSubtypeAt(i);
                        final String[] locales = DEFAULT_LATIN_IME_LANGUAGES;
                        Log.w(TAG, "i = " + i + ", locales[0] = " + locales[0]);
                        if((subtype.getLocale()).equals(locales[0])) {
                            Log.w(TAG, "putString " + subtype.hashCode());
                            android.provider.Settings.Secure.putInt(context.getContentResolver(),  
                                android.provider.Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE, subtype.hashCode());
                        } 
                    }  
                }
            }
        }
    }
         
    /**  
    * M: Check if the current locale is default or not. 
    */  
    private boolean isDefaultLocale (String locale) { 
        final String[] locales = DEFAULT_LATIN_IME_LANGUAGES;
         
        for (String s : locales) {
            if (s.equals(locale)) {
                return true;
            }
        }
        
        return false; 
    }
         
}
  
复制代码

 


方法二:
还有一种修改方案:(在amlogic验证是OK的)
(1) 首先frameworks\base\packages\SettingsProvider\res\values\defaults.xml 增加下面语句
<string name="def_input_methods">com.android.inputmethod.latin/.LatinIME;529847764;-921088104</string>

意思是增加英文和泰文输入法,android/packages/inputmethods/LatinIME/java/res/xml/method.xml中有定义的
-921088104;529847764分别代表en_US和th

(2) 然后在frameworks\base\packages\SettingsProvider\src\com\android\providers\settings\DatabaseHelper.java
增加如下代码
loadStringSetting(stmt, Settings.Secure.ENABLED_INPUT_METHODS, R.string.def_input_methods);


frameworks/base/packages/SettingsProvider的作用
我们在调用android.provider.Settings修改一些设置时,Settings会调用真正的SettingsProvider去访问数据库。
android把SettingsProvider的代码放在了frameworks/base/packages下面。

Android framework系统默认设置修改
修改Settings源码可修改系统设置项,Settings数据被存放于com.android.providers.settings/databases/settings.db 中,如果想修改系统启动后加载的默认值,一种方法是直接修改settings.db的值,另一种就是修改SettingsProvider默认值
Settings应用能够配置Android系统的各种设置,这些设置的默认值都是由frameworks中的SettingsProvider从数据库中读取的,
那么第一次开机的时候这些数据都是从哪儿来的呢?
frameworks/base/packages/SettingsProvider/res/values/defaults.xml这个文件就是用来存储Android系统的默认设置
如果想定义defaults.xml中没有的,在这里添加后,需修改frameworks/base/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java,加入自己的存储代码。
例如:
600000设置关屏超时时间的默认值
102 设置亮度的默认值
false设置是否允许安装非Market应用程序的默认值


参考:
Android的语言设置(一) 
http://blog.youkuaiyun.com/seker_xinjian/article/details/6288957

Latin输入法怎么默认勾选几种语言
http://wenku.baidu.com/link?url=gAscqnKoMNOi_wzR3LEsk9kw-Hsp6k-hkWsW3_Jvyz3SmMXkENODD6XjRtS9BrndAS4iY2IuM8nQaxj05J4NUmBFdFE5-7nl9P9bVIwqfCm

Android framework系统默认设置修改
http://blog.youkuaiyun.com/tiantian715/article/details/7739294

在android settings.db数据库中添加一项新的设置 
http://www.2cto.com/kf/201303/198067.html

<think>嗯,用户现在想通过ADB命令修改Android系统的默认输入法。之前他们询问过如何查看当前输入法,现在需要进一步的操作步骤。我需要参考之前的回答和用户提供的引用内容来给出正确的指导。 首先,用户提到了引用[1]和[2],其中引用[1]说明了如何获取当前的默认输入法和已启用的输入法列表,而引用[2]给出了修改默认输入法的ADB命令示例。根据这些信息,我需要整理出一个步骤清晰的流程,确保用户能够正确执行命令。 在之前的对话中,用户已经学会了如何查看当前输入法,所以现在需要教他们如何修改修改默认输入法通常需要先启用目标输入法,然后设置其为默认。关键点在于获取正确的输入法ID,并确保输入法已经被启用。如果用户直接设置未启用的输入法,可能会失败,所以步骤中必须包括启用输入法的部分。 另外,用户可能需要处理一些特殊情况,比如输入法服务未启用或者权限问题。这里需要提醒用户检查是否已经正确安装并启用了目标输入法,否则设置默认会失败。此外,有些设备可能需要root权限,特别是当修改系统安全设置时,可能需要使用adb shell pm grant来授予权限,如引用中提到的android.permission.WRITE_SECURE_SETTINGS。 还要注意命令的正确格式,比如在设置enabled_input_methods时,输入法ID需要用冒号分隔,并且不能有空格。如果用户的值不正确,可能会导致设置失败。示例中的引用[2]显示了enabled_input_methods的值是多个输入法ID用冒号连接,所以需要确保用户理解这一点。 另外,用户可能需要验证修改是否成功,所以需要包括验证步骤,再次运行获取默认输入法的命令来确认。同时,提醒用户注意设备兼容性和系统权限的问题,比如某些厂商可能限制ADB修改系统设置,这时候可能需要额外的步骤或者解锁权限。 总结下来,步骤应该是:获取当前输入法列表,启用目标输入法,设置默认输入法,验证结果。同时,处理可能出现的错误情况和注意事项,比如输入法ID的正确性、权限问题、设备兼容性等。确保用户能够按照步骤操作,并在遇到问题时知道如何排查。</think>根据引用[1][2]提供的ADB操作方法,通过命令修改Android系统默认输入法需遵循以下步骤: ### 一、核心操作流程 1. **获取目标输入法完整ID** ```bash adb shell ime list -a | grep "mId=" ``` $$ \text{输入法ID格式} = \text{包名/服务类名} $$ 示例输出(如引用[2]): ```text mId=com.android.inputmethod.latin/.LatinIME mId=com.sohu.inputmethod.sogou/.SogouIME ``` 2. **强制启用目标输入法** ```bash adb shell settings put secure enabled_input_methods "原启用列表:新输入法ID" ``` 示例(参考引用[2]拉丁输入法): ```bash adb shell settings put secure enabled_input_methods "com.android.inputmethod.latin/.LatinIME:com.new.inputmethod/.IME" ``` 3. **设置默认输入法**(关键步骤) $$ \text{default_input_method} = \text{目标输入法ID} $$ ```bash adb shell settings put secure default_input_method "com.new.inputmethod/.IME" ``` ### 二、验证命令有效性 ```bash # 验证是否生效 adb shell settings get secure default_input_method adb shell dumpsys input_method | grep "mCurMethodId" ``` ### 三、特殊场景处理 | 场景 | 解决方案 | 关联引用 | |------|----------|----------| | 输入法未启用 | 需先通过`enabled_input_methods`添加ID | [^1] | | 权限不足 | 执行`adb shell pm grant 包名 android.permission.WRITE_SECURE_SETTINGS` | [^2] | | 系统限制 | 部分厂商ROM需关闭输入法签名验证 | [^1] | ### 四、操作示意图 $$ \begin{array}{ccc} \text{获取输入法列表} & \xrightarrow{\text{ime list -a}} & \text{筛选目标ID} \\ \downarrow & & \downarrow \\ \text{更新启用列表} & \xleftarrow{\text{settings put}} & \text{设置默认值} \end{array} $$ ### 五、典型错误示例 ```bash # 错误:直接设置未启用的输入法 adb shell settings put secure default_input_method "uninstalled.ime/.Service" # 输出:写入成功但实际无效(需先执行enabled_input_methods) ``` ### 六、注意事项 1. 输入法ID需严格匹配`包名/类名`格式 2. 修改后建议重启输入法进程: ```bash adb shell ime set com.new.inputmethod/.IME ``` 3. 华为/小米等设备可能需要额外系统权限 --相关问题-- 1. 如何通过ADB禁用Android设备的特定输入法? 2. 输入法服务显示`Not started`时如何强制启动? 3. 安卓系统级输入法开发需要哪些特殊权限?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值