I create folder values-ru (for any region). But with using Ukrainian language or Belarus i have an error.
android.content.res.Resources$NotFoundException: String resource ID #0x7f0d0037
Tell me, why i got an error. Does i must create values-ru-uk and etc. for all region?
You should define all your strings in the default (source) language, regardless of what translations you're adding.
These goes in: values/strings.xml.
If this is missing (or the string is missing in that file) then I expect that's why you get an error.
You can then add as many language files as you need: e.g:
values-uk/strings.xml. (Ukrainian)
values-be/strings.xml. (Belarusian)
or specific regions thereof: e.g:
values-ru-rUA/strings.xml. (Russian in Ukraine)
Disclaimer: I'm not an Android developer, but I've written localisation software that generates strings files.
Related
I keep getting an error when creating folders for internationalization. But the errors appear just for folders with the name like values-xx_XX. If I have values-xx everything is ok, but like I asked in the title I want to make 2 separate folders for the (aprox.)the same language: values-pt_PT,values-pt_BR. How can I do that without getting any errors? Note: The error is not specified anywhere, the eclipse is just marking the folder with a red cross and doesn't allow me to run the project.
Every hint is appreciated. Thank you! :)
Use the format values-xx-rXX instead of values-xx_XX. In this instance you should use values-pt-rPT and values-pt-rBR.
See http://developer.android.com/guide/topics/resources/providing-resources.html#AlternativeResources
The language is defined by a two-letter ISO 639-1 language code,
optionally followed by a two letter ISO 3166-1-alpha-2 region code
(preceded by lowercase "r").
I haven't done it myself, but after a quick search here, I found Setting region based Local in android where they suggest using the constructor as you did:
Locale locale = new Locale("ar","SA"); //(language,country)
But also, if you wish to pass it as one parameter, you'd still leverage the lowercase "r" as in the "values" folder, like this:
Locale locale = new Locale("ar-rSA");
Hope it helps :)
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.
I have two values directories - one for English and one default.
if the resource are located in any of those folders, i can use it.
But if there is no resource in default values directory and locale is other than English, it causes ResourceNotFoundException.
I understand why this happens and why Android was built this way (to prevent ambiguous resource usage in case there are more than one non-default resource files with this resource).
But is there any way to force Android use, for example, English resource bundle if resource couldn't be found?
The only option you have is to make sure the /res/values/strings.xml file contains every string in English but you must also have /res/values-no/strings.xml which has the Norwegian strings.
If /res/values-no/strings.xml doesn't have the resource it will drop back to /res/values/strings.xml. It's the only way to do it.
I have seen several conflicting tables that show localizations and what names they should take
A lot of them suggest that there are versions of the language for each country, which is fine, for languages like English, Spanish and Chinese, where I can choose to make a values-en folder or a values-en_US folder if I want to make it more specific
but some other languages like greek have a locale name el_GR , can I just make a folder names values-el or does it HAVE to be values-el_GR
thats just an example and I don't trust the tables I have read, and the android developer guide does not nearly list the available locales
The folder name of Android string files is formatted as the following:
without region variant: values-[locale]
with region variant: values-[locale]-r[region]
For example: values-en, values-en-rGB, values-el-rGR.
In your case, you just need to create a folder values-el for the Greek translation, and values-el-rGR for the country-specific Greek translation.
Also, you can make use of the resources fallback mechanism in Android, to allow particular strings to be further translated locally.
For example, suppose you have a string called “R.string.title” and the locale is ‘el-GR’, Android will look for a value of “R.string.title” by searching the files in the following order:
res/values-el-rGR/strings.xml
res/values-el/strings.xml
res/values/strings.xml
Therefore, you can just put the country-specific translation inside the res/values-el-rGR/strings.xml, and let the res/values-el/strings.xml stores the general translations.
It can avoid duplicating your strings in different language files by utilizing this fallback mechanism.
Right click "res" folder in your project. Pick > New > Android resource file > Localization - and it will offer you all the possible Language and Locales options and even create required folders.
all can find in https://developer.android.com/index.html
in https://developer.android.com/guide/topics/resources/providing-resources.html#AlternativeResources
the page descript multiple resouce define, like drawable , value
in https://developer.android.com/training/basics/supporting-devices/languages.html
the page provide Language res define,
it‘s import How Create Locale Directories and Resource Files .
the format is <resource type>-b+<language code>[+<country code>].
and the language code country code reference https://developer.android.com/reference/java/util/Locale.html
language
ISO 639 alpha-2 or alpha-3 language code, or registered language subtags up to 8 alpha letters (for future enhancements). When a language has both an alpha-2 code and an alpha-3 code, the alpha-2 code must be used.
You can find a full list of valid language codes in the IANA Language Subtag Registry (search for "Type: language").
https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry
country (region)
ISO 3166 alpha-2 country code or UN M.49 numeric-3 area code. You can find a full list of valid country and region codes in the IANA Language Subtag Registry (search for "Type: region").
https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry
Other reference: https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
What's the meaning of attribute 'msgid' in strings.xml ?
How to get its value?
Attribute "msgid" is present in strings.xml if you are using string localization. For example, if you have alternate application strings for Spanish in the folder values-es, values.xml will contain "msgid".
When I look at the strings.xml for Spanish I see some long values like
8340973892742019101
What is interesting is that strings.xml for Italian and other languages contains the same msgid for the same string.
The only thing that comes to my mind is that it are some unique resource IDs, produced internally by the application. So, I do not think it makes sense to search for additional meaning in them. They are unique within the application, and that is only important.
These are operating system's strings and come from the com.android.support:appcompat-v7 package. You can see them defined here