App State Changes when changing language within the android app - android

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);

Related

English/Spanish App: How do I set displayed values in spanish in values-es/strings but keep the values in English for the ifs checks in the app?

I have the folder values with the strings.xml in English and values-es folder with another string.xml in spanish. I have a fragment that gets opened from the action bar to set the settings and store them in SharedPreferences, that works fine in English. I have a lot of if's in the app to check what is set on Share preferences but with the words in English and now in the strings.xml in spanish I want to do something like this to avoid changing all the ifs in the app. I tried this but it doesn't work:
<string-array name="music">
<item value="Yes">Si</item>
<item value="No">No</item>
</string-array>
Is there any way to do something similar? Basically I want the user to select "Si" on the preferences spinner but when I get the value from the spinner I want it to retrieve "Yes"
You should be using constants for the value you need to save in shared preferences that way it will be language independent.
For example if you have 2 radio buttons for music naming on and off you should create 2 constants
public static final int ON = 1;
public static final int OFF = 0;
Now on click of radio button you Should be checking id of radio button and saving appropriate constant in shared preferences:
case: R.id.radio_on
//save ON in shared preferences
break;
case: R.id.radio_off
//save OFF in shared preferences
break;
Then you can check for the constants independent of any language.
Hi please pass the value si which you want to pass to string and take the value yes from your spinner just you can try this example
http://www.androidhive.info/2014/07/android-building-multi-language-supported-app/
Basically I want the user to select "Si" on the preferences spinner
but when I get the value from the spinner I want it to retrieve "Yes"
If you are displaying the values in Splanish and for particular part of code you want to retrieve the value in English below might be the way you are looking for.
Resources res = getResources();
Configuration conf = res.getConfiguration();
Locale savedLocale = conf.locale; // Save your current locale first (Splanish in your case)
conf.locale = new Locale("es"); // Change the desired locale( English in your case)
res.updateConfiguration(conf, null);
// retrieve resources from desired locale
String str = res.getString(id);
// restore original locale
conf.locale = savedLocale;
res.updateConfiguration(conf, null);
I hope it will help.

Can you programmatically switch between xml resource files on android?

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.

Android : Setting language in app

I want to change my app language in my app because android languages don't have all languages i want to use. So i got this to change:
String languageToLoad = "en";
Locale locale = new Locale(languageToLoad);
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config,
getBaseContext().getResources().getDisplayMetrics());
However, when user opens app and change it. Then strings which is showing at that moment still are the older language it changes just when new Activity is created.
Other problem that i should somehow save what user language was select and then change language when app is started.
So how to improve this? I want that when user select language all strings would be taken from selection languages strings.xml and how to save which language user was selected?
You can use a SharedPreference to store the user's language. Here's the documentation about it: http://developer.android.com/reference/android/content/SharedPreferences.html
About the need to reload the Activity, you may find some answers here: Android: locale(system Language) change effect my application layouts
You can create a public class (public class Share) with static members like public static String language = "en"; You can easily access the fields of this class with using the code as Share.language in whole of your project. If you want to change the language you can set Share.language = "fa";. To reload the activity with selected language, you should place the following code before any activitie's super.onCreate(saveInstanceState); :
Locale l = new Locale(Shares.language);
Locale.setDefault(l);
Configuration config = new Configuration();
config.locale = l;
context.getApplicationContext().getResources()
.updateConfiguration(config, null);
Please note that, language can be set, if you have a folder like values-language in your /res folder.
Good luck, Hossein :)

Changing strings.xml on the fly

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.

Get string from default locale using string in specific locale

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.

Categories

Resources