Ok, I know title sound crazy :)
Here is what I want. My app is localized for device user but information I send back to server need to be all English. My default app locale English.
For example, I have array:
Apples
Oranges
Peaches
I have localized array:
Яблоки
Апельсины
Персики
When russian user sees list and selects couple items - I need to get corresponding english versions.
I guess my answer boils down to how to do getString() and pass locale?
Or how do I get Array in specific locale?
The code below will retrieve localized string for polish language even if the default locale on the device is different:
Configuration conf = getResources().getConfiguration();
conf.locale = new Locale("pl");
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
Resources resources = new Resources(getAssets(), metrics, conf);
/* get localized string */
String str = resources.getString(R.string.hello);
I hope this also apply to other resource types like array, so it should suffice to replace "pl" with "en"...
If you use JB 2.2.x or above (basically API >= 17) you can use createConfigurationContext do:
public String translate(Locale locale, int resId) {
Configuration config = new Configuration(context.getResources().getConfiguration());
config.setLocale(locale);
return context.createConfigurationContext(config).getText(resId);
}
This one has no side effects: API17 and higher
Configuration config = new Configuration(context.getResources().getConfiguration());
config.setLocale(locale);
return context.createConfigurationContext(config).getResources();
This "force" localization won't work if your devices doesn't have locale you're forcing.
Cannot prove this "just like this", but just now i'm struggling with such issue, where i'm forcing resource to be in locale/language witch isn't installed on device (on android 2.3.3), and still getting strings from values-en (english) resources.
On other devices, with locale you're forcing (but not necessary set as current locale), you'll get correct resources.
You have to identify the element by something else, like an id, or even the English Name.
It is not possible to get the original string for a given localized string. One of the reason is that localization of strings is not a transitive function, but there are many other reasons why this is not a good direction.
I believe, this is the safe way to go (without touching current configuration):
Configuration conf = new Configuration();
conf.setToDefaults(); // That will set conf.locale to null (current locale)
// We don't want current locale, so modify it
conf.locale = new Locale(""); // Or conf.locale = Locale.ROOT for API 9+
// or conf.setLocale(Locale.ROOT) for API 14+
// Since we need only strings, we can safely set metrics to null
Resources rsrcDflt = new Resources(getAssets(), null, conf);
String apples = srcDflt.getString(R.string.apples); // Got it at last!
I had the same issue with ListPreference that saved "state name" and "body figure" preferences.
The ListPreference gets its values and entries from an array saved in the localized "values" folders.
The list values were the same (english) but the entries were localized (english and hebrew).
I finally used the following code:
public void OnSharedPreferenceChanged (SharedPreferences sharedPreferences, String key)
{
SharedPreferences.Editor editor = sharedPreferences.edit();
Preference pref = settings.findPreference(key);
pref.setSummary(sharedPreferences.getString(key, ""));
if (key.equalsIgnoreCase(PREF_STATE)
|| key.equalsIgnoreCase(PREF_BODY_FIGURE))
{
editor.putString(key, ((ListPreference) pref).getValue());
editor.commit();
}
}
That way the preference always showed the localized string to the user (as the summary) but saved the English string in the preference memory which was ultimately sent to the server.
I combined the two approaches necessary to work on all Android versions. See my answer here.
Related
We are using a total of 6 languages inside our android app, which user can choose from. We are setting the locale programmatically. The languages are
English, Hindi, Tamil, Telegu, Kannada, Malayalam, Marathi.
Using the code below we change the app's language.
locale = new Locale(lang);
Locale.setDefault(locale);
Configuration conf = new Configuration(config);
conf.locale = locale;
getApplicationContext().getResources().updateConfiguration(conf,getBaseContext().getResources().getDisplayMetrics());
When we change the language between Hindi and English app is able to get the data from shared preferences, but for the other languages, it returns null for the same query. Please help
Update 1 : Following is the code to retrieve data from shared preference
SharedPreferences sharedPrefs = context.getSharedPreferences(context.getString(R.string.shared_prefs_key), Context.MODE_PRIVATE);
String value = sharedPrefs.getString(key, null);
Since you are using string value to get the data from sharedpreferences R.string.shared_prefs_key that is why the issues is occurring because the key would be changing in different language string. And since the data was stored during different key, it gives null for other language keys.
Change that to a constant value like below:
SharedPreferences sharedPrefs = context.getSharedPreferences("<your key>", Context.MODE_PRIVATE);
I'm working on a app in Xamarin.Android and it has to support English and Bulgarian. Most of the text is stored in the Strings.xml in the values folder.
The English text is in the default values folder and the Bulgarian text is in values-bg.
The filename for both is String.xml, and the name of each string is the same as it's translated version.
Now how can I make it so that when i click one button it reads the strings from values-bg and when i click another it reads from the default again? Also I would like that to be so for every activity in the app.
I've been testing how to change locale programmatically, and I finally found a solution that worked for me.
As you said, you need a values folder, containing strings.xml with default values, which would be english, then a values-bg folder, with the same file but with Bulgarian translated values. It is important that strings have the same name, so you did it right.
Then, in your click event, you can add this :
var locale = new Java.Util.Locale ("bg");
Android.Content.Res.Configuration conf = Resources.Configuration;
conf.Locale = locale;
DisplayMetrics dm = Resources.DisplayMetrics;
Resources.UpdateConfiguration (conf, dm);
Recreate ();
First, that code will declare a Locale variable for "bg" locale. Then, it gets the actual configuration of the device, and apply the new Locale to it. Using UpdateConfiguration, it save the changes. The Recreate is optional, it just, as its name explains it all, recreates the current activity, which will be loaded using the new configuration, with a locale "bg" instead of whatever default locale was applied. It will now fetch strings in the values-bg folder.
NOTE : I've read in the comments of the accepted answer here that on some devices, the configuration will reset to default after some time in the app. I'm not sure why this happens, but you might want to check if the locale has been changed somehow when loading a new activity, to prevent that rollback.
Android has built in functionality to switch between resources based on a users device language (http://developer.android.com/training/basics/supporting-devices/languages.html), but is it possible to switch the resources manually?
For example if I have:
yProject/
res/
values/
strings.xml
values-es/
strings.xml
values-fr/
strings.xml
Can I change which string file is used based on the users preference rather than their device language? So someone using a french language device can choose to use the English text if they want?
I know I can do it with string variables in my code rather than using the xml, but I feel the xml would be neater.
Yes you can. This is a copy/paste from a project doing so, based on user preference, to be put in onCreate():
Resources res = getResources();
Configuration conf = res.getConfiguration();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
String def = Locale.getDefault().getDisplayLanguage();
String lang = prefs.getString("LANGUAGE", def);
conf.locale = new Locale(lang);
Log.v("myapp", lang+" = "+conf.locale+" = "+conf.locale.getDisplayName());
res.updateConfiguration(conf, res.getDisplayMetrics());
By setting a user preference named LANGUAGE to the two-letter code of the desired language, and then restarting the Activity, you manually override set the language. By removing the preference you get the system default.
I wanna develop android application for different types of languages. So I have used localization for it. For that I have created different values folder like values-fr, values-ja , values-de. N also created strings.xml with static value according to that values folder. So All is good. But now my question is that I wanna change UI text according to user's selection of language. So How can I manually get particular string values from values->string.xml for particular language???
I think it may be easy, But I have no idea.
Thanks,
Locale locale = new Locale("cn");
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
http://developer.android.com/guide/topics/resources/localization.html
You just need to get the String from the file like this way
String string = getString(R.string.hello);
Android will choose the folder based on the mobile locale. See this link for further information about Android localization.
http://developer.android.com/guide/topics/resources/localization.html
And this one for String resources if you still have some doubts on how to acces the strings.
http://developer.android.com/guide/topics/resources/string-resource.html
Hope it helps, good luck! :)
i am trying to post my question understable.
I have 2 strings.xml one is for english and another is for Indian Local Language, let it be Tamil.
I have kept the meanings of all the attributes of strings.xml(english) in my tamil strings.xml
Initially my application will load english strings.xml (as normal)
I have button somewhere which should be used to change the language (tamil in this case)
Upon clicking that - my whole app should be reading my tamil strings.xml ..
I know below code only works for default LOCALE
Resources res = getResources();
DisplayMetrics dm = res.getDisplayMetrics();
Configuration conf = res.getConfiguration();
conf.locale = Locale.GERMANY;
res.updateConfiguration(conf, dm);
Can this be tweaked to read the my customized strings.xml on the fly?
Any ideas are greatly appreciated.
That is not possible. It's only possible to change the language of your phone and than you will change the language for your app.
why don't you make a settings activity and in there you put an option to change the language that will transfer you user to a locale and text in the settings page on phone?
Tell me if you need a code or something like that.
Do you mean you want to change your language on demand from English to Tamil within your app?
I call this method in my activity onCreate:
public void setupLocale(Activity c, String NewLocale) {
Resources res = c.getBaseContext().getResources();
Configuration newConfig = new Configuration(res.getConfiguration());
newConfig.locale = new Locale(NewLocale);
res.updateConfiguration(newConfig, null);
}
Where c is my activity and NewLocale is the locale string I want to use. e.g "fr" for french, "da" for Danish. Don't know what Tamil is but you probably do.