This is happening on all of the devices we have in Indonesia.
The country codes are correct, also the display language and ISO3 seem correct:
Locale.getDefault().getISO3Country() // "IDN"
Locale.getDefault().getDisplayCountry() // "Indonesia"
Locale.getDefault().getCountry() // "ID"
Locale.getDefault().getISO3Language() // "ind"
Locale.getDefault().getDisplayLanguage() // "Bahasa Indonesia"
But the normal language code is wrong, should be "id" instead of "in". And then android is also generating the wrong language_COUNTRY identifier, should be "id_ID" instead of "in_ID":
Locale.getDefault().getLanguage() // "in"
Locale.getDefault().toString() // "in_ID"
Is this a known problem? What can we do about it?
cyanide suggests just overwriting the locale, but what about the devices who really need to use "in" and not "id", it would be the wrong one for them then?
Well, found out why it is happening, see the Android Locale Constructor Reference:
ISO 639 is not a stable standard; some of the language codes it defines (specifically "iw", "ji", and "in") have changed. This constructor accepts both the old codes ("iw", "ji", and "in") and the new codes ("he", "yi", and "id"), but all other API on Locale will return only the OLD codes.
So not much we can do, use "in" inside the app for strings, etc. and convert it to "id" (or treat in as id) when talking to outside entities like backend servers.
Check language settings on your device. If all right, then your system is dodgy, so you may try to upgrade it. As a matter of fact, configuration can be changed prorammatiically
public void updateLocale(Resources rsrc) {
Configuration conf = rsrc.getConfiguration();
Locale locale = conf.locale;
if (locale.getCountry().equals("ID") && locale.getLanguage().equals("in")) {
conf.locale = new Locale("id", "ID");
rsrc.updateConfiguration(conf, rsrc.getDisplayMetrics());
}
}
However, it isn't really advisable;
I have a same experience and I found a reference in Android Developer Site
If you want to change old language code("he", "yi", and "id") to new one("iw", "ji", and "in"), you just use this API below
//kotlin
Locale.getDefault().toLanguageTag()
Related
I have a piece of code where I'm trying to change the language in my app, using a Spinner View Component. While working with this, I've come to realize that I'm probably not using the most smooth method, but more intrestingly, I've noticed that two strings that LOOK the same are not equal when compared. Why is it like this, and how should I do if I want to "check" if the language is a certain one?
if (myLocale.toLanguageTag()=="sv")
{
//Changing language from Swedish to English
}
else
{
Toast.makeText(parent.getContext(),
myLocale.toString(), Toast.LENGTH_SHORT).show();
//Here, the toast will tell me what myLocale.toString is "sv",
//and so is myLocale.toLanguageTag(). Yet they are not equal...
}
As stated in the documentation:
Locale.toString() returns a string representation of this Locale object, consisting of language, country, variant, script, and extensions, whatever is available, as below:
language + "_" + country + "_" + (variant + "_#" | "#") + script + "-" + extensions
Language is always lower case, country is always upper case, script is always title case, and extensions are always lower case.
for example en_US, en
Whereas Locale.toLanguageTag() returns you the same stuff (language, country, and variant), but as a tag. Here Tag means some code given for language, country and variant defined by some IETF's BCP 47 standard (BCP = 'Best Current Practice').
for example en-US
The only difference I can see is the _ and - or perhaps some language/country codes too.
In nutshell, both of them return String; one returns a normal string representation of the Locale whereas the later returns a string as a well-formed IETF BCP 47 language tag representing the locale.
The documentation also suggests using toString only in debugging mode:
This behavior is designed to support debugging and to be compatible with previous uses of toString that expected language, country, and variant fields only. To represent a Locale as a String for interchange purposes, use toLanguageTag().
Hope it helps.
Use .equals() for strings comparison.
A good explanation can be found here
if ("sv".equals(myLocale.toLanguageTag()))
The app I work on will be launched in the UK, US and AU. I have strings.xml in values-en-rUS , values-en-rAU and values folders. I have certain strings for ex "Zipcode" which will only be used in the US so I have added them to strings.xml in values-en-rUS. I have "Postcode" as the equivalent in AU and UK strings.xml files.
This works fine as long as the device locale is set correctly ie, English(United states) in United states. If the device is in English (Australia) and the user is using the app in United states the solution fails.
Is there a standard approach for displaying a specific string irrespective of the device locale? Any help is appreciated
I think you are using the wrong localization.
values-en-rUS you are defining resources in english (locale en) for mobiles situated in the US region.
If you use values-en_US instead it should correctly work for the locale en_US.
To better understand how the fallback between the different locales will happen consider this link:
Android doc
The correct Java SE standard usage is:
Locale: Properties file name part:
Locale("en", "US") values_en_US
Locale("en", "AUS") values_en_AUS
Locale("en", "UK") values_en_UK
Best have a Locale("en") / values_en and values too.
There are some Locale constants. A small prototype will see whether this works satisfactory.
May i know what is the difference between Locale.getDefault().getLanguage() and mContext.getResources().getConfiguration().locale.getLanguage()
Sorry for my draft but i need a detailed distinction between them.
Locale.getDefault().getLanguage();
Returns the language name for this Locale or the empty string if no
language was set, though document states that getLanguage() returns language code but it doesn't.
getResources().getConfiguration().locale.getLanguage()
Returns the Language code.
I am trying to get the current device locale with the region like "en_us","en_gb".
I am calling Locale.getDefault().getLanguage() and it returns only the two letters code en.
Format like "en_us" or "en_gb" has "language code"_"country code"
A Locale object contains both country code and language code.
So you can use below snippet to format your own code..
String cCode = Locale.getDefault().getCountry();
String lCode = Locale.getDefault().getLanguage();
String code = lCode+"_"+cCode;
or
you can use toString() method on Locale object to get the data
String code = Locale.getDefault().toString();
The default Locale is constructed statically at runtime for your application process from the system property settings, so it will represent the Locale selected on that device when the application was launched. Typically, this is fine, but it does mean that if the user changes their Locale in settings after your application process is running, the value of getDefaultLocale() probably will not be immediately updated.
If you need to trap events like this for some reason in your application, you might instead try obtaining the Locale available from the resource Configuration object, i.e.
Locale current = getResources().getConfiguration().locale;
You may find that this value is updated more quickly after a settings change if that is necessary for your application.
i have tested this :)
i have got from this as link may be deleted so Answer copied :)
It's worth pointing out that locale codes and language tags are related but different. Locale codes have an underscore separator (e.g. fr_CA), and language tags have a dash separator (e.g. fr-ca). I'm sure there are some deeper differences but that's beyond my pay grade.
This answer gives the result of various methods on the Locale class: https://stackoverflow.com/a/23168383
It looks like you want the toString() method (to get the locale code) or the toLanguageTag() (to get the language tag).
Use
Locale.getDisplayName();
This is shorthand for
Locale.getDisplayName(Locale.getDefault());
The documentation is in here:http://developer.android.com/reference/java/util/Locale.html
In my android app I need to know which is the language of the phone in this format :fr (for francais), en (for english),etc.. How can I do this? I know that I can display language with this :
Locale.getDefault().getDisplayLanguage()
but the result is francais,english,...
Can I obtain somehow the initials of languages?
Locale.getDefault().getLanguage()
Returns the language code for this Locale or the empty string if no language was set.
http://developer.android.com/reference/java/util/Locale.html#getLanguage()
How about using
Locale.getDefault().getLanguage();
I think you can try one of these two.
Locale.getDefault().getLanguage();
This will give language iso code i.e. "de", "ru". OR
Resources.getSystem().getConfiguration().locale;
This returns global shared Resources object that provides access to only system resources.