I used Locale.getDefault.getDisplayLanauge() to get language code, but I get "hd". I don't know what's it. I suppose it should be "en".
Could someone give me a hint why it's "hd" by default, and what does it mean?
I had the same problem. Are you making your own Android build?
It's happening, when you use the screen density as first argument of PRODUCT_LOCALES. In my product mk file the first argument of PRODUCT_LOCALES was hdpi. I moved it to the end and now everything is working fine.
You probably have the exact same problem as I had. The Android build process takes the first two letters of the first word in PRODUCT_LOCALES and stores them as default language. And if you have, like I had, hdpi Android takes "hd" as default language!
Also I found this comment in a Android makefile, which explains this problem perfectly:
Screen density is actually considered a locale (since it is taken into account
the the build-time selection of resources). The product definitions including
this file must pay attention to the fact that the first entry in the final
PRODUCT_LOCALES expansion must not be a density.
Related
The motivation of this question comes from this other question:
How do I get the current language my app is in? (Not the device's language as specified in the Settings. I want the language that Android resolved to use for my app).
This question has been asked several times on the site, but it fails to consider this corner-case:
Imagine the user has only one preferred language in his device: say German, for example.
My app two strings.xml files: The default one, and one in French (values-fr/strings.xml).
Obviously, Android will resolve to use the default strings.xml in this case.
But if I do any of the following, it will return German:
Locale.getDefault()
getResources().getConfiguration().getLocales().get(0)
getResources().getConfiguration().locale.
(And many other suggestions that I have found on the site)
And who told Android that the default strings.xml file was in German? Why did it made that assumption? The default file could be in Spanish, Italian, Polish...whatever.
Ideally, I would like a method that returns null in this case. Some method that tells me that no match was found for German and Android had to fall-back to the default strings.xml.
Does such method exist?
Put the language name in both strings.xml files. For example, as languageName.
When you get the string for R.string.languageName, it will be the language chosen by Android among the ones you support.
Those functions all return the phone's locale. They have nothing to do with resource localization. So nobody said the strings.xml file was German. The user set the phone to German, and the resource subsystem decided strings.xml was the best match for that. Basically you have the way it works backwards.
I don't think there is a way to get what you want for two reasons:
1)It's supposed to be transparent to the programmer.
2)It doesn't pick one file over the other. It picks independently for each string. So if you have a strings.xml with two strings A and B, and had a german strings file with only A, it would give you the german A and the default B.
In Android Studio 2.2.2 I have an error in AndroidManifest.xml file saying
Resources referenced from the manifest cannot vary by configuration
There is a StackOverflow question by someone else on this message but the answer only describes how to ignore it. What I want to know is what does it mean?
The line associated with the error says
android:versionName="#string/appvername"
what does the error mean and how do I prevent (not just ignore) it? What is a "configuration" in this context?
What is a "configuration" in this context?
Quoting the documentation:
You should always externalize resources such as images and strings from your application code, so that you can maintain them independently. Externalizing your resources also allows you to provide alternative resources that support specific device configurations such as different languages or screen sizes, which becomes increasingly important as more Android-powered devices become available with different configurations. In order to provide compatibility with different configurations, you must organize resources in your project's res/ directory, using various sub-directories that group resources by type and configuration.
So, a configuration is a mix of device capabilities and states that controls what resources get loaded. For example, the device locale settings determine which strings get used from your available string resources.
What I want to know is what does it mean?
Not every attribute in the manifest can be populated by a resource, because the system cannot handle varying values based on configuration.
For example, you cannot change the Java class name of an <activity> by using a string resource in android:name, with an eye towards using different Java classes with different screen sizes. While that's an interesting concept, Android is not set up to support that.
how do I prevent (not just ignore) it?
In this case, I think you are encountering an IDE bug. android:versionName should support string resources, as that is a user-facing value, and therefore you might want to translate the string. So, add tools:ignore="ManifestResource" to the <manifest> element, until the bug gets fixed.
I am a bit noob in Android and recently I found out that I can use the predefined string that Android provides as #android:string/cancel or #android:string/ok. At first I thought it was a good idea to use them because is a way to reuse code, but now I am not so sure about that.
What if somebody with a device configured with a language that I don't support install my app?
I assume that the app will use a default language, probably english, but those string from #android:string will get translated to the user's language, so he will end up with a mix of languages.
It this true? What do you think about use #android:string?
Thanks!
EDIT: Apparently my question hasn't been understood properly. I am NOT asking about how to support different languages. My question is about the convenience of use strings defined on #string:android, if it is correct to use them or can be lead to undesirable situation like a mix up of languages in the same application.
To ensure that your strings are appearing properly on devices configured with different languages, you'll want to create different values directories for different languages. For example, your default string values would be kept under values/strings.xml and French string values would be kept under values-fr/strings.xml.
The Android Developer website gives you plenty of information for supporting different languages in your application. http://developer.android.com/training/basics/supporting-devices/languages.html
The android: values (strings, icons, themes, etc.) will differ between devices and Android versions. If you want to use them, it's safest to copy them into your project. So for strings, you wouldn't have to worry about partial translation.
In the ressource folder of your app (res), ther is a folder "values" in it, and in this folder is the string ressource xml (strings.xml).
Usually, your app selects the strings from this file.
But you can add other value folders like this: Just create a new folder and name it "values-countryCode", for example "values-ch" for Switzerland ;)
Your app automaticly chooses the right string ressource, depending on your device's langague settings. If the langague of your device isn't available, it just takes the sting ressource of the default "values" folder.
A list if the country-codes is here.
Further information can be found here.
Hope I helped, and this is what you're looking for!
So I am not such a newbie in Programming, Java or Android developing, but I got a strange issue: I have made an application, quite advanced, and have it on market.
For now I have over 1000 installs and I have around 4 or 5 crash reports for a ResourceNotFoundException. The strangest thing is that the line it crashes on is on
setContentView(R.layout.some_custom_layout)
In code I am always referring to resourced by
someTxtView.setText(R.string.some_string)
So I am wondering if I used
mContext.getResources().getDrawable(mContext.getResources().getIdentifier("some_string", "string", "my.example.package"));
would the crash go away?
I was facing the same issue and I fixed it by creating Layout Folder called "layout-small".
Based on resolutions I have created only 2 folders "layout-large" and "layout-medium". But few phones are having lower resolution it doesn't find proper resources as per the resolution. Android OS renders xml resources as per resolution. It goes and find the resources in required folders.
95+ % Android phones having resolution which matches "layout-normal" folder. But still there are Phones having lower resolution. Hence this issue occurred.
For more Details : http://developer.android.com/guide/practices/screens_support.html
Hope this helps your problem.
If you are calling setContentView(R.layout.some_custom_layout) from the Activity's onCreate method, you should be good as long as your app compiles (and I assume it does).
AFAIK accessing your string resources via:
someTxtView.setText(R.string.some_string)
is not the way to go. You should be doing this:
getContext().getResources().getString(R.string.some_string)
Except
setContentView(R.layout.some_custom_layout);
try using
setContentView(yourpackagename.R.layout.some_custom_layout);
that helped me a lot of times.
I have one suggestion. Do you use in your layouts android secific resources, such as drawables or something, for example
android:backgroud="#android:drawable/some_android_drawable"
Maybe some vendors don't provide some resources with their firmware, so your app crashs.
for example this issue
someTxtView.setText(R.string.some_string)
There you set integer value to text. Its not correctly becouse it search a resousre on this value. You must write
someTextView.setText(getResources().getText(R.string.blabla));
It's good to have consistency in file names.
MyActivity.java contains the public class MyActivity
I would like the xml file with its layout to be called res/layout/MyActivity.xml
But I get an error message saying "Invalid file name: must contain only [a-z0-9_.]"
So two questions:
Why is the character set so limited (not even upper case? Come on!) - Ah - this restriction is probably in place so you will never be screwed by filesystems that don't make a distinction between upper and lower case, like Apple's HFS+ (although see Wikipedia for the gory story http://en.wikipedia.org/wiki/Comparison_of_file_systems#cite_note-note-35-77 )
Which filenames are restricted - all of res? just res/layout? res/layout plus some other folders?
Can anyone confirm 1, and give details on 2?
Thanks,
Peter
Why is the character set so limited
Because the name has to be a valid Java identifier, so you can use constants like R.layout.foo to identify the layout at runtime.
Which filenames are restricted - all
of res? just res/layout? res/layout
plus some other folders?
Anything in res/
Not sure of the reason for #1. Never seen an explanation in any readings about Resources. For #2 from my experience anything that will be used as a id in java e.g., R.drawable.marker, R.string.default_message has to follow those rules of [a-z0-9_].
When using MacOS X as a development platform, almost any developer dealing with cross platform code will sooner or later run into the issue that source code from a Linux/UNIX project cannot be built after download/checkout/clone because the project has two identically named files in a single directory that only vary in case; and on OS X that means you end up with just one file as the second one will overwrite the first one.
Of course HFS+ can be case-sensitive, but this can only be configured when you format a partition and by default all Macs come with preinstalled OS X on a preformatted partition with a case-insensitive HFS+ (as that is the default mode for HFS+). So you would first have to reformat your newly bought Mac and reinstall OS X to achieve that goal. And then be prepared for trouble as many apps rely on case-insensitivity on the Mac; a very famous example is Steam (you cannot run Steam from a case-sensitive HFS+).
And it's not just MacOS. FAT is case-insensitive and while NTFS can be case-sensitive (just like HFS+), it isn't by default. Also I think SMB isn't as per protocol spec (at least older versions). The filesystem used on CDs isn't, and so on.
So I guess to avoid any troubles straight from the beginning, Google thought it's a good idea to force files to be all lower case, in which case it doesn't matter what filesystem you are using or how it is configured. Of course, that's a bit stupid if you can still run into that issue with your source code files, however that these may be mixed case is a decision that predates Android and that has been made by Sun many years before Google even dreamed of that system.