I am trying to change my device's language in my app. I have this code:
Locale locale = new Locale("en_US");
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getApplicationContext().getResources().updateConfiguration(config, null);
Log.i("some","Well, I tried!");
But this code does not change state of my device, and in LogCat I can see "Well, I tried" message. What are the possible reasons of such strange behaviour?
Edit this line
getApplicationContext().getResources().updateConfiguration(config, null);
like this:
context.getApplicationContext().getResources().updateConfiguration(config, null);
If you came here for language problems for builds after Summer 2021, it may have nothing to do with your code. We had the same issue and the problem was the new bundle (.aab) requirement (required since Summer 2021).
With app bundles, devices download only the code and resources they require to run your app. So, for language resources, a user’s device downloads only your app’s language resources that match the one or more languages currently selected in the device’s settings.
Read further
Basically, the language file is not downloaded if the device does not support that language. There are 2 ways to solve it:
Option 1 (Easiest): Just disable the bundle optimization
Add this in your build.gradle file:
android {
bundle {
language {
enableSplit = false
}
}
// ...
// Other configuration
}
Option 2: Download the language file on demand
Use the method described here.
How to debug
Before applying these methods,
Delete the app
Add the new language in the device settings
Download the app again
If the app supports the new language then the problem is definitely the bundle optimization and the above mentioned solutions will work.
To change the applications locale manually.
You will need to set the locale using the code below.
Locale locale = new Locale("AR"); // AR here is for arabic
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config,
getBaseContext().getResources().getDisplayMetrics());
Make sure it is set in the activity "onCreate" method before calling the "setContentView" method.
Also see that the resource files are specified for the language required.
Related
I use this snippet to allow the user to set his favorite locale in the appplication:
Locale locale = new Locale(newLan);
Locale.setDefault(locale);
Configuration config = getBaseContext().getResources().getConfiguration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config,getBaseContext().getResources().getDisplayMetrics());
Problem is that I would like to write a setting that would allow the user to get back to the default langage of the phone.
How is it possible?
Because after using the snippet above and imagine user chose French, I cannot get back the phone locale (which might be english for instance)
I just tried this, my phone locale is US, the toast is shown in french but in the log I still see US, maybe if you don't set the new locale as default it works anyway?
Locale locale = new Locale("fr");
//Locale.setDefault(locale);
Configuration config = getBaseContext().getResources().getConfiguration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config,getBaseContext().getResources().getDisplayMetrics());
Toast.makeText(this, android.R.string.cancel, Toast.LENGTH_LONG).show();
Log.d("LOCALE", Locale.getDefault().getCountry());
I've seen using Locale.setDefault() in other questions and answers, now I'm wondering, why would you be required to set the default Locale manually? If that was necessary, wouldn't it be done in updateConfiguration() anyway? this answer is also interesting
How about:
Saving current locale to shared preferences
Force to whatever you want
Use the shared preferences value to move back to original locale
Firstly this bit of code config.locale = locale; is deprecated, you should use config.setLocale(locale);
Have you tried getting the current device locale with Locale.getDefault().getDisplayLanguage();, and set it once the user chooses the default locale to be the selected language of your application with your code snippet?
In https://stackoverflow.com/a/34675427/519334 I solved the issue "go back to device-languge" by remembering the device-language in a static variable before any app-changes to locale have been taken place:
public class Global {
public static final Locale systemLocale = Locale.getDefault();
}
In my project there is a option for the user to select language. The whole application should change by selecting the language. Language is fetched from the server side.
I referred various sites and links, but couldn't find a better solution. Localization is not possible, because it's a huge app and also language is not fixed , it is fetched from the server side and it can be varied.
Is any other solution is available? Please help...
You can use something like this:
Locale locale = new Locale(languageCode);
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config, null);
This will set the locale of the app to the desired one, not changing the global locale set on the device. All of the native localisation mechanisms will work with the context locale.
Although its not recommended to use separate language for your app other than the Android system's . But you can still change it .
Below is the code :
private void setLocale (String localeCode , Bundle b ){
Log.d(TAG+"set location function: "+localeCode);
locale = new Locale(localeCode);
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
getApplicationContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
UserDetail.this.getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
onCreate(null);
}
Use this method call on some user trigger:
setLocale("en-us",savedInstanceStat); // for english
setLocale("ar",savedInstanceStat); // for arabic
To learn more about android locals:
http://www.icanlocalize.com/site/tutorials/android-application-localization-tutorial/
I try to change my locale in an android application.
If I use only language all is ok, but today I added portuguese-br translation to my app.
Code:
Locale locale;
if(language.contains("-")) // In this case, the locale specify also the country
{
String[] country_locale = language.split("-");
locale = new Locale(country_locale[0], country_locale[1]);
}
else
locale = new Locale(language);
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getApplicationContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
All is ok untill last line.
I know because in a previous piece of my program i could get some string with the correct pt-br locale with this code:
Resources resources = new Resources(ctx.getAssets(), ctx.getResources().getDisplayMetrics(), new_config);
updateConfiguration set my locale to English if Locale was defined with a country code.
String.xml is in values-pt-rBR
While debugging Locale value is set to pt-BR.
EDIT: After further tests, this works on my Android phone, but doesn't work on my tablet (both Sambung with android 4.4.2).
What could be the reason?
EDIT 2: Also over the emulator work if I use a phone, not work if I use a tablet.
On your current Activity, try call the follow after your code:
finish();
startActivity(getIntent());
This will recreate your Activity and, then, reload the string resources.
In my app users have the ability to switch their app locale to one of the other app supported languages. I'm having issues getting Portuguese-Brazil and Simplified Chinese to work. All other translations work properly when the user changes the locale settings.
These translations work properly if the device locale is pt-rBR or zh-rCN so the only thing that could be wrong is the locale code I use. However, anything I've tried fails. Anybody know the proper Android locale codes for these so users can properly switch if they desire?
Use
new Locale("pt","BR");
instead of
new Locale("pt_BR");
Use following code its working for me for traditional and simplified chinese.
if(selectedLanguage.equals("zh_CN"))
locale = Locale.SIMPLIFIED_CHINESE;
else if(selectedLanguage.equals("zh_TW"))
locale = Locale.TRADITIONAL_CHINESE;
else
locale = new Locale(selectedLanguage);
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
baseContext.getResources().updateConfiguration(config, baseContext.getResources().getDisplayMetrics());
I want to test how my application looks like, and force it to load some specific language, but I don't want and don't need it in production code, so it can be some switch in eclipse or some code in onCreate.
EDIT: I don't want to manually change this, I want code what will let me to automate my tests.
I did something like this in my onCreate method:
// LOCALE
if (DEBUG == true)
{
Misc.setLocale(this, "en"); // change "en" to "fr" for french
}
And here is setLocale method:
public static void setLocale(Context context, String language)
{
final Locale locale = new Locale(language);
Locale.setDefault(locale);
final Configuration config = new Configuration();
config.locale = locale;
context.getResources().updateConfiguration(config,
context.getResources().getDisplayMetrics());
}
Now I can really fast change languages, I don't need to bother with emulator or settings in my device. I also can't forget about this, because of checking for DEBUG value.
Just change the language on your emulator. If you need to run automated tests against particular languages, just define separate AVDs configured for each language.
Any code you call is just going to force the same thing to happen as if you had changed the settings.