Created
September 16, 2016 14:35
-
-
Save kmansoft/e1e76a7df61e8dfb90e34bbc50e43e50 to your computer and use it in GitHub Desktop.
Change Android application locale
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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