androidandroid-architecture-componentsandroid-jetpackandroid-10.0

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


Solution

  • 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