以编程方式更改语言(Android N 7.0 - API 24)

2023-11-21

我使用以下代码在我的应用程序中设置特定语言。语言保存到SharedPreferences在应用程序内。它可以完美地工作到 API 级别 23。使用 Android NSharedPreferences效果也很好,它返回正确的语言代码字符串,但它不会更改区域设置(设置手机的默认语言)。可能出什么问题了?

更新1:当我使用Log.v("MyLog", config.locale.toString());之后立马res.updateConfiguration(config, dm)它返回正确的区域设置,但应用程序的语言没有更改。

更新2:我还提到,如果我更改区域设置然后重新启动活动(使用新意图并完成旧意图),它会正确更改语言,甚至在旋转后显示正确的语言。但是当我关闭应用程序并再次打开它时,我会得到默认语言。有点奇怪。

public class ActivityMain extends AppCompatActivity {

    //...
    @Override
    protected void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState);
        // Set locale
        SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);
        String lang = pref.getString(ActivityMain.LANGUAGE_SAVED, "no_language");
        if (!lang.equals("no_language")) {
            Resources res = context.getResources();
            Locale locale = new Locale(lang);
            Locale.setDefault(locale);
            DisplayMetrics dm = res.getDisplayMetrics();
            Configuration config = res.getConfiguration();
            if (Build.VERSION.SDK_INT >= 17) {
                config.setLocale(locale);
            } else {
                config.locale = locale;
            }
        }
        res.updateConfiguration(config, dm);

        setContentView(R.layout.activity_main);
        //...
    } 
    //... 
}

更新3: 答案也在这里: https://stackoverflow.com/a/40849142/3935063


创建一个新类扩展 ContextWrapper

public class MyContextWrapper extends ContextWrapper {
    public MyContextWrapper(Context base) {
        super(base);
    }

    @TargetApi(Build.VERSION_CODES.N)
    public static ContextWrapper wrap(Context context, Locale newLocale) {
        Resources res = context.getResources();
        Configuration configuration = res.getConfiguration();

        if (VersionUtils.isAfter24()) {
            configuration.setLocale(newLocale);

            LocaleList localeList = new LocaleList(newLocale);
            LocaleList.setDefault(localeList);
            configuration.setLocales(localeList);

            context = context.createConfigurationContext(configuration);

        } else if (VersionUtils.isAfter17()) {
            configuration.setLocale(newLocale);
            context = context.createConfigurationContext(configuration);

        } else {
            configuration.locale = newLocale;
            res.updateConfiguration(configuration, res.getDisplayMetrics());
        }

        return new ContextWrapper(context);
    }
}

重写 Activity 的 AttachBaseContext 方法

@Override
protected void attachBaseContext(Context newBase) {
    Locale languageType = LanguageUtil.getLanguageType(mContext);
    super.attachBaseContext(MyContextWrapper.wrap(newBase, languageType));
}

完成活动并重新开始,新的区域设置将生效。

demo:https://github.com/fanturbo/MultiLanguageDemo

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

以编程方式更改语言(Android N 7.0 - API 24) 的相关文章

随机推荐