0

I have an app, where the app language is slovak if the user's device language is set to Slovak, otherwise it will be EN. So the language is not changing in app, but is from instaliing SK or EN.

 String languageToLoad  = Resources.getSystem().getConfiguration().locale.getLanguage();
 String lng = "sk".equals(languageToLoad) ? "sk" : "en";

 Locale locale = new Locale(lng);Locale.setDefault(locale);
 Configuration config = new Configuration();config.locale = locale;
 getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());

I noticed, that locale in Configuration has been deprecated and also updateConfiguration(Configuration, DisplayMetrics) in Resources has been deprecated from android N (I think).

However for some reason it still works also for higher Android versions, but Android studio says it is deprecated.

So I tried to separate the code:

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        String languageToLoad  = Resources.getSystem().getConfiguration().getLocales().get(0).getLanguage();
        String lng = "sk".equals(languageToLoad) ? "sk" : "en";
        Locale locale = new Locale(lng);Locale.setDefault(locale);
        Configuration config = new Configuration();config.setLocale(locale);
        getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());

    } else {
  String languageToLoad  = Resources.getSystem().getConfiguration().locale.getLanguage();
  String lng = "sk".equals(languageToLoad) ? "sk" : "en";

  Locale locale = new Locale(lng);Locale.setDefault(locale);
  Configuration config = new Configuration();config.locale = locale;
  getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
}

but the first condition (for >=N) is not ok, I am not sure how to replace the current code. It still says the updateConfiguration is deprecated.

Even if I try getBaseContext().createConfigurationContext(config); it doesn't change the language

Darksymphony
  • 2,155
  • 30
  • 54

2 Answers2

1

When API >= N, replace this:

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

by this:

context.createConfigurationContext(config);

Yet, you must create a custom context wrapper, and ensure the activity is restarted. See the next accepted answer:

Android N change language programmatically

PerracoLabs
  • 16,449
  • 15
  • 74
  • 127
  • I did as I added it to my question, but it did not change the language – Darksymphony Oct 17 '20 at 10:16
  • However if I leave getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics()); there, it is working, but is deprecated – Darksymphony Oct 17 '20 at 10:22
  • That is deprecated means that it will be removed in a future API version, or stop working completely. Did you create a custom ContextWrapper? – PerracoLabs Oct 17 '20 at 10:26
  • no I didn't. It worked before without it. If possible I want to do it the same way just changing deprecated items. Can't believe setting app locale is not easy nowadays – Darksymphony Oct 17 '20 at 10:31
  • 1
    I've updated the answer, it has been answered before. As you are experiencing, yes something as simple as changing the language is a real pain, I have lived this myself. – PerracoLabs Oct 17 '20 at 10:32
  • why to restart activity? The user will not switch languages in app, I just want to have default language for whole app according the user device lang. For now a few lines of code did this. Really I need to do it with tons of code and creating other class and contextwrapper? – Darksymphony Oct 17 '20 at 10:36
  • 1
    If the user will not change the language manually, then is not necessary to restart the activity. The context wrapper is a single class, and what you can do is to create a Base Activity class which overrides the attachBaseContext method, where you apply the language change. then make all your project activities to be descendants from your new base Activity class. It is a good design to have a custom base Activity class where you can have common functionality. Also, check other of the answers in the supplied link, as some may provide other solutions more suitable for your requirements. – PerracoLabs Oct 17 '20 at 10:44
0

Ok, so I solved it this way:

created a ContextWrapper in separate java file:

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 (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        configuration.setLocale(newLocale);

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

        context = context.createConfigurationContext(configuration);

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

    return new ContextWrapper(context);
}

}

and then in my MainActivity I used it like this:

     @Override
       protected void attachBaseContext(Context newBase) {

        String languageToLoad;
        String lng;
        Locale locale;

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
             languageToLoad = Resources.getSystem().getConfiguration().getLocales().get(0).getLanguage();
        }
else {  languageToLoad  = Resources.getSystem().getConfiguration().locale.getLanguage();
        }

         lng = "sk".equals(languageToLoad) ? "en" : "sk";
         locale = new Locale(lng);Locale.setDefault(locale);

        Context context = ContextWrapper.wrap(newBase, locale);
        super.attachBaseContext(context);
    }

Seems working fine now

Darksymphony
  • 2,155
  • 30
  • 54
  • One thing I don't understand, why I get deprecated message for locale in languageToLoad = Resources.getSystem().getConfiguration().locale.getLanguage(); as this is in ELSE condition, so it is for versions below "N" – Darksymphony Oct 17 '20 at 11:05