Asked  7 Months ago    Answers:  5   Viewed   30 times

My app supports 3 (soon 4) languages. Since several locales are quite similar I'd like to give the user the option to change locale in my application, for instance an Italian person might prefer Spanish over English.

Is there a way for the user to select among the locales that are available for the application and then change what locale is used? I don't see it as a problem to set locale for each Activity since it is a simple task to perform in a base class.

 Answers

50

For people still looking for this answer, since configuration.locale was deprecated from API 24, you can now use:

configuration.setLocale(locale);

Take in consideration that the minSkdVersion for this method is API 17.

Full example code:

@SuppressWarnings("deprecation")
private void setLocale(Locale locale){
    SharedPrefUtils.saveLocale(locale); // optional - Helper method to save the selected language to SharedPreferences in case you might need to attach to activity context (you will need to code this)
    Resources resources = getResources();
    Configuration configuration = resources.getConfiguration();
    DisplayMetrics displayMetrics = resources.getDisplayMetrics();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1){
        configuration.setLocale(locale);
    } else{
        configuration.locale=locale;
    }
    if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N){
        getApplicationContext().createConfigurationContext(configuration);
    } else {
        resources.updateConfiguration(configuration,displayMetrics);
    }
}

Don't forget that, if you change the locale with a running Activity, you will need to restart it for the changes to take effect.

EDIT 11th MAY 2018

As from @CookieMonster's post, you might have problems keeping the locale change in higher API versions. If so, add the following code to your Base Activity so that you update the context locale on every Activity creation:

@Override
protected void attachBaseContext(Context base) {
     super.attachBaseContext(updateBaseContextLocale(base));
}

private Context updateBaseContextLocale(Context context) {
    String language = SharedPrefUtils.getSavedLanguage(); // Helper method to get saved language from SharedPreferences
    Locale locale = new Locale(language);
    Locale.setDefault(locale);

    if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N) {
        return updateResourcesLocale(context, locale);
    }

    return updateResourcesLocaleLegacy(context, locale);
}

@TargetApi(Build.VERSION_CODES.N_MR1)
private Context updateResourcesLocale(Context context, Locale locale) {
    Configuration configuration = new Configuration(context.getResources().getConfiguration())
    configuration.setLocale(locale);
    return context.createConfigurationContext(configuration);
}

@SuppressWarnings("deprecation")
private Context updateResourcesLocaleLegacy(Context context, Locale locale) {
    Resources resources = context.getResources();
    Configuration configuration = resources.getConfiguration();
    configuration.locale = locale;
    resources.updateConfiguration(configuration, resources.getDisplayMetrics());
    return context;
}

If you use this, don't forget to save the language to SharedPreferences when you set the locale with setLocate(locale)

EDIT 7th APRIL 2020

You might be experiencing issues in Android 6 and 7, and this happens due to an issue in the androidx libraries while handling the night mode. For this you will also need to override applyOverrideConfiguration in your base activity and update the configuration's locale in case a fresh new locale one is created.

Sample code:

@Override
public void applyOverrideConfiguration(Configuration overrideConfiguration) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && Build.VERSION.SDK_INT <= Build.VERSION_CODES.N_MR1) {
        // update overrideConfiguration with your locale  
        setLocale(overrideConfiguration) // you will need to implement this
    }
    super.applyOverrideConfiguration(overrideConfiguration);
} 
Tuesday, June 1, 2021
 
eek
answered 7 Months ago
eek
72

Answering my own question: On Ubuntu the default LANG is defined in /etc/default/locale:

jeroen@dev:~? cat /etc/default/locale
# Created by cloud-init v. 0.7.7 on Wed, 29 Jun 2016 11:02:51 +0000
LANG="en_US.UTF-8"

So in R we could do something like:

readRenviron("/etc/default/locale")
LANG <- Sys.getenv("LANG")
if(nchar(LANG))
   Sys.setlocale("LC_ALL", LANG)

Apache also has a line in /etc/apache2/envvars that can be uncommented to enable this.

Wednesday, June 9, 2021
 
felipsmartins
answered 6 Months ago
62

try using gem geocoder and i18n_data gem and have a before_filter to a method which does

def checklocale
  I18n.locale =  I18nData.country_code(request.location.country) 
end
Tuesday, August 3, 2021
 
Jodrell
answered 4 Months ago
85

Sorry for late reply

Try this

  Locale[] locales = Locale.getAvailableLocales();
            ArrayList<String> localcountries=new ArrayList<String>();
            for(Locale l:locales)
            {
                localcountries.add(l.getDisplayLanguage().toString());
            }
    String[] languages=(String[]) localcountries.toArray(new String[localcountries.size()]);

I hope this will help you.

Wednesday, August 4, 2021
 
Revent
answered 4 Months ago
77

The language is defined by a two-letter ISO 639-1 language code, optionally followed by a two letter ISO 3166-1-alpha-2 region code (preceded by lowercase "r").

from Providing Resources

According to the linked table, he is the qualifier for hebrew.

Note: Some devices use iw instead, as Error 545 noted in the comments, so you better check for both cases. See this question for more information.

Friday, August 6, 2021
 
ErocM
answered 4 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :  
Share