使用例:ユーザーに表示されるエラーメッセージのロギング。
ただし、ユーザーのデバイスのロケールに依存するメッセージをログに残したくない場合があります。一方、(技術的な)ログ記録のためだけにユーザーのデバイスのロケールを変更する必要はありません。これは達成できますか?私はここでstackoverflowでいくつかの潜在的な解決策を見つけました:
ただし、これらの結果、デバイスのロケールが変更されます(次の構成が変更されるまで)。
とにかく、私の現在の回避策はそうです:
public String getStringInDefaultLocale(int resId) {
Resources currentResources = getResources();
AssetManager assets = currentResources.getAssets();
DisplayMetrics metrics = currentResources.getDisplayMetrics();
Configuration config = new Configuration(
currentResources.getConfiguration());
config.locale = DEFAULT_LOCALE;
/*
* Note: This (temporiarily) changes the devices locale! TODO find a
* better way to get the string in the specific locale
*/
Resources defaultLocaleResources = new Resources(assets, metrics,
config);
String string = defaultLocaleResources.getString(resId);
// Restore device-specific locale
new Resources(assets, metrics, currentResources.getConfiguration());
return string;
}
正直なところ、私はこのアプローチがまったく好きではありません。これは効率的ではなく、同時実行性などについて考えると、「間違った」ロケールで何らかのビューが表示される可能性があります。
だから-アイデアは?たぶんこれは、標準のJavaのように、 ResourceBundle sを使用して実現できますか?
これはAPI +17
に使用できます
@NonNull
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
public static String getStringByLocal(Activity context, int id, String locale) {
Configuration configuration = new Configuration(context.getResources().getConfiguration());
configuration.setLocale(new Locale(locale));
return context.createConfigurationContext(configuration).getResources().getString(id);
}
更新(1):古いバージョンをサポートする方法。
@NonNull
public static String getStringByLocal(Activity context, int resId, String locale) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1)
return getStringByLocalPlus17(context, resId, locale);
else
return getStringByLocalBefore17(context, resId, locale);
}
@NonNull
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
private static String getStringByLocalPlus17(Activity context, int resId, String locale) {
Configuration configuration = new Configuration(context.getResources().getConfiguration());
configuration.setLocale(new Locale(locale));
return context.createConfigurationContext(configuration).getResources().getString(resId);
}
private static String getStringByLocalBefore17(Context context,int resId, String language) {
Resources currentResources = context.getResources();
AssetManager assets = currentResources.getAssets();
DisplayMetrics metrics = currentResources.getDisplayMetrics();
Configuration config = new Configuration(currentResources.getConfiguration());
Locale locale = new Locale(language);
Locale.setDefault(locale);
config.locale = locale;
/*
* Note: This (temporarily) changes the devices locale! TODO find a
* better way to get the string in the specific locale
*/
Resources defaultLocaleResources = new Resources(assets, metrics, config);
String string = defaultLocaleResources.getString(resId);
// Restore device-specific locale
new Resources(assets, metrics, currentResources.getConfiguration());
return string;
}
更新(2):この記事を確認
アプリの起動時に実行されるMap
のように、グローバルクラス内のApplication
にデフォルトロケールのすべての文字列を保存できます。
public class DualLocaleApplication extends Application {
private static Map<Integer, String> defaultLocaleString;
public void onCreate() {
super.onCreate();
Resources currentResources = getResources();
AssetManager assets = currentResources.getAssets();
DisplayMetrics metrics = currentResources.getDisplayMetrics();
Configuration config = new Configuration(
currentResources.getConfiguration());
config.locale = Locale.ENGLISH;
new Resources(assets, metrics, config);
defaultLocaleString = new HashMap<Integer, String>();
Class<?> stringResources = R.string.class;
for (Field field : stringResources.getFields()) {
String packageName = getPackageName();
int resId = getResources().getIdentifier(field.getName(), "string", packageName);
defaultLocaleString.put(resId, getString(resId));
}
// Restore device-specific locale
new Resources(assets, metrics, currentResources.getConfiguration());
}
public static String getStringInDefaultLocale(int resId) {
return defaultLocaleString.get(resId);
}
}
このソリューションは最適ではありませんが、同時実行性の問題は発生しません。
API +17の場合、これを使用できます。
public static String getDefaultString(Context context, @StringRes int stringId){
Resources resources = context.getResources();
Configuration configuration = new Configuration(resources.getConfiguration());
Locale defaultLocale = new Locale("en");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
LocaleList localeList = new LocaleList(defaultLocale);
configuration.setLocales(localeList);
return context.createConfigurationContext(configuration).getString(stringId);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1){
configuration.setLocale(defaultLocale);
return context.createConfigurationContext(configuration).getString(stringId);
}
return context.getString(stringId);
}