Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Changing locale stopped working in Android 10

I've been using below code to change locale in an Android app (the app has its own setting for locale which may be different from OS locale). The code works fine up to Android 9 (P). In Android 10 (Q), it stopped working, the resources are not updated. I don't see any locale related changes in Android 10 release notes. What could break this code in Android 10? If it's something known, could anyone point me to the solution please?

private fun setLocale(context: Context, language: String): Context {
    //...persist here. persisting works fine
    return if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N)
        updateResources(context, language)
    else
        updateResourcesLegacy(context, language)
}

@TargetApi(Build.VERSION_CODES.N)
private fun updateResources(context: Context, language: String): Context {
    val locale = Locale(language)
    Locale.setDefault(locale)

    val configuration = context.resources.configuration
    configuration.setLocale(locale)
    configuration.setLayoutDirection(locale)

    return context.createConfigurationContext(configuration)
}

UPD:

I've found out that this code stopped working after upgrading to a newer version of androidx.appcompat:appcompat. I could narrow it down: it works in 1.2.0-alpha01 and does not work in 1.2.0-alpha02.

I see in the release notes for 1.2.0-alpha02 there were 3 changes related to context: https://developer.android.com/jetpack/androidx/releases/appcompat#1.2.0-alpha02

  • Ensured the base context is always a wrapper (aosp/1194355)
  • Added some improvements to be more clever when modifying the base context configuration (aosp/1204543)
  • Disabled createConfigurationContext() for Robolectric (aosp/1186218)
like image 452
Peter Avatar asked Aug 18 '20 04:08

Peter


1 Answers

I'm posting the response from Googlers that worked for me. I asked the question on their issue tracker and they suggested to create a new Configuration instance instead of modifying existing one.

So, instead of this (the below won't work):

val configuration = context.resources.configuration
configuration.setLocale(locale)
configuration.setLayoutDirection(locale)

it should be (this works):

val configuration = Configuration()
configuration.setLocale(locale)
configuration.setLayoutDirection(locale)

This way is used in their tests: one and two

like image 122
Peter Avatar answered Sep 28 '22 18:09

Peter