Android 2.3でファームビルド時にデフォルトのキーボードを変更する

4系では使えないと思うけどメモ。
最悪、ROMのマスタ作る前に、データベースを直接書き換えておけばいいんだけど、マスタアップがある度にそれを忘れる可能性もあるし、何より美しくないので、きれいにやりたい。

imeコマンドで起動時に変更する

init.[device].shとかに仕込んでみたけど、起動時には、タイミングが早すぎてどうも反映しない。
起動して、しばらくしてからやると大丈夫なんだけど。
Settingプロバイダとか、ImeManagerが動いてないとダメなのかも。

# ime enable jp.mydata.softkeyboard/.SoftKeyboard
# ime set jp.mydata.softkeyboard/.SoftKeyboard

ime list -sとかime list -aとかime listとかで、状態は確認できるのだけど、デフォルトになっているかどうかは確認手段がなさそう。

settings.dbを直接書き換える

secureなdb扱いの領域にあるので、root権限が必要。
確認。

# sqlite3 /data/data/com.android.providers.settings/databases/settings.db
SQLite version 3.6.22
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> .tables
android_metadata   bookmarks          system
bluetooth_devices  secure
sqlite> .dump secure
(snip)
INSERT INTO "secure" VALUES(40,'disabled_system_input_methods','');
INSERT INTO "secure" VALUES(41,'default_input_method','jp.mydata.softkeyboard/.SoftKeyboard');
INSERT INTO "secure" VALUES(43,'enabled_input_methods','jp.mydata.softkeyboard/.SoftKeyboard');
(snip)
sqlite> .quit

設定済みの例。
関連する項目はこれくらいかな。
enabled_input_methods以外は、項目がない場合もある。
コマンド一発で書き換える。正確には2発だけど。

/system/xbin/sqlite3 /udata/data/data/com.android.providers.settings/databases/settings.db "update secure set value = 'jp.mydata.softkeyboard/.SoftKeyboard' where name = 'enabled_input_methods';"
/system/xbin/sqlite3 /udata/data/data/com.android.providers.settings/databases/settings.db "update secure set value = 'jp.mydata.softkeyboard/.SoftKeyboard' where name = 'default_input_method';"

これも、init.[device].shとかに仕込んでみたけど、これもタイミングが早すぎるのか、どうも反映しない場合がある。
起動して、しばらくしてからやると大丈夫なんだけど。

しょうがないので、フレームワークに手を入れる - DatabaseHelper.javaに割り込む案

ぐぐると、中華圏の人の苦労した成果が2パターン出てくる。
frameworks/base/packages/SettingsProvider/res/values/defaults.xmlに設定を追記。

    <string name="config_default_input_method" translatable="false">jp.mydata.softkeyboard/.SoftKeyboard</string>

XMLからdbに設定を反映するframeworks/base/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.javaにコードを追記。

            loadStringSetting(stmt, Settings.Secure.DEFAULT_INPUT_METHOD,
                    R.string.config_default_input_method);

これだけだと、出来上がっているapkを追加しても、apkをソースからビルドするようにしても、デフォルトのIMEとして自動で認識してくる場合と、そうでない場合があるようだ。
そこまでの切り分けはできていない。


dbを見ても、enabled_input_methodsに入ってないケースがある。

# sqlite3 /data/data/com.android.providers.settings/databases/settings.db
sqlite> .dump secure
(snip)
INSERT INTO "secure" VALUES(3,'default_input_method','jp.mydata.softkeyboard/.SoftKeyboard');
INSERT INTO "secure" VALUES(22,'enabled_input_methods','com.android.inputmethod.latin/.LatinIME');

もちろん、imeコマンドでも出てこない。


enabled_input_methodsを同様に追記してやると、期待通りに動作するようになった。
XMLに追記。

<string name="def_enabled_input_methods">jp.mydata.softkeyboard/.SoftKeyboard</string> 

DatabaseHelper.javaに追記。

loadStringSetting (stmt, Settings.Secure.ENABLED_INPUT_METHODS, 
R.string.def_enabled_input_methods);

順序的には、enableする前にやったほうがいいかな。たぶん関係ないけど。

しょうがないので、フレームワークに手を入れる - InputMethodManagerService.javaに割り込む案

こちらは、あんまりきれいじゃないので試していない。
enabled_input_methodsしてないのでダメかも。上と同様にやればいいのだとは思う。
frameworks/base/core/res/res/values/config.xml にデフォルト設定を追記する。

<string name="config_default_input_method">jp.mydata.softkeyboard/.SoftKeyboard</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
        {
            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 )
        {
        }
    }