Change Locale not work after migrate to Androidx

change locale android
android change default locale
android locale not updating
android change language without restarting activity
how to change whole app language in android programmatically
updateconfiguration deprecated
android change language programmatically
android studio default locale

I have an old project that supports multi-languages. I want to upgrade support library and target platform, Before migrating to Androidx everything works fine but now change language not work!

I use this code to change default locale of App

private static Context updateResources(Context context, String language)
{
    Locale locale = new Locale(language);
    Locale.setDefault(locale);

    Configuration configuration = context.getResources().getConfiguration();
    configuration.setLocale(locale);

    return context.createConfigurationContext(configuration);
}

And call this method on each activity by override attachBaseContext like this:

@Override
protected void attachBaseContext(Context newBase)
{
    SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
    String language = preferences.getString(SELECTED_LANGUAGE, "fa");
    super.attachBaseContext(updateResources(newBase, language));
}

I try other method to get string and I noticed that ‍‍‍‍getActivity().getBaseContext().getString work and getActivity().getString not work. Even the following code does not work and always show app_name vlaue in default resource string.xml.

<TextView
    android:id="@+id/textView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/app_name"/>

I share a sample code in https://github.com/Freydoonk/LanguageTest

Also getActivity()..getResources().getIdentifier not work and always return 0!


Basically what's happening in the background is that while you've set the configuration correctly in attachBaseContext, the AppCompatDelegateImpl then goes and overrides the configuration to a completely fresh configuration without a locale:

 final Configuration conf = new Configuration();
 conf.uiMode = newNightMode | (conf.uiMode & ~Configuration.UI_MODE_NIGHT_MASK);

 try {
     ...
     ((android.view.ContextThemeWrapper) mHost).applyOverrideConfiguration(conf);
     handled = true;
 } catch (IllegalStateException e) {
     ...
 }

In an unreleased commit by Chris Banes this was actually fixed: The new configuration is a deep copy of the base context's configuration.

final Configuration conf = new Configuration(baseConfiguration);
conf.uiMode = newNightMode | (conf.uiMode & ~Configuration.UI_MODE_NIGHT_MASK);
try {
    ...
    ((android.view.ContextThemeWrapper) mHost).applyOverrideConfiguration(conf);
    handled = true;
} catch (IllegalStateException e) {
    ...
}

Until this is released, it's possible to do the exact same thing manually. To continue using version 1.1.0 add this below your attachBaseContext:

Kotlin solution

override fun applyOverrideConfiguration(overrideConfiguration: Configuration?) {
    if (overrideConfiguration != null) {
        val uiMode = overrideConfiguration.uiMode
        overrideConfiguration.setTo(baseContext.resources.configuration)
        overrideConfiguration.uiMode = uiMode
    }
    super.applyOverrideConfiguration(overrideConfiguration)
}

Java solution

@Override
public void applyOverrideConfiguration(Configuration overrideConfiguration) {
    if (overrideConfiguration != null) {
        int uiMode = overrideConfiguration.uiMode;
        overrideConfiguration.setTo(getBaseContext().getResources().getConfiguration());
        overrideConfiguration.uiMode = uiMode;
    }
    super.applyOverrideConfiguration(overrideConfiguration);
}

This code does exactly the same what Configuration(baseConfiguration) does under the hood, but because we are doing it after the AppCompatDelegate has already set the correct uiMode, we have to make sure to take the overridden uiMode over to after we fix it so we don't lose the dark/light mode setting.

Please note that this only works by itself if you don't specify configChanges="uiMode" inside your manifest. If you do, then there's yet another bug: Inside onConfigurationChanged the newConfig.uiMode won't be set by AppCompatDelegateImpl's onConfigurationChanged. This can be fixed as well if you copy all the code AppCompatDelegateImpl uses to calculate the current night mode to your base activity code and then override it before the super.onConfigurationChanged call. In Kotlin it would look like this:

private var activityHandlesUiMode = false
private var activityHandlesUiModeChecked = false

private val isActivityManifestHandlingUiMode: Boolean
    get() {
        if (!activityHandlesUiModeChecked) {
            val pm = packageManager ?: return false
            activityHandlesUiMode = try {
                val info = pm.getActivityInfo(ComponentName(this, javaClass), 0)
                info.configChanges and ActivityInfo.CONFIG_UI_MODE != 0
            } catch (e: PackageManager.NameNotFoundException) {
                false
            }
        }
        activityHandlesUiModeChecked = true
        return activityHandlesUiMode
    }

override fun onConfigurationChanged(newConfig: Configuration) {
    if (isActivityManifestHandlingUiMode) {
        val nightMode = if (delegate.localNightMode != AppCompatDelegate.MODE_NIGHT_UNSPECIFIED) 
            delegate.localNightMode
        else
            AppCompatDelegate.getDefaultNightMode()
        val configNightMode = when (nightMode) {
            AppCompatDelegate.MODE_NIGHT_YES -> Configuration.UI_MODE_NIGHT_YES
            AppCompatDelegate.MODE_NIGHT_NO -> Configuration.UI_MODE_NIGHT_NO
            else -> applicationContext.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK
        }
        newConfig.uiMode = configNightMode or (newConfig.uiMode and Configuration.UI_MODE_NIGHT_MASK.inv())
    }
    super.onConfigurationChanged(newConfig)
}

UPDATE Dec 16:

The recent version of AppCompatDelegateImpl.java has received many more changes since initially writing this post. The fix by Chris Banes I mention above apparently wasn't enough to completely get rid of all bugs related to configChanges (you can see my workaround above for configChanges="uiMode", and one user pointed out in the comments here that in his case the orientation value wasn't changing in onConfigurationChanged). The latest implementation instead relies on a new method called generateConfigDelta to create the correct configuration instance, so every other way of handling night mode is effectively deprecated.

Personally, I've been using my solution for months without any issues or any users complaining, but you should still be aware that AppCompatDelegateImpl is still a work in progress, so please use my solution at your own discretion. Also make sure to check out the other answers which suggest a downgrade to earlier library versions, which might be more appropriate in your situation.

Not working for new AndroidX appcompat versions · Issue #53 , Recently I upgraded my AndroidX dependency versions (from 1.1.0 to questions/55265834/change-locale-not-work-after-migrate-to-androidx I have an old project that supports multi-languages. I want to upgrade support library and target platform, Before migrating to Androidx everything works fine but now change language not work! I use this code to change default locale of App


Finally, I find the problem in my app. When migrating the project to Androidx dependencies of my project changed like this:

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'androidx.appcompat:appcompat:1.1.0-alpha03'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    implementation 'com.google.android.material:material:1.1.0-alpha04'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0-alpha02'
} 

As it is seen, version of androidx.appcompat:appcompat is 1.1.0-alpha03 when I changed it to the latest stable version, 1.0.2, my problem is resolved and the change language working properly.

I find the latest stable version of appcompat library in Maven Repository. I also change other libraries to the latest stable version.

Now my app dependencies section is like bellow:

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'androidx.appcompat:appcompat:1.0.2'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    implementation 'com.google.android.material:material:1.0.0'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
}

Does not work with 'appcompat:1.1.0' · Issue #6 · YarikSOffice , I have an old project that supports multi-languages. I want to upgrade support library and target platform, Before migrating to Androidx everything works fine but​  Migration to androidx looks quite straight forward but involves some manual work to follow up after automatic migration. It also requires some careful efforts on testing since even after


There is an issue in new app compat libraries related to night mode that is causing to override the configuration on android 21 to 25. This can be fixed by applying your configuration when this public function is called:

public void applyOverrideConfiguration(Configuration overrideConfiguration

For me, this little trick has worked by copying the settings from the overridden configuration to my configuration but you can do whatever you want. It is better to reapply your language logic to the new configuration to minimize errors

@Override
public void applyOverrideConfiguration(Configuration overrideConfiguration) {
    if (Build.VERSION.SDK_INT >= 21&& Build.VERSION.SDK_INT <= 25) {
        //Use you logic to update overrideConfiguration locale
        Locale locale = getLocale()//your own implementation here;
        overrideConfiguration.setLocale(locale);
    }
    super.applyOverrideConfiguration(overrideConfiguration);
}

Android, android documentation: Change locale of android application programatically. Following example explain how to change the application locale within application, not from device. SharedPreferences; import android.content.res. need to restart your activity to take the effect of locale change In order to work properly for  If I run the master branch on my device, everything is working perfectly and the language change as expected when I press the button to change the language. As soon as I update the appcompat library in build.gradle (from implementation 'androidx.appcompat:appcompat:1.0.2' to implementation 'androidx.appcompat:appcompat:1.1.0 ), the language


Finally i got solution for locate, In my case actually issue was with bundle apk because it split the locate files. In bundle apk by default all splits will be generated. but within the android block of your build.gradle file you are able to declare which splits will be generated.

bundle {
            language {
                // Specifies that the app bundle should not support
                // configuration APKs for language resources. These
                // resources are instead packaged with each base and
                // dynamic feature APK.
                enableSplit = false
            }
        }

After adding this code to android block of build.gradle file my issue get resolved.

Support different languages and cultures, custom back navigation · Migrate to the Navigation component Supporting different languages goes beyond using locale-specific resources. Use format strings, not method calls, to convert numbers to strings in your app's logic: when used on devices running Android 4.2 (API level 17) or higher. In this tutorial we will learn how to migrate an existing Android Studio project, to use the new AndroidX (Android Extension Libraries) dependencies. The And


Late answer but I thought might be helpful. As of androidx.appcompat:appcompat:1.2.0-beta01 The solution of 0101100101 overriding applyOverrideConfiguration no longer works on me. Instead, in then overriden attacheBaseContext, you have to call the applyOverrideConfiguration() without overriding it.

override fun attachBaseContext(newBase: Context) {
    val newContext = LocaleHelper.getUpdatedContext(newBase)
    super.attachBaseContext(newContext)
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && Build.VERSION.SDK_INT <= Build.VERSION_CODES.N_MR1){
        applyOverrideConfiguration(newContext.resources.configuration)
    }
}

It's just a shame that his solution only works on 1.1.0. Base on my research this should have been officially fix. It's just weird that this bug still here. I know I use the beta but for someone who wants to use the latest, this solution for me is working. Tested on emulator api level 21-25. Above that api level, you don't have to worry about it.

Localize your app, Whenever the app runs in a locale for which you have not provided locale-​specific When this app is launched on a device with locale set to English, the app might run without a problem, because Move all strings into strings.xml strings in strings.xml as well, and regenerate the images after translation. After the language change, activity titles are not translated properly sometimes even after restarting of an activity. It took me some time to find out what’s going on. During a launch of an activity, its title (declared in a manifest file) is being loaded from the top level resources and cached.


java.util.Locale.setDefault java code examples, Best Java code snippets using java.util.Locale.setDefault (Showing top 20 results out of 3,339) onConfigurationChanged(newConfig); // Set correct language (​default or chosen) Locale Configuration; import android.os. This does not affect system configuration, and attempts to override the Work around this by avo. AndroidX replaces the original support library APIs with packages in the androidx namespace. Only the package and Maven artifact names changed; class, method, and field names did not change. Note: We recommend working in a separate branch when migrating. Also try to avoid refactoring your code while performing the migration. Prerequisites


Android-LocalizationActivity, Keep calm and stay easy with multiple language supported in your android LocalizationActivityDelegate; import com.akexorcist.localizationactivity.core. getLanguage(this); } // Just override method locale change event @Override public void "License"); you may not use this work except in compliance with the License. See Migrating to AndroidX to learn how to migrate an existing project. If you want to use androidx -namespaced libraries in a new project, you need to set the compile SDK to Android 9.0 (API level 28) or higher and set both of the following Android Gradle plugin flags to true in your gradle.properties file.


androidx.ui.text.Locale A Locale object represents a specific geographical, political, or cultural region. An operation that requires a Locale to perform its task is called locale-sensitive and uses the Locale to tailor information for the user.