• 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) 修改 packagesinputmethodsLatinIMEjavaAndroidManifest.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) 在packagesinputmethodsLatinIMEjavasrccomandroidinputmethodlatin目录增加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) 首先frameworksasepackagesSettingsProvider esvaluesdefaults.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) 然后在frameworksasepackagesSettingsProvidersrccomandroidproviderssettingsDatabaseHelper.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.csdn.net/seker_xinjian/article/details/6288957

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

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

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

  • 相关阅读:
    j2ee学习笔记
    go开发和运行环境的配置
    Java基础学习笔记
    经典C/S服务器模型之守护进程
    linux抓包命令-tcpdump命令详解
    PostgreSQL的HA解决方案-2负载均衡(load balance)
    PostgreSQL的HA解决方案-1主从和备份(master/slave and backup)
    PostgreSQL的HA解决方案-项目概述
    将数据写到kafka的topic
    将sparkStreaming结果保存到Redshift数据库
  • 原文地址:https://www.cnblogs.com/lijunamneg/p/3839779.html
Copyright © 2020-2023  润新知