12

I'm writing app that support two language and I'm changing language with Change app Locale here my code :

 Locale locale = new Locale("fa");
            Locale.setDefault(locale);
            Configuration configs = new Configuration();
            configs.locale = locale;
            getBaseContext().getResources().updateConfiguration(configs, getBaseContext().getResources().getDisplayMetrics());

And

in manifest I'm set android:supportsRtl="true"

These codes working in many Devices but in some devices not working . for example Texts not Translating but Direction change .

Tested Devices :

  • Samsung J5Pro 2018 (android = 7.1): Worked
  • Pixel 2 API 26 : Worked
  • Samsung J7 2017 (android = 7): Worked
  • Nexus 5 (android = 6) : Not Worked
  • Samsung Galaxy G531 (android < lollipop) : Not Worked
Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
The Jake
  • 285
  • 2
  • 14
  • it should work on nexus 4 also may you forgot to call `recreate()` – Basil Battikhi Oct 24 '18 at 08:11
  • I have an activity that shows in the first time for choosing Language ,after user choose one of the languages then app direct user to the MainActivity. so i don't need to `recreate()` @Basil Battikhi – The Jake Oct 24 '18 at 08:30

4 Answers4

15

i have found my solution , my problem was i'm inserted "fa" in Locale and my String Values Directory name was values-fa-rlIR, so names are different so not worked ,i'm wondering why it's working on some devices!

I'm just change the String Values Directory name from values-fa-rlIR to values-fa and it's working well.

The Jake
  • 285
  • 2
  • 14
3

had the same problem. Android Studio names the language folder like values-xx-rXX. Android 6.0 and lower can't handle this so You have to rename the foldername (I did it directly in Windows Explorer) to values-de. Now it works for me on all devices

2

or try this method , i used in many apps and it works

@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
    fun fixUpLocale(ctx: Context, newLocale: Locale) {
        val res = ctx.resources
        val config = res.configuration
        val curLocale = getLocale(config)
        if (curLocale != newLocale) {
            Locale.setDefault(newLocale)
            val conf = Configuration(config)
            conf.setLocale(newLocale)
            res.updateConfiguration(conf, res.displayMetrics);
        }
    }

    fun getLocale(config: Configuration): Locale {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            return config.locales[0]
        } else {
            //noinspection deprecation
            return config.locale;
        }
    }
B.mansouri
  • 376
  • 7
  • 16
0
fun changeLang(context: Context, lang_code: String): ContextWrapper {
    defaultLanguage = lang_code
    var context = context
    val sysLocale: Locale

    val rs = context.resources
    val config = rs.configuration

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        sysLocale = config.locales.get(0)
    } else {
        sysLocale = config.locale
    }
    if (lang_code != "" && !sysLocale.language.equals(lang_code)) {
        val locale = 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.resources.updateConfiguration(config, context.resources.displayMetrics)
        }
    }

    return ContextWrapper(context)
}

put this in every activity that you want to change the language

   override fun attachBaseContext(newBase: Context) {
    val lang_code = Shared.defaultLanguage //load it from SharedPref
    val context = Shared.changeLang(newBase, lang_code)
    super.attachBaseContext(context)
}

you can try this code , it's in Kotlin , and for more information you can check Android N change language programmatically

i think that it's an API matter.

B.mansouri
  • 376
  • 7
  • 16
  • i have problem in android Marshmallow and prelollipop but your code is for Android N so cant help me . – The Jake Oct 24 '18 at 08:25
  • try this line context.createConfigurationContext(config) – B.mansouri Oct 24 '18 at 08:26
  • where should i use this ? this is not updating the Configuration. @B.mansouri – The Jake Oct 24 '18 at 08:45
  • add the on attachBaseContext in every activity – B.mansouri Oct 24 '18 at 08:49
  • i'm getting android.content.Context.getSharedPreferences(java.lang.String, int)' on a null object reference Error when write it in attacbaseContext in main activity and i'm in java no Kotlin – The Jake Oct 24 '18 at 09:21
  • try to use a fixed local and try to test it , if it works , then try to use the local from the shared preferences – B.mansouri Oct 24 '18 at 09:22
  • i'm use this , is it right ?@B.mansouri `@Override protected void attachBaseContext(Context newBase) { Locale locale = new Locale("fa"); Locale.setDefault(locale); Configuration configs = new Configuration(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { configs.setLocale(locale); } else { configs.locale = locale; } newBase.createConfigurationContext(configs); super.attachBaseContext(newBase); }` – The Jake Oct 24 '18 at 10:00
  • try to make the langauge change in a function taht return context Wrapper and try again – B.mansouri Oct 24 '18 at 10:08