Search code examples
androidlocale

Setting default locale


We have an english as default, and translations for several other languages in our app. When user launches an app, we call Locale.setDefault() to set it to locale of our translations. For example, phone is running in spanish, but we have no spanish translations, we call Locale.setDefault(Locale.US). We need this for time formatting, because libs use Locale.getDefault(). It works perfectly until android 24. Android 24 "ignores" Locale.setDefault(). And all dates are formatted with device language but not app language.


Solution

  • So the solution was to change not only locale, but also locale inside configuration.

    In application class

    @Override
    protected void attachBaseContext(Context base) {
        LocaleUtil.getInstance().invalidateCurrentLocale(base);
        super.attachBaseContext(base);
    }
    
    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        LocaleUtil.getInstance().invalidateCurrentLocale(this);
    }
    

    And this is LocaleUtil methods

    public void invalidateCurrentLocale(Context context) {
        updateResources(context,
                        getLocaleOrDefault(getConfigLocale(context.getResources().getConfiguration())));
    }
    
    public Locale getConfigLocale(Configuration configuration) {
        if (Build.VERSION.SDK_INT < 24) {
            return configuration.locale;
        } else {
            return configuration.getLocales().get(0);
        }
    }
    
    private Locale getLocaleOrDefault(Locale locale) {
        if (AVAILABLE_LOCALES.contains(locale)) {
            return locale;
        }
        return DEFAULT_LOCALE;
    }
    
    private void updateResources(Context context, Locale locale) {
        Locale.setDefault(locale);
    
        Resources res = context.getResources();
        Configuration config = new Configuration(res.getConfiguration());
        config.setLocale(locale);
        res.updateConfiguration(config, res.getDisplayMetrics());
    }