|
~ To be, or not to be, or to think about it tomorrow. ~ 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 として渡していた部分を |
|