Peter
Peter

Reputation: 1602

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

Upvotes: 11

Views: 4217

Answers (2)

AlexeySRG
AlexeySRG

Reputation: 861

Another solution worked for me. It's all about calling the language change method

This is how it doesn't work in Android 10:

setLocale(MyApplication.getContext(), "en");

And this is how it works:

setLocale(MainActivity.this, "en");

Upvotes: 0

Peter
Peter

Reputation: 1602

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

Upvotes: 15

Related Questions