Change the locale at runtime?

Since API 11 you can use recreate so can make this method in your activity:

private void restartInLocale(Locale locale)
{
    Locale.setDefault(locale);
    Configuration config = new Configuration();
    config.locale = locale;
    Resources resources = getResources();
    resources.updateConfiguration(config, resources.getDisplayMetrics());
    recreate();
}

You can start a new instance of your activity and exit the old one. Here is a full (untested) example how you can store any desired language and restart your app. You just need to call restartInLanguage with your prefered language.

public class YourMainActivity extends Activity {
    private static final String APP_SHARED_PREFS = "com.example.test";
    private SharedPreferences settings;
    private Editor editor;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        settings=getSharedPreferences(APP_SHARED_PREFS, Activity.MODE_PRIVATE);
        editor=settings.edit();

        Locale locale = new Locale(settings.getString("lang", "default-lang"));
        Locale.setDefault(locale);
        Configuration config = new Configuration();
        config.locale = locale;
        getResources().updateConfiguration(config, getResources().getDisplayMetrics());

        // your stuff...
    }

    public void restartInLanguage(String lang) {
        editor.putString("lang", lang);
        editor.commit();
        Intent intent = getIntent();
        finish();
        startActivity(intent);
    }

    // ...
}

I have combined @weston and @rekire (both +1) and extendet it to handle this use-case:

  • ActivityA => ActivityB => SettingsActivity-changeLocale

After changeLocale in SettingsActivity the parent activities ActivityA and ActivityB should also be recreated to reflect the new locale.

My solution: ActivityA and ActivityB inherit from LocalizedActivity which checks in onResume if the locale has changed and trigger a recreate() if necessary

So every activity that inherits from LocalizedActivity automatically handles app specific locale change.

/**
 * An activity that can change the locale (language) of its content.
 *
 * Inspired by http://stackoverflow.com/questions/13181847/change-the-locale-at-runtime
 *
 * Created by k3b on 07.01.2016.
 */
public class LocalizedActivity extends Activity {
    /** if myLocale != Locale.Default : activity must be recreated in on resume */
    private Locale myLocale = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        fixLocale(this);
        super.onCreate(savedInstanceState);
    }

    @Override
    protected void onResume() {
        super.onResume();

        // Locale has changed by other Activity ?
        if ((myLocale != null) && (myLocale.getLanguage() != Locale.getDefault().getLanguage())) {
            myLocale = null;
            recreate();
        }
    }

    /**
     * Set Activity-s locale to SharedPreferences-setting.
     * Must be called before onCreate
     * @param context
     */
    public static void fixLocale(Context context)
    {
        final SharedPreferences prefs = PreferenceManager
                .getDefaultSharedPreferences(context);
        String language = prefs.getString(Global.PREF_KEY_USER_LOCALE, "");
        Locale locale = Global.systemLocale; // in case that setting=="use android-locale"
        if ((language != null) && (!language.isEmpty())) {
            locale = new Locale(language); // overwrite "use android-locale"
        }

        if (locale != null) {
            Locale.setDefault(locale);
            Configuration config = new Configuration();
            config.locale = locale;
            Resources resources = context.getResources();
            resources.updateConfiguration(config, resources.getDisplayMetrics());
            // recreate();

            if (context instanceof LocalizedActivity) {
                ((LocalizedActivity) context).myLocale = locale;
            }
        }
    }
}

Here is the source of LocalizedActivity.java and SettingsActivity.java that are used in my A Photo Manager project