Android:如何在不更改当前语言环境的情况下获取特定语言环境中的字符串

标签 android localization locale android-resources

用例:记录显示给用户的错误消息。

但是,您不希望日志中的消息取决于用户设备的区域设置。 另一方面,您不想仅仅为了您的(技术)日志记录而更改用户设备的区域设置。 这可以实现吗? 我在 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;
}

说实话,我一点也不喜欢这种方法。它效率不高,而且 - 考虑并发性和所有这些 - 它可能会导致“错误”语言环境中的某些 View 。

那么 - 有什么想法吗?也许这可以使用 ResourceBundle 来实现s,就像在标准 Java 中一样?

最佳答案

您可以将其用于 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);
}

更新(一):如何支持旧版本。

@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): Check this article

关于Android:如何在不更改当前语言环境的情况下获取特定语言环境中的字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17771531/

相关文章:

android - 如果屏幕上没有水平空间,请转到下一个垂直可用空间?

c# - Microsoft Sans Serif 字体未在中文本地化 Windows 中使用

java - 在 java.time 中从 `DateTimeFormatter.ofLocalized…` 生成的本地化字符串中强制使用 4 位数年份

android - 将经纬度从数据库保存到 GPX 文件.Android

android - 是否可以从Google Play商店或 “symlink”中检索使用faSTLane生成的发行说明,以便可以在应用程序中显示它?

c# - ASP.NET - 转换本地化数字

java - 使用指定的语言环境 (sv) 和 NumberFormat 将 String 解析为 Long

java - 根据动态货币值动态更改区域设置

javascript - 如何根据用户区域设置格式化数字和日期?

java - Chronometer 初始值错误