3

The app supports os 8.0+

I have added the values-ar folder with support for strings.xml . If I change the language from phone settings to arabic, the app loads the correct resources. If I set the default locale at runtime in Application class, it fails to load the specific ("ar") resources.

d

This is how I change conf (on Application class):

fun changeDefaultLocale() {
        Locale.setDefault(Locale("ar")
        val configuration = resources.configuration
        configuration.setLocale(locale)
        this.createConfigurationContext(configuration)
    }

What I have tried:

  • rename values-ar to values-ar-rEG
  • add resConfigs "en", "ar" on app/build.gradle
  • add android:configChanges="locale" to Manifest/<application
  • use Locale("ar","AE") or Locale("ar","EG")

I had put a break point on the row after I called the above changeDefaultLocale() fun:

enter image description here

Why it doesn't load the correct resource file? I repeat, if I change it from the phone settings it works correctly.

UPDATE

Using @Nurbol response I have updated the BaseActivity as below, and it's working fine. My problem now is:

Activity A -> Activity B (here I switch the locale), then if I press back and the sistem restores Activity A, it has the old configuration, and the old locale. How to overcome that?

override fun attachBaseContext(base: Context) {
    super.attachBaseContext(updateBaseContextLocale(base))
}

private fun updateBaseContextLocale(context: Context): Context {
    val locale = Locale("ar")
    Locale.setDefault(locale)
    return updateResourcesLocale(context, locale)
}

@TargetApi(Build.VERSION_CODES.N)
private fun updateResourcesLocale(context: Context, locale: Locale): Context {
    val configuration = context.resources.configuration
    configuration.setLocale(locale)
    return context.createConfigurationContext(configuration)
}
ghita
  • 2,746
  • 7
  • 30
  • 54
  • https://stackoverflow.com/questions/51097334/refreshrecreate-the-activities-in-back-stack-when-change-locale-at-run-time found here the answer to the updated question. – ghita Jun 23 '19 at 11:29

1 Answers1

0

Changing locales programmaticaly is not suggested. Cause it is buggy. If you really want to change it. You should call changeDefaultLocale() method within every activity's onCreate() befor setContentView(). You can simply create BaseActivity class that does that and use it as parent class of every activity.

abstract class BaseActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Change locale settings in the app.
        val dm = resources.displayMetrics
        val conf = resources.configuration
        val lang = "ar"

        conf.setLocale(Locale(lang.toLowerCase())) // API 17+ only.

        resources.updateConfiguration(conf, dm)
    }
}
Nurbol
  • 371
  • 2
  • 8
  • 1
    Updated my answer. Try it out @ghita – Nurbol Jun 23 '19 at 10:25
  • it does change the rtl configuration (so the layout switched from right to left) but it still doesn't read the proper `strings.xml` file. I'ved also added `Locale.setDefault(Locale("ar")` to your method, no effect; – ghita Jun 23 '19 at 10:50
  • Use updated above code. Deprecated but works @ghita – Nurbol Jun 23 '19 at 11:18
  • thank you for your answer Nurbol, I have found a solution based on your answer, I'ved updated the question. – ghita Jun 23 '19 at 11:21