Skip to content

Instantly share code, notes, and snippets.

@kmansoft
Created September 16, 2016 14:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kmansoft/e1e76a7df61e8dfb90e34bbc50e43e50 to your computer and use it in GitHub Desktop.
Save kmansoft/e1e76a7df61e8dfb90e34bbc50e43e50 to your computer and use it in GitHub Desktop.
Change Android application locale
package org.kman.Compat.util;
import java.util.Locale;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Build;
import android.preference.PreferenceManager;
import android.text.TextUtils;
public class AppLocaleManager {
private static final String TAG = "AppLocaleManager";
// Has to match preference key in the .xml file
private static final String PREFS_KEY = "prefsUILocale";
public static AppLocaleManager factory() {
return gInstance;
}
public void applyFromPrefs(Context context) {
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
final String newLocaleCode = prefs.getString(PREFS_KEY, null);
applyImpl(context, newLocaleCode);
}
public void applyFromPrefs(Context context, SharedPreferences prefs) {
final String newLocaleCode = prefs.getString(PREFS_KEY, null);
applyImpl(context, newLocaleCode);
}
public void applyFromValue(Context context, String newLocaleCode) {
applyImpl(context, newLocaleCode);
}
public Locale getSystemLocale() {
if (gSavedSystemLocale != null) {
return gSavedSystemLocale;
}
return Locale.getDefault();
}
private void applyImpl(Context context, String newLocaleCode) {
applyImplToContext(context, newLocaleCode);
final Context app = context.getApplicationContext();
if (app != context) {
applyImplToContext(app, newLocaleCode);
}
}
private boolean applyImplToContext(Context context, String newLocaleCode) {
MyLog.i(TAG, "applyImpl: newLocaleCode = %s, savedSystemLocale = %s", newLocaleCode, gSavedSystemLocale);
Locale newLocale = null;
if (TextUtils.isEmpty(newLocaleCode)) {
// System locale
if (gSavedSystemLocale == null) {
// We've never changed it
return true;
}
newLocale = gSavedSystemLocale;
} else {
// Non-system, explicit locale
if (gSavedSystemLocale == null) {
gSavedSystemLocale = Locale.getDefault();
}
try {
final String[] split = newLocaleCode.split("_");
if (split != null && split.length >= 2) {
newLocale = new Locale(split[0], split[1]);
} else {
newLocale = new Locale(newLocaleCode);
}
} catch (Exception x) {
// Just in case
MyLog.w(TAG, x);
newLocale = null;
}
}
MyLog.i(TAG, "applyImpl: newLocale = %s", newLocale);
if (newLocale == null) {
return false;
}
try {
final Resources resources = context.getResources();
if (resources == null) {
return false;
}
final Configuration config = resources.getConfiguration();
if (config == null) {
return false;
}
if (config.locale == null || !localesEqual(config.locale, newLocale)) {
config.locale = newLocale;
final ConfigCompat configCompat = ConfigCompat.factory();
configCompat.setLayoutDirection(config, newLocale);
resources.updateConfiguration(config, resources.getDisplayMetrics());
}
final Locale defaultLocale = Locale.getDefault();
if (defaultLocale == null || !localesEqual(defaultLocale, newLocale)) {
Locale.setDefault(newLocale);
}
} catch (Exception x) {
// Just in case
MyLog.w(TAG, x);
}
return true;
}
private AppLocaleManager() {
}
private static class ConfigCompat {
static ConfigCompat factory() {
if (Build.VERSION.SDK_INT >= 17) {
return new ConfigCompat_api17();
}
return new ConfigCompat();
}
void setLayoutDirection(Configuration config, Locale locale) {
}
}
private boolean localesEqual(Locale a, Locale b) {
final String langA = a.getLanguage();
final String countryA = a.getCountry();
final String langB = b.getLanguage();
final String countryB = b.getCountry();
return ((langA == null && langB == null) || langA.equals(langB))
&& ((countryA == null && countryB == null) || countryA.equals(countryB));
}
@TargetApi(17)
private static class ConfigCompat_api17 extends ConfigCompat {
@Override
void setLayoutDirection(Configuration config, Locale locale) {
config.setLayoutDirection(locale);
}
}
private static Locale gSavedSystemLocale;
private static AppLocaleManager gInstance = new AppLocaleManager();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment