Force locale for Android flavor with resConfig

前端 未结 2 827
自闭症患者
自闭症患者 2020-12-01 06:44

I am trying to use the resConfig and resConfigs from the Android Build system.

  • Android Studio version 1.2.2
  • Gradle build version 1.2.3
  • OSX 1
2条回答
  •  一生所求
    2020-12-01 07:41

    Well, after many hours, here's the solution to my problem for those ending up with the same problem.

    Turns out that resConfig is not for what I though. The proper and only way I found to force the locale for a specific flavor is like this:

    First, make sure all your activities extends a common activity which will be responsible to force the locale. (I had to create 2 since I have some activities extending FragmentActivity and some extending Activity. I also don't really like doing so in the Activities constructor but since I have to call applyOverrideConfiguration before any call is done on getResources, I need to call it before the activity's onStart).

    public class LocaleMainActivity extends Activity {
    
        public LocaleMainActivity() {
            ActivityUtils.forceLocale(this);
        }
    }
    
    public class LocaleMainFragmentActivity extends FragmentActivity {
    
        public LocaleMainFragmentActivity() {
            ActivityUtils.forceLocale(this);
        }
    }
    
    //Method from ActivityUtils
    public static void forceLocale(ContextThemeWrapper contextThemeWrapper) {
        Configuration configuration = new Configuration();
        Locale defaultLocale = new Locale(BuildConfig.LOCALE);
        configuration.locale = defaultLocale;
        contextThemeWrapper.applyOverrideConfiguration(configuration);      
    }
    

    Next, you need to define the locale in your build.gradle flavors

    productFlavors {
    
        myFrenchFlavor {
         buildConfigField "String", "LOCALE", "\"fr\""
        }
        myEnglishFlavor {
          buildConfigField "String", "LOCALE", "\"en\""
        }
    }
    

    I tested the solution on API 19+. Works when you change language while in the app too.



    Alternate solution (won't work on Android M+ see android bug report) This solution is wide spreaded on stackOverflow but I faced a wall while implementing this on Android M so keep this in mind.

    In the onCreate() of your AndroidApplication you can call updateConfiguration with the locale set.

    Locale myLocale = new Locale(BuildConfig.LOCALE);
    Resources res = getResources();
    Configuration conf = res.getConfiguration();
    conf.locale = myLocale;
    res.updateConfiguration(conf, res.getDisplayMetrics());
    

    You will also need to reset it if you defined onConfigurationChanged()

    @Override
        public void onConfigurationChanged(Configuration newConfig) {
            super.onConfigurationChanged(newConfig);            
            Configuration config = new Configuration(newConfig);
            config.locale = new Locale(BuildConfig.LOCALE);
            getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
        }
    

    EDIT: Be aware that this applyOverrideConfiguration currently has a side effect which is explained here Chromium webview does not seems to work with Android applyOverrideConfiguration. The Chromium team are currently working on it!

    Thanks.

提交回复
热议问题