为了账号安全,请及时绑定邮箱和手机立即绑定

Android N以编程方式更改语言

Android N以编程方式更改语言

翻过高山走不出你 2019-10-25 10:16:48
我发现了只在Android N设备上才能复制的真正奇怪的错误。在浏览我的应用程序时,可以更改语言。这是更改它的代码。 public void update(Locale locale) {    Locale.setDefault(locale);    Configuration configuration = res.getConfiguration();    if (BuildUtils.isAtLeast24Api()) {        LocaleList localeList = new LocaleList(locale);        LocaleList.setDefault(localeList);        configuration.setLocales(localeList);        configuration.setLocale(locale);    } else if (BuildUtils.isAtLeast17Api()){        configuration.setLocale(locale);    } else {        configuration.locale = locale;    }    res.updateConfiguration(configuration, res.getDisplayMetrics());}该代码在我的巡回活动(带recreate()电话)中效果很好,但是在接下来的所有活动中,所有String资源都是错误的。屏幕旋转将其修复。我该怎么办?我应该以其他方式更改Android N的语言环境还是仅仅是系统错误?PS这是我发现的。第一次启动MainActivity时(在我的旅行之后)Locale.getDefault()是正确的,但是资源错误。但是在其他活动中,它会给我错误的语言环境和该语言环境的错误资源。旋转后屏幕(或其他一些配置更改)Locale.getDefault()是正确的。
查看完整描述

3 回答

?
凤凰求蛊

TA贡献1825条经验 获得超4个赞

好。最后,我设法找到了解决方案。


首先,您应该知道在25个API Resources.updateConfiguration(...)中已弃用。因此,您可以执行以下操作:


1)您需要创建自己的ContextWrapper,它将覆盖baseContext中的所有配置参数。例如,这是我的ContextWrapper,可以正确更改Locale。注意context.createConfigurationContext(configuration)方法。


public class ContextWrapper extends android.content.ContextWrapper {


    public ContextWrapper(Context base) {

        super(base);

    }


    public static ContextWrapper wrap(Context context, Locale newLocale) {

        Resources res = context.getResources();

        Configuration configuration = res.getConfiguration();


        if (BuildUtils.isAtLeast24Api()) {

            configuration.setLocale(newLocale);


            LocaleList localeList = new LocaleList(newLocale);

            LocaleList.setDefault(localeList);

            configuration.setLocales(localeList);


            context = context.createConfigurationContext(configuration);


        } else if (BuildUtils.isAtLeast17Api()) {

            configuration.setLocale(newLocale);

            context = context.createConfigurationContext(configuration);


        } else {

            configuration.locale = newLocale;

            res.updateConfiguration(configuration, res.getDisplayMetrics());

        }


        return new ContextWrapper(context);

    }

}

2)这是您在BaseActivity中应该做的事情:


@Override

protected void attachBaseContext(Context newBase) {


    Locale newLocale;

    // .. create or get your new Locale object here.


    Context context = ContextWrapper.wrap(newBase, newLocale);

    super.attachBaseContext(context);

}

注意:


如果要在某个地方更改应用程序的区域设置,请记住要重新创建活动。您可以使用此解决方案覆盖所需的任何配置。


查看完整回答
反对 回复 2019-10-25
?
ABOUTYOU

TA贡献1812条经验 获得超5个赞

受各种代码的启发(例如:我们的Stackoverflow团队(大声疾呼)),我制作了一个简单得多的版本。该ContextWrapper扩展名是不必要的。


首先,假设您有2个按钮用于2种语言,即EN和KH。在按钮的onClick中,将语言代码保存到中SharedPreferences,然后调用activity recreate()方法。


例:


@Override

public void onClick(View v) {

    switch(v.getId()) {

        case R.id.btn_lang_en:

            //save "en" to SharedPref here

            break;

        case R.id.btn_lang_kh:

            //save "kh" to SharedPref here

            break;


        default:

        break;

    }

    getActivity().recreate();

}

然后创建一个ContextWrapper可能在Utils类中返回的静态方法(这就是我所做的,lul)。


public static ContextWrapper changeLang(Context context, String lang_code){

    Locale sysLocale;


    Resources rs = context.getResources();

    Configuration config = rs.getConfiguration();


    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {

        sysLocale = config.getLocales().get(0);

    } else {

        sysLocale = config.locale;

    }

    if (!lang_code.equals("") && !sysLocale.getLanguage().equals(lang_code)) {

        Locale locale = new Locale(lang_code);

        Locale.setDefault(locale);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {

            config.setLocale(locale);

        } else {

            config.locale = locale;

        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {

            context = context.createConfigurationContext(config);

        } else {

            context.getResources().updateConfiguration(config, context.getResources().getDisplayMetrics());

        }

    }


    return new ContextWrapper(context);

}

最后,从加载的语言代码SharedPreferences中的所有活动'S attachBaseContext(Context newBase)方法。


@Override

protected void attachBaseContext(Context newBase) {

    String lang_code = "en"; //load it from SharedPref

    Context context = Utils.changeLang(newBase, lang_code);

    super.attachBaseContext(context);

}

奖励:为了节省键盘上的汗水,我创建了一个LangSupportBaseActivity类,扩展了类Activity并在其中使用最后一块代码。并且我将所有其他活动扩展LangSupportBaseActivity。


例:


public class LangSupportBaseActivity extends Activity{

    ...blab blab blab so on and so forth lines of neccessary code


    @Override

    protected void attachBaseContext(Context newBase) {

        String lang_code = "en"; //load it from SharedPref

        Context context = Utils.changeLang(newBase, lang_code);

        super.attachBaseContext(context);

    }

}


public class HomeActivity extends LangSupportBaseActivity{

    ...blab blab blab

}


查看完整回答
反对 回复 2019-10-25
?
哔哔one

TA贡献1854条经验 获得超8个赞

从Android 7.0+开始,我的应用程序的某些部分不再更改其语言。即使使用上面提出的新方法。应用程序和活动上下文的更新对我有所帮助。这是Activity子类覆盖的Kotlin示例:


private fun setApplicationLanguage(newLanguage: String) {

    val activityRes = resources

    val activityConf = activityRes.configuration

    val newLocale = Locale(newLanguage)

    activityConf.setLocale(newLocale)

    activityRes.updateConfiguration(activityConf, activityRes.displayMetrics)


    val applicationRes = applicationContext.resources

    val applicationConf = applicationRes.configuration

    applicationConf.setLocale(newLocale)

    applicationRes.updateConfiguration(applicationConf,

            applicationRes.displayMetrics)

}


override fun attachBaseContext(newBase: Context?) {

    super.attachBaseContext(newBase)


    setApplicationLanguage("fa");

}

注意:不建议使用updateConfiguration,但是无论如何,每个Activity的createConfigurationContext都保留一些字符串不变。


查看完整回答
反对 回复 2019-10-25
  • 3 回答
  • 0 关注
  • 561 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信