12
votes

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
4
it should work on nexus 4 also may you forgot to call recreate()Basil Battikhi
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 BattikhiThe Jake

4 Answers

14
votes

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.

3
votes

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

1
votes

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;
        }
    }
0
votes
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.