The Serbian language has Latin and Cyrillic alphabets. In Android's Date and Time Picker widgets, the displayed alphabet for Serbian locales seems to be Cyrillic, as seen here.
I wanted to change the locale so that the android widgets are using the Latin Serbian alphabet.
The current language/country code (yielding Cyrillic) are sr and RS respectively. Therefore, my setLocale function is called as
setLocale("sr", "RS");
This is the part im not sure about - according to localeplanet.com, the local code for latin serbian is sr_Latn_RS. However, I tried both
setLocale("sr_Latn", "RS");
//and
setLocale("sr_Latn_RS", "RS");
neither of which work (no change occurs, default to english). According to the Android documentation, it looks like setLocale expects two letter codes.
The language codes are two-letter lowercase ISO language codes (such
as "en") as defined by ISO 639-1. The country codes are two-letter
uppercase ISO country codes (such as "US") as defined by ISO 3166-1.
The variant codes are unspecified.
So how do I specify a Latin serbian locale code? Or does it not exist?
The previous answer works well if you only support Lollipop or above. However, if you're coding in Serbian a lot of your user base probably won't have it. Here's a solution that works for old and new versions.
private static Locale serbianLatinLocale(){
Locale locale = null;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
for (Locale checkLocale : Locale.getAvailableLocales()) {
if (checkLocale.getISO3Language().equals("srp") && checkLocale.getCountry().equals("LATN") && checkLocale.getVariant().equals("")) {
locale = checkLocale;
}
}
} else {
locale = new Locale.Builder().setLanguage("sr").setRegion("RS").setScript("Latn").build();
}
return locale;
}
For getting latin locale I first used code below.
new Locale.Builder().setLanguage("sr").setRegion("RS").setScript("Latn").build();
But this solution didn't work on my Android 5.1.1 device (it was still in cyrillic). So I removed setting of region like this:
new Locale.Builder().setLanguage("sr").setScript("Latn").build();
And you have to put your string for serbian resources in b+sr+Latn folder.
Please search for your query before posting a question. It may be answered in some other related form.
Locale newLocale = new Locale("sr","RS");
Configuration config = new Configuration();
config.setLocale(newLocale);
// using this to reference my Activity
this.getBaseContext().getResources().updateConfiguration(config, this.getBaseContext().getResources().getDisplayMetrics());
i found these two answers suitable to your query
android custom date-picker SO and locale from english to french.
EDIT
Locale[] locales = Locale.getAvailableLocales();
for(Locale locale : locales){
if(locale.getCountry().equalsIgnoreCase("RS")
&& locale.getScript().equalsIgnoreCase("Latn"))
{
Configuration config = new Configuration();
config.setLocale(locale);
// using this to reference my Activity
this.getBaseContext().getResources().updateConfiguration(config, this.getBaseContext().getResources().getDisplayMetrics());
break;
}
}
I know there will be an efficient way to do it, however you may get the direction that you need to get the list of available locales and get the locale you desire. Hope it helps
EDIT-2 (Final)
you can construct the locale using:
Locale locale = new Locale.Builder().setLanguage("sr").setRegion("RS").setScript("Latn").build();
setLocale(locale);
Can you please use below one ?
public class MyApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
Resources res = this.getResources();
Configuration conf = res.getConfiguration();
boolean isLatinAlphabet = PreferenceManager.getDefaultSharedPreferences(this);
if(conf.locale.getLanguage().equals("sr") && isLatinAlphabet) {
conf.locale = new Locale("sr", "YourContryCode");
res.updateConfiguration(conf, res.getDisplayMetrics());
}
}
}
Note: Replace your YourContryCode in conf.locale = new Locale("sr", "YourContryCode"); line.
Manifest.xml:
<application
android:name=".MyApplication"
android:icon="#drawable/ic_launcher"
android:label="#string/application_name"
android:theme="#style/AppTheme">
...
</application>
Hope this will help you.
Related
My Android application supports two languages: Arabic and English. Arabic is the default language.
Now, to make Arabic as default language, i am changing my app locale to Arabic in Splash Screen. And i have maintained both English and Arabic string files for the locale change. But, when i click on some other random fragments (eg. Navigation menu item), my app static strings changes back to English locale.
I assume this is because my app default locale might have been changed to English. This issue is generated randomly, no specific scenarios are noted.
Can you suggest any solution?
Edit: I am using Shared preferences to save the language.
First step you wand to save the language in your sqlite (ex: language saved in table settings at sqlite):
mDatabase = new SqliteItemDatabase(getApplicationContext());
final List<Setting> allsettings = mDatabase.listSettings();
String the_lang = "";
if(position == 0)
{
the_lang = "en";
}
else if(position == 1)
{
the_lang = "ar";
}
LocaleHelper.setLocale(LAngSelect.this, the_lang);// =>set language
mDatabase.updateSettings(new Setting(allsettings.get(0).getId(),the_lang));
mDatabase.close();
Second step: to set activity right-to-left you want to add in every activity:
mDatabase = new SqliteItemDatabase(this);
final List<Setting> allsettings = mDatabase.listSettings();
String langs = allsettings.get(0).getLang() ;
if(langs.equals("ar")) {
//HERE CHECK CONDITION FOR YOUR LANGUAGE if it is AR then
//change if it is english then don't
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
getWindow().getDecorView().setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
//Resources res = getResources(); //resource handle
}
}
How can I get simplified chinese description (简体)? From the available locale Locale.SIMPLIFIED_CHINESE, no method seems to return this description:
getDisplayLanguage() returns the correct language name, but without the variant.
getDisplayName() returns the correct language name and country, but also without the variant.
getDisplayVariant() returns an empty string.
I've also tried to build a new Locale using the different constructors, also to no avail.
new Locale("zh", "CN");
new Locale("zh", "CN", "Hans");
I've checked the Android source code for LocalePicker and I've concluded that it is loaded from the resources (special_locale_codes and special_locale_names).
Any solutions besides having to hardcode/include this string in my resources?
Let me explain my process on how I tackled this. First, I found this block of code in LocalePicker.java
private static String getDisplayName(Locale l, String[] specialLocaleCodes, String[] specialLocaleNames) {
String code = l.toString();
for (int i = 0; i < specialLocaleCodes.length; i++) {
if (specialLocaleCodes[i].equals(code)) {
return specialLocaleNames[i];
}
}
return l.getDisplayName(l);
}
which takes in a Locale as you already know. Then it tries to find the locale code in the specialLocaleCodes string array. The specialLocaleNames you are seeking are obtained from arrays.xml as you've helpfully stated:
<string-array translatable="false" name="special_locale_codes">
<item>ar_EG</item>
<item>zh_CN</item>
<item>zh_TW</item>
</string-array>
and the corresponding languages
<string-array translatable="false" name="special_locale_names">
<item>العربية</item>
<item>中文 (简体)</item>
<item>中文 (繁體)</item>
</string-array>
Notice the code with the simplified Chinese is zh_CN and the last two characters are capitalized.
However,
Locale locale = new Locale("zh_CN");
System.out.println("Locale: " + locale);
prints
Locale: zh_cn
Notice the lower case. So there is no way specialLocaleCodes[i].equals(code) will return true. So then I poked around Locale.java and, long story short, we can bypass that case-changing jumble by doing this (and you MUST keep the 3rd parameter as an empty string for this to work):
Locale locale = new Locale("zh", "CN", "");
System.out.println("Locale: " + locale);
Prints
Locale: zh_CN
With this you should be able to do this:
Locale locale = new Locale("zh", "CN", "");
System.out.println("Name:" + locale.getDisplayName(locale));
Upon further inspection on Kitkat using this (thank you Andrew!)
int specialLocaleNamesId = Resources.getSystem().getIdentifier("special_locale_names", "array", "android");
String[] specialLocaleNames = Resources.getSystem().getStringArray(specialLocaleNamesId);
it was possible to print out
العربية,中文 (简体),中文 (繁體)
as expected. However, something in Kitkat is still preventing the correct string to display. Frustrating.
However, in Lollipop 5.0+ and Java 1.7 this works using forLanguageTag() in Locale.
Locale locale = Locale.forLanguageTag("zh-Hans");
System.out.println("getDisplayName:" + locale.getDisplayName(locale));
System.out.println("getDisplayLanguage:" + locale.getDisplayLanguage(locale));
which prints
getDisplayName:中文 (简体中文)
getDisplayLanguage:中文
You could probably access the android internal resource: com.android.internal.R.array.special_locale_names the same way it's done in LocalePicker:
final Resources resources = context.getResources();
final String[] specialLocaleNames = resources.getStringArray(com.android.internal.R.array.special_locale_names);
But it's probably safer to use your own resource here (avoiding
the use of internals)
In my app I am having an option of switching from Chinese to traditional chinese.
I am using spinner, where position 1 is chinese and 2 is traditional chinese. When position 1 is selected, here is my code which switches the language
if (pos == 0)
{
langSelected ="en";
}
else if (pos == 1)
{
langSelected ="zh";
}
else if (pos == 2)
{
langSelected ="zh-rTW";
}
Locale locale = new Locale(lang);
Locale.setDefault(locale);
android.content.res.Configuration config = new android.content.res.Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
#Override
public void onConfigurationChanged(android.content.res.Configuration newConfig)
{
super.onConfigurationChanged(newConfig);
if (locale != null){
newConfig.locale = locale;
Locale.setDefault(locale);
getBaseContext().getResources().updateConfiguration(newConfig, getBaseContext().getResources().getDisplayMetrics());
}
}
While switching from english to chinese using spinner the correct language gets loaded, but when loading traditional chinese(zh-rTW), only the chinese text gets loaded
I have my simplified chinese text in values-zh, where as I have loaded the Traditional Chinese text in values-zh-rTW
The app name differs for each language, so I also tried changing the Language from device Settings, now also in Simplified Chinese it is loading correctly but traditional Chinese not loading. But here the app name gets changed for Traditional Chinese, i.e. app name loads from values-zh-rTW
Where I am going wrong, should I have to change the folder for Traditional Chinese ?
I know it's a late post, but hope it helps someone..
The solution is to simply create a Locale using the country name. What this means is that the Locale class already has some static locale declared. For example:-
China locale - https://developer.android.com/reference/java/util/Locale.html#CHINA
Taiwan locale - https://developer.android.com/reference/java/util/Locale.html#TAIWAN
So put simply, the solution is:-
Locale locale;
if(lang.equals("zh-rTW"))
locale = Locale.TAIWAN;
else(lang.equals("zh-rCN")
locale = Locale.CHINA;
else
//handle other languages
This code changes locales of Chinese simplified and traditional:
public void setAppLocale(Context context, String languageCode, String countryCode){
Resources resources = context.getResources();
Locale locale = new Locale(languageCode, countryCode);
Locale.setDefault(locale);
Configuration configuration = new Configuration();
configuration.setLocale(locale);
resources.updateConfiguration(configuration, resources.getDisplayMetrics());
}
From my experience it is better to have values-zh-rCN for simplified Chinese and values-zh-rTW for traditional. Also, and this might be already what you are doing somewhere further in you code, changing the locale manually requires to reload the activity in order to take affect. So a simple Finish() and StartActivity() should be enough.
I wanted to make android app which supports English and Swedish. I have gone through the localization concept. But i wonted to have two buttons on click on English button should load the strings according to English and on click on Swedish button should load the Swedish strings. how can i do this?
Sv=Swedish... en=English...
enter your language code in languageToLoad :
String languageToLoad = "Sv"; // your language
Locale locale = new Locale(languageToLoad);
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config,
getBaseContext().getResources().getDisplayMetrics());
this.setContentView(R.layout.main);
Declare two buttons, one for english and another for swedish. your code for english en and for swedish sv and then you have use Localization,this way..
Locale myLocale = new Locale(lang);
Resources res = getResources();
DisplayMetrics dm = res.getDisplayMetrics();
Configuration conf = res.getConfiguration();
conf.locale = myLocale;
res.updateConfiguration(conf, dm);
check this simple example to achieve your goal.
My answer is similar to others but I have added some extras that may be important
Warning
Everything I have read says that its not a good idea to let your app change the language because it isn't supported by the Android framework and it may cause problems.
With that being said, I have done it in my app and, while it has been a bit of a pain, it seems to be working so far. Here is how I did it in case you want to do it this way. You need a separate strings.xml file for each language. strings.xml in values folder as your default then maybe a strings.xml in say a values-es folder for Spanish strings. I have used the following code to change the configuration settings depending on a radio button that the user selects
`
final Configuration LANG_CONFIG = ChooseLocale.this.getResources().getConfiguration();
Locale newLocale = new Locale("English");
curLang = ChooseLocale.this.getLanguage();
if ((curLang.equals("English")) || (curLang.equalsIgnoreCase("Ingles")))
{
newLocale = new Locale("en_US");
}
else
{
newLocale = new Locale("es");
}
Toast.makeText(getApplicationContext(), newLangToast + " " + curLang , Toast.LENGTH_SHORT).show();
Configuration config = getBaseContext().getResources().getConfiguration();
Locale.setDefault(newLocale);
config.locale = newLocale;
getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
SharedPreferences.Editor editor = langPref.edit();
editor.putString(LANG_PREF, curLang);
editor.commit();
`
With this line being the most important to update the config
getBaseContext().getResources().updateConfiguration(config,getBaseContext().getResources().getDisplayMetrics());
I get the local from my getLanguage() function which can be handled however you want. I also had to add
#Override public void onConfigurationChanged(Configuration newConfig) { newConfig = Globals.getUserLanguage(this); super.onConfigurationChanged(newConfig); to every activity that allows orientation change and add this to my onCreate() of each
final SharedPreferences langPref = getSharedPreferences (LANG_PREF, 0); if (Globals.langConfig != null) this.onConfigurationChanged(Globals.langConfig);
I also added android:configChanges="orientation|locale" to each activity in the manifest that allows orientation change. I store the users language preference in a DB that can be changed on the website or within the app. Hope this helps.
I develop finance app that should use different currency symbol which depends on the country. I'm using this code:
Float value = 100;
TextView tv = (TextView) view;
NumberFormat currencyFormat = NumberFormat.getCurrencyInstance();
tv.setText(currencyFormat.format(value));
I have several reports that my app is returning Euro symbol instead the right currency (in Malysia or India for example). Those users state that their system language is native to their country. I can't prove that myself because there are no such languages avalaible on my phone or emulator.
I suppose you could try and force a locale in your app since this seems to be related to how the default locale is being set on the device. See these links -
how to choose serbain language from android Emulator settings?
http://www.tutorialforandroid.com/2009/01/force-localize-application-on-android.html
This would probably help you replicate the issue that users reported on their devices.
EDIT:
I have not tested this myself but it could work in your case.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String languageToLoad = "en";
String countryToLoad = "MY"; // 2 digit country code for Malaysia
Locale locale = new Locale(languageToLoad, countryToLoad);
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config,
getBaseContext().getResources().getDisplayMetrics());
this.setContentView(R.layout.main);
}