Unable to change language in Oreo

大兔子大兔子 提交于 2019-11-30 20:35:51

When you set new Locale you should restart your Activity. You can perform it using the next snippet of code:

private void restartActivity() {
    Intent intent = getIntent();
    finish();
    startActivity(intent);
}

Then your changeLanguage() method will look in a next way:

public void changeLanguage(Context context, String language) {
    Locale locale = new Locale(language);
    Locale.setDefault(locale);
    Configuration config = context.getResources().getConfiguration();
    config.setLocale(locale);
    context.createConfigurationContext(config);
    context.getResources().updateConfiguration(config, context.getResources().getDisplayMetrics());

    restartActivity();
}
Locale locale = new Locale(lang);
    Locale.setDefault(locale);
    Configuration config = new Configuration();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        config.setLocale(locale);
    } else {
        config.locale = locale;
    }
    context.getApplicationContext().getResources().updateConfiguration(config,
            context.getApplicationContext().getResources().getDisplayMetrics());

This worked for me.

I had same problem before and after some research I find out one solution. Create custom language aware context wrapper and attach on your activity's attachBaseContext() method.

@SuppressWarnings("NewApi")
public static LanguageAwareContext newLanguageAwareContext(String targetLanguage, Context context) {
    Resources resources = context.getResources();
    Configuration configuration = resources.getConfiguration();

    Locale newLocale = new Locale(targetLanguage);

    if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N) {
        configuration.setLocale(newLocale);
        LocaleList.setDefault(new LocaleList(newLocale));

        context = context.createConfigurationContext(configuration);
    } else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR1) {
        configuration.setLocale(newLocale);
        context = context.createConfigurationContext(configuration);
    } else {
        resources.updateConfiguration(configuration, resources.getDisplayMetrics());
    }

    return new LanguageAwareContext(context);
}

override attachBaseContext method and change with your customized context wrapper

@Override
protected void attachBaseContext(Context newBase) {
    newBase = LanguageAwareContext.newLanguageAwareContext("en",newBase);

    super.attachBaseContext(newBase);
}

Yes, there is issue with Android Oreo for language change(strings and layout direction in arabic,urdu and hebrew), i found the solution this will help you to solve this problem

In LanguageContextWrapper.java class

 public static ContextWrapper wrap(Context context, String language) {
            Locale locale = new Locale(language);
            Locale.setDefault(locale);
            Resources resources = context.getResources();
            Configuration configuration = resources.getConfiguration();
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                configuration.setLocale(locale);
                LocaleList localeList = new LocaleList(locale);
                LocaleList.setDefault(localeList);
                configuration.setLocales(localeList);
                configuration.setLayoutDirection(locale);
                context.createConfigurationContext(configuration);
            } else {
                configuration.locale = locale;
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
                    configuration.setLayoutDirection(locale);
                }
            }
            resources.updateConfiguration(configuration, resources.getDisplayMetrics());

        return new LanguageContextWrapper(context);
    }

In activity class override following method

 override fun attachBaseContext(base: Context) {
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N_MR1) {
            super.attachBaseContext(LanguageContextWrapper.wrap(base, Locale.getDefault().language))
        } else {
            super.attachBaseContext(base)
        }
    }

And after change language we have to recreate activity, we need to write following code

fun recreateActivity(){
    if (Build.VERSION.SDK_INT in 26..27) {
                    if (Locale.getDefault().language == "ar" ||
                            Locale.getDefault().language == "iw" ||
                            Locale.getDefault().language == "ur")
                        window.decorView.layoutDirection = View.LAYOUT_DIRECTION_RTL
                    else
                        window.decorView.layoutDirection = View.LAYOUT_DIRECTION_LTR
                }
                recreate()

  }

I recently faced issue related to layout direction on Oreo. Resources were being updated but Layout direction not changing.

Below code worked for me.

 public static void setRTLSupportIfRequired(AppCompatActivity activity) {
        if(getLanguageFromPrefs(activity).equals("ar")) {
            activity.getWindow().getDecorView().setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
        }else{
            activity.getWindow().getDecorView().setLayoutDirection(View.LAYOUT_DIRECTION_LTR);
        }

    }

Note: Previously I were using View.LAYOUT_DIRECTION_LOCALE but it was not working on Oreo

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!