I have a strings.xml question
My app is in english.
values/strings.xml is in English
there are many other languages in the app too
my latest string key additions are in values-en/strings.xml , the english locale folder , but not in values the default language folder
how will this affect a non-english user that loads a view which tries to access the strings only defined in values-en? will the OS find the string in that one file and display it in english?
this is tricky to me because it is not in the default values xml file
thanks for the insight
Imagine the strings system as a series of if conditions. First we check the language of the user, once we have that we check to see if the folder for that specific language contains the string we are looking for. If it does, we return that string, otherwise we check the "values" folder by default.
if (language.equals("en") {
stringsFolders = "values-en";
} else if (language.equals("es") {
stringsFolders = "values-es";
}
if (stringsFolder.contains(key) {
return stringsFolder.get(key);
} else if ("values".contains(key) {
return "values".get(key);
} else {
throw CantFindException();
}
If a string belongs in values-en and a spanish user looks for it, they will not have the opportunity to check the values-en folder because they don't qualify for it. Alternatively, the "values" folder is always checked by default so placing it there will work for all languages
Related
I am trying to create multilangualge app and faced with a problem! I have a string in values\strings.xml translated in German language values-de\strings.xml. I am trying to compare user input with those strings. If my input is in English and device's language is also English, everything works fine, but if I switch device's language to German and input a string in English, contains() and equals() methods will return false. Is there a way to compare strings in different languages? Thanks in advance! Also, sorry for my English!
if (mystring.contains(context.getResources().getString(R.string.testString))) {
check = true;
}
if (mystring.equals(context.getResources().getString(R.string.testString))) {
check = true;
}
In android when you call getResources() it will always get the resources of the default locale, to get one from other locales you must specify explicitly which locale you want to use, and you can find how to do it here :
https://stackoverflow.com/a/33629163/6171845
My country (Spain) has several languages (es-ES, ca-ES, gl-ES, eu-ES). We won't add all the languages for now so we would like to use main language in Spain, i.e. Spanish (es). We would like to display the /values-es/strings.xml when the user has selected one of the other languages in the country. How can we do that?
Oh, and we would like to use English as the default language (/values/strings.xml).
It would be great to have something like /values-ES/strings.xml, but I suppose that can't be done because the first code should be the language code.
Now we are copying the /values-es/strings.xml file to the other folders (values-ca, values-gl and values-eu) but we'd like to avoid that.
I think that you should have only 2 folders with 1 strings.xml for each other:
res/values/strings.xml this resource will contains your text in English ;
res/values-es/strings.xml this resource will contains your text in Spanish .
When your app is installed on a device which is configured with the Italian language, it will use the file resource on case 1.
When your app is installed on a device which is configured with a Spanish language (and there are a lot of Spanish language out there, think about South America countries), it will use the file resource on case 2.
You can do it easily with Android Studio:
right-click on res folder
go to New > Android resource directory
a window will show you some options; pick Locale and then click on the button with those symbols "> >"
then on the Language list, pick es: Spanish and then click OK, as showed in the image below (note that by default the Specific Region Only has Any Region selected!)
By experience: I never faced up a Breton, Corsican or Provençal users claiming for a full translation of the application in their language (by default the app has English as default and French).
I would say you want to do something like this.
if (Locale.getDefault().getISO3Country().equals("ESP"))
{
Locale[] locales = Locale.getAvailableLocales();
for (Locale loc : locales)
if (loc.getISO3Language().equals("SPA"))
{
Locale.setDefault(loc);
break;
}
}
Note: I'm not sure if I got the ISO3 language and country codes right. And you'll also have to do something for the (rare?) situation that the es-ES locale is not available.
If you are trying to override Catalan with Spanish, you should probably have that in the values-ca/strings.xml file.
The way to do what you are asking is to provide the resources in the appropriate mobile country code resource folder, which takes precedence over language-region resources.
Assume that you have the following situation:
The application code calls for R.string.text_a
Two relevant resource files are available:
res/values-mcc404/strings.xml, which includes text_a in the application's default language, in this case English.
res/values-hi/strings.xml, which includes text_a in Hindi.
The application is running on a device that has the following configuration:
The SIM card is connected to a mobile network in India (MCC 404).
The language is set to Hindi (hi).
Android will load text_a from res/values-mcc404/strings.xml (in English), even if the device is configured for Hindi. That is because in the resource-selection process, Android will prefer an MCC match over a language match.
The MCC for Spain is 214.
(See Localization)
I found another tricky solution: hard links. Although it doesn't remove whole problem completely, at least it protects you from routine task of copying file across multiple directories or making equal changes in all existed files with risk of miss something.
But I must admit that there is some caveats:
1) Some IDE does not support working with hard links by-default. Intellij IDEA and Android Studio will break your hard links if you don't disable "safe write" option in settings.
2) Most version control systems also doesn't support hard links by default. Let's take git for example. It will break existing hard links after reverting or merging changes.
Currently, I'm using batch file for restoring hard links after they get broken by git.
In a general term, there should be only one strings.xml file under values folder containing the relevant data.
If we explicitly specify different values folder like values-ca,values-es, whenever there are setting changes in the android device, it will look to the particular folder and take the appropriate strings value.
If the requirement is keep uniform text means better have only values->strings.xml file alone with the required data.
But with this approach multilingual apk is not possible i.e. for other country different language is expected, there will be variations again. So wherever we need uniform language, lets go with single folder alone and wherever multilingual is preferred, we can have multiple values-es,values-ca folder like that.
Hope that helps
How about trying to set it in java, instead of using strings.xml.
As doing it programatically gives you more flexibility at run-time.
Configuration config = new Configuration(getResources().getConfiguration());
Locale locale = Locale.getDefault();
String country = locale.getCountry();
String language = locale.getLanguage();
if (country.equalsIgnoreCase("ES") && (language.equalsIgnoreCase("ca") || language.equalsIgnoreCase("gl") || language.equalsIgnoreCase("eu"))) {
locale = new Locale("es");
}
config.setLocale(locale);
And then you can simply have one /values-es/strings.xml for all the ES country languages.
For e.g there is app which provides multi-language support, in my activity/UI, I call getResources().getString(R.string.hello) which exist in strings.xml,such that
values\strings.xml
values-ru\strings.xml
Now when calling getResources().getString(R.string.hello) and need to access string based on system locale, so will one get strings from values\strings.xml OR values-ru\strings.xml?
OR
does one need to change my app locale based on system locale (keep app locale same as system locale) and then retrieve the value from getString(), something suggested in below links
get-string-from-default-locale-using-string-in-specific-locale
how-to-get-string-from-different-locales-in-android
I have searched various other links, but not able to find the solution
MyProject/
res/
values/
strings.xml
values-es/
strings.xml
values-fr/
strings.xml
Add the string values for each locale into the appropriate file.
At runtime, the Android system uses the appropriate set of string resources based on the locale currently set for the user's device.
For info on Localizing with Resources
http://developer.android.com/guide/topics/resources/localization.html
More info #
http://developer.android.com/training/basics/supporting-devices/languages.html
Also check the below link
http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.3_r2.1/android/content/ContextWrapper.java/
86 #Override
87 public Resources getResources()
88 {
89 return mBase.getResources();
90 }
Return a Resources instance for your application's package.
332
333 public final String getString(int resId) {
334 return getResources().getString(resId);
335 }
Return a localized string from the application's package's default string table.
Parameters:
resId Resource id for the string
It is done automatically. By standard the language that is on is in your values\strings.xml but if the user device has his language set to ru the string automatically is the one on the values-ru\strings.xml and so on for all the languages that you put on your resources.
You can read more about this subject in here.
At runtime, the Android system uses the appropriate set of string resources based on the locale currently set for the user's device.
this is my first question :)
I'm developing an application that stores animal species in a database. The app must be multilanguage, so I tought to take advantage of using strings.xml resource files.
The idea is to store the english name of the species on the db, for example "cat", "dog" etc.. and then display to the user the actual translation, based on an xml like this (for italian):
<string name="dog">Cane</string>
<string name="cat">Gatto</string>
The problem is that R.string contains the name dog and cat, but they are actually int, so I'm searching a way to use the "dog" string to be used to compare the R.string.dog translated value.
I'm almost sure that my design is terribly wrong, but don't know what the correct way to doing this kind of work, since the app is now in a very early stage of development.
Thank you
EDIT with example
This example illustrates the problem:
Database data:
row1: id="1", value="dog"
row2: id="2", value="cat"
String file strings.xml:
<string name="dog">Dog</string>
<string name="cat">Cat</string>
String file strings-it.xml:
<string name="dog">Cane</string>
<string name="cat">Gatto</string>
My problem is: the user want to insert a specie in his native language (eg. "Cane"), and I want to search in the DB for its existence before inserting.
I should loop for every row on the DB (where values are stored in english), get the the translation of each row (eg: I found cat, then I translate to "Gatto") and compare with the user input.
Is it possible to do that?
If you have a string name you want to use, you can use getIdentifier() to get the string id. As an example, to find R.string.cat:
Resources res = getResources();
int stringId = res.getIdentifier("cat", "string", packageName);
In the above example, if there is no R.string.cat found, it will simply return 0. It's an easy test to see if a string exists.
Alternatively, you can get an array of all the string ids in your R.java by using something like:
Field[] fields = R.string.class.getFields();
int[] ids = new int[fields.length];
for(int i=0;i<field.length;i++)
ids[i] = field[i].getInt(null);
Of course, that will also look for any strings that you don't really intend as translations, such as dialog/window titles, label/button captions, etc. I wouldn't advise it in the general case. If I had to do it, I'd prefix the "translation" strings with something so I could easily tell what is what, something like "entry_cat".
Note that we're using reflection, and if you have a lot of strings, it could slow you down. If you are going to loop through R.java, I'd advise only doing it on start-up, and saving the values in some sort of array/list.
First read this.
http://developer.android.com/training/basics/supporting-devices/languages.html
You can create value folder with many language's i.e janapee,dutch etc
you can find out value folder inside the res folder in your project. and create new value folders.
res/
values/
strings.xml
values-es/
strings.xml
values-fr/
strings.xml
JUST TRANSLATE YOUR WORDS BY GOOGLE TRANSLATOR IN ANY LANGUAGE AND PUT INSIDE THE STRING.XML FILE .
Well, first of all, start reading this here:
Suppose that your application's default language is English. Suppose
also that you want to localize all the text in your application to
French, and most of the text in your application (everything except
the application's title) to Japanese. In this case, you could create
three alternative strings.xml files, each stored in a locale-specific
resource directory:
res/values/strings.xml Contains English text for all the strings that
the application uses, including text for a string named title.
res/values-fr/strings.xml Contain French text for all the strings,
including title. res/values-ja/strings.xml Contain Japanese text for
all the strings except title. If your Java code refers to
R.string.title, here is what will happen at runtime:
If the device is set to any language other than French, Android will
load title from the res/values/strings.xml file. If the device is set
to French, Android will load title from the res/values-fr/strings.xml
file. Notice that if the device is set to Japanese, Android will look
for title in the res/values-ja/strings.xml file. But because no such
string is included in that file, Android will fall back to the
default, and will load title in English from the
res/values/strings.xml file.
Hi I am trying to localize my android application and I read up on how by reading this tutorial http://developer.android.com/guide/topics/resources/localization.html but after looking through it, I couldn't figure out how to change the language. I have the default values in res/values/strings.xml and I have my other strings in res/values-latin/strings.xml. but I cant figure out how to make my application use the strings in res/values-latin/strings.xml instead of the default. Could someone explain this to me?
How about if someone clicks a change language button how could I inform the application to change all the strings?
Thank you!
Android will do it for you automatically.
When a user runs your application:
The Android system selects which resources to load, based on the
device's locale.
Example:
Suppose that your application's default language is English. Suppose also that you want to localize all the text in your application to French. In this case, you could create two alternative strings.xml files, each stored in a locale-specific resource directory:
res/values/strings.xml
Contains English text for all the strings that the application uses.
res/values-fr/strings.xml
Contain French text for all the strings.
If your Java code refers to R.string.title, here is what will happen at runtime:
If the device is set to any language other than French, Android will load English title from the res/values/strings.xml file.
If the device is set to French, Android will load French title from the res/values-fr/strings.xml file.
With latin it will not work. You should search alternative method.
My solution in java:
public final class English {
String moon = "Moon";
String earth = "Earth";
String mars = "Mars";
}
public final class Latin {
String moon = "Luna";
String earth = "Terrae";
String mars = "Mars in Latin";
}
Then in your code you can aceess them:
TextView textView = (TextView) findViewById(R.id.my_text);
textView.setText( Latin.moon );