Change app language programmatically in Android
It's possible. You can set the locale. However, I would not recommend that. We've tried it at early stages, it's basically fighting the system.
We have the same requirement for changing the language but decided to settle to the fact that UI should be same as phone UI. It was working via setting locale but was too buggy. And you have to set it every time you enter activity (each activity) from my experience. here is a code if you still need this (again, I don't recommend that)
Resources res = context.getResources();
// Change locale settings in the app.
DisplayMetrics dm = res.getDisplayMetrics();
android.content.res.Configuration conf = res.getConfiguration();
conf.setLocale(new Locale(language_code.toLowerCase())); // API 17+ only.
// Use conf.locale = new Locale(...) if targeting lower versions
res.updateConfiguration(conf, dm);
If you have language specific content - you can change that base on the setting.
update on 26th of march 2020
public static void setLocale(Activity activity, String languageCode) {
Locale locale = new Locale(languageCode);
Locale.setDefault(locale);
Resources resources = activity.getResources();
Configuration config = resources.getConfiguration();
config.setLocale(locale);
resources.updateConfiguration(config, resources.getDisplayMetrics());
}
- NOTES: Language code cannot got '-' & must be 2 small case letter only
Android - Change application locale programmatically
A blog article, how to change the language on Android at runtime and don’t go mad, addressed the issue (along with others) and the author created a library called Lingver to solve the issues.
EDIT (3 Jun 2022): Lingver library has completely failed to address a few issues and appears to be inactive for some time. After a thorough investigation, I have came up with my own implementation: (You can copy the code below under the terms of either Apache-2.0 or GPL-3.0-or-later license)
LangUtils.java
public final class LangUtils {
public static final String LANG_AUTO = "auto";
public static final String LANG_DEFAULT = "en";
private static ArrayMap<String, Locale> sLocaleMap;
public static void init(@NonNull Application application) {
application.registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() {
private final HashMap<ComponentName, Locale> mLastLocales = new HashMap<>();
@Override
public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) {
mLastLocales.put(activity.getComponentName(), applyLocaleToActivity(activity));
}
@Override
public void onActivityStarted(@NonNull Activity activity) {
if (!Objects.equals(mLastLocales.get(activity.getComponentName()), getFromPreference(activity))) {
Log.d("LangUtils", "Locale changed in activity " + activity.getComponentName());
ActivityCompat.recreate(activity);
}
}
@Override
public void onActivityResumed(@NonNull Activity activity) {
}
@Override
public void onActivityPaused(@NonNull Activity activity) {
}
@Override
public void onActivityStopped(@NonNull Activity activity) {
}
@Override
public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) {
}
@Override
public void onActivityDestroyed(@NonNull Activity activity) {
mLastLocales.remove(activity.getComponentName());
}
});
application.registerComponentCallbacks(new ComponentCallbacks() {
@Override
public void onConfigurationChanged(@NonNull Configuration newConfig) {
applyLocale(application);
}
@Override
public void onLowMemory() {
}
});
applyLocale(application);
}
public static void setAppLanguages(@NonNull Context context) {
if (sLocaleMap == null) sLocaleMap = new ArrayMap<>();
Resources res = context.getResources();
Configuration conf = res.getConfiguration();
// Assume that there is an array called language_key which contains all the supported language tags
String[] locales = context.getResources().getStringArray(R.array.languages_key);
Locale appDefaultLocale = Locale.forLanguageTag(LANG_DEFAULT);
for (String locale : locales) {
conf.setLocale(Locale.forLanguageTag(locale));
Context ctx = context.createConfigurationContext(conf);
String langTag = ctx.getString(R.string._lang_tag);
if (LANG_AUTO.equals(locale)) {
sLocaleMap.put(LANG_AUTO, null);
} else if (LANG_DEFAULT.equals(langTag)) {
sLocaleMap.put(LANG_DEFAULT, appDefaultLocale);
} else sLocaleMap.put(locale, ConfigurationCompat.getLocales(conf).get(0));
}
}
@NonNull
public static ArrayMap<String, Locale> getAppLanguages(@NonNull Context context) {
if (sLocaleMap == null) setAppLanguages(context);
return sLocaleMap;
}
@NonNull
public static Locale getFromPreference(@NonNull Context context) {
String language = // TODO: Fetch current language from the shared preferences
getAppLanguages(context);
Locale locale = sLocaleMap.get(language);
if (locale != null) {
return locale;
}
// Load from system configuration
Configuration conf = Resources.getSystem().getConfiguration();
//noinspection deprecation
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N ? conf.getLocales().get(0) : conf.locale;
}
public static Locale applyLocaleToActivity(Activity activity) {
Locale locale = applyLocale(activity);
// Update title
try {
ActivityInfo info = activity.getPackageManager().getActivityInfo(activity.getComponentName(), 0);
if (info.labelRes != 0) {
activity.setTitle(info.labelRes);
}
} catch (Exception e) {
e.printStackTrace();
}
// Update menu
activity.invalidateOptionsMenu();
return locale;
}
private static Locale applyLocale(Context context) {
return applyLocale(context, LangUtils.getFromPreference(context));
}
private static Locale applyLocale(@NonNull Context context, @NonNull Locale locale) {
updateResources(context, locale);
Context appContext = context.getApplicationContext();
if (appContext != context) {
updateResources(appContext, locale);
}
return locale;
}
private static void updateResources(@NonNull Context context, @NonNull Locale locale) {
Locale.setDefault(locale);
Resources res = context.getResources();
Configuration conf = res.getConfiguration();
//noinspection deprecation
Locale current = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N ? conf.getLocales().get(0) : conf.locale;
if (current == locale) {
return;
}
conf = new Configuration(conf);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
setLocaleApi24(conf, locale);
} else {
conf.setLocale(locale);
}
//noinspection deprecation
res.updateConfiguration(conf, res.getDisplayMetrics());
}
@RequiresApi(Build.VERSION_CODES.N)
private static void setLocaleApi24(@NonNull Configuration config, @NonNull Locale locale) {
LocaleList defaultLocales = LocaleList.getDefault();
LinkedHashSet<Locale> locales = new LinkedHashSet<>(defaultLocales.size() + 1);
// Bring the target locale to the front of the list
// There's a hidden API, but it's not currently used here.
locales.add(locale);
for (int i = 0; i < defaultLocales.size(); ++i) {
locales.add(defaultLocales.get(i));
}
config.setLocales(new LocaleList(locales.toArray(new Locale[0])));
}
}
MyApplication.java
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
LangUtils.init(this);
}
}
In your preference where you are changing the language, you can simply restart the preferences activity like this:
ActivityCompat.recreate(activity);
Activites that use Android WebView
After loading the webview via Activity.findViewById()
you can add the following line immediately:
// Fix locale issue due to WebView (https://issuetracker.google.com/issues/37113860)
LangUtils.applyLocaleToActivity(this);
How can I change language of whole application by only single click?
Change Language Programmatically in Android
Here is the appropriate way of changing the locale of the application:
There are some difficulties which you have to overcome to change the language programmatically.
1.)Your application will not remember your language change after it is closed or recreated during the configuration change.
2.)You should update currently visible UI properly according to the selected language.
Solution
“LocaleHelper
” is the solution all you need. You just have to initialize locale on your application’s main class. After that all your language changes will persist.
After the recent changes in Android API Version 24(Nougat) we need to override attachBaseContext to reflect changes.
Below method used to change language for application :
private static boolean updateResources(Context context, String language) {
Locale locale = new Locale(language);
Locale.setDefault(locale);
Resources resources = context.getResources();
Configuration configuration = resources.getConfiguration();
configuration.locale = locale;
resources.updateConfiguration(configuration, resources.getDisplayMetrics());
return true;
}
find more details in below link :
Changing Android’s Locale Programmatically
Related Topics
How to Create a Video from an Array of Images in Android
How to Get Data from Edit Text in a Recyclerview
Charging Animation for Android
How to Open Fragment from Recyclerview Adapter
Android Q, Programmatically Connect to Different Wifi Ap for Internet
Showing Thumbnail for Link in Whatsapp || Og:Image Meta-Tag Doesn't Work
Install_Failed_User_Restricted:Android Studio Using Redmi 4 Device
Android - Edittext Not Showing Any Text
How to Make Buttons Align At the Middle - Android Studio
Recyclerview No Adapter Attached; Skipping Layout
How to Tell If a View Is Visible on Screen in Android
Fragment Is Not Being Replaced But Put on Top of the Previous One
Android Studio 0.4.3 - Task 'Assemble' Not Found in Root Project
Converting Edittext to Int - Android
How to Convert Utc Timestamp to Device Local Time in Android
Setcontentview(R.Layout.Main); Gives Error from Start
Java.Io.Filenotfoundexception Open Failed Eacces (Permission Denied) on Device