~ To be, or not to be, or to run away far away! ~ null-i.net |
AndroidJava/日本語と英語などで切り替える | |
日本語と他の言語をアプリ内で切り替える(2019-04-07) 今回のこのメモは、 言語の自動切り替え†切替と言っても、翻訳してくれる訳でもなく、 src/res/values/strings.xml あたりに、 <string name="your_string_name">Hello World</string> のようにあらかじめ書いておけば、 String text = getApplicationContext().getString(R.string.your_string_name); のようにtextへ"Hello World" を呼び出せますが、 values/strings.xml に、 your_string_name="Hello World" values-ja/strings.xml に、 your_string_name="はろ〜、わぁるど" を用意しておけば、getString時に自動で選んで読み込んでくれる、と。
自力で直接ファイルを作る場合は、方法の1つとして
ちなみに最初は後者の方法しか知りませんでした。 日本語の判定†アプリ起動時の初期値は Locale.getDefault() で拾えそうです。 日本語、多言語への切り替え(ContextWrapperを使う)†上記の日本語の判定にも絡むのですが、
ことから、
そのため、以前は Locale.setDefault やら Config.setLocale やらで済ました内容が /* * Context を指定の言語で上書きするためのラッパー * Context context = MyContextWrapper.get(context, Locale.JAPANESE); * のように使う。そして、処理を分けたい時は * if(isLocaleJp(context)) * のように日本語とそれ以外に分岐させる。 */ class MyContextWrapper extends ContextWrapper { MyContextWrapper(Context context){ super(context); } static ContextWrapper get(Context context, Locale locale_update){ Lg.d("Locale:" + locale_update); if(locale_update == null){ locale_update = Locale.getDefault(); } Configuration configuration = context.getResources().getConfiguration(); Lg.d("Build.VERSION.SDK_INT:" + Build.VERSION.SDK_INT); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { Lg.d("Build.VERSION_CODES.N"); configuration.setLocale(locale_update); LocaleList localeList = new LocaleList(locale_update); LocaleList.setDefault(localeList); configuration.setLocales(localeList); context = context.createConfigurationContext(configuration); }else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { Lg.d("Build.VERSION_CODES.JELLY_BEAN_MR1"); configuration.setLocale(locale_update); context = context.createConfigurationContext(configuration); }else{ Lg.d("else"); configuration.locale = locale_update; context.getResources().updateConfiguration(configuration, null); } return new MyContextWrapper(context); } static boolean isLocaleJp(Context context){ // 渡された Contextが日本語なら trueを返す Locale locale; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { Lg.d("Build.VERSION_CODES.N"); locale = context.getResources().getConfiguration().getLocales().get(0); }else { Lg.d("Build.VERSION_CODES.JELLY_BEAN_MR1"); locale = context.getResources().getConfiguration().locale; } return (locale.equals(Locale.JAPAN) || locale.equals(Locale.JAPANESE)); } } 以上のような例をふまえて、 @Override protected void attachBaseContext(Context context){ super.attachBaseContext(MyContextWrapper.get(context, Locale.JAPANESE)); } 私は(上のようにattachBaseContext を Overrideせずに) 余談:ContextWrapperの置き換え後の注意†というより、ContextとActivityを「混ぜて」使っていた場合の注意です。 new AlertDialog.Builder(context) この引数の contextは、私は Activity自身を(thisで)渡していたのですが、 Exception:android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application AlerDialog.Builderで指定する引数は「the parent context」だとAPIリファレンスにも書いてあって、 Context-ContextWrapper-ContextThemeWrapper-Activity Context-ContextWrapper-ContextThemeWrapper-Service クラスの継承順で言えば上記なので、言語対応後のWrapperを渡しても いままで Activity や Service として渡していた部分を |
|