Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

android - Localization for Canada defaults to UK; should default to US

I'm working on an application that has localized strings for the UK, specified in res/values-en-rGB/strings.xml. My default string implementations, for the US, are in res/values/strings.xml.

Now, I'm adding additional localizations for Canada in res/values-en-rCA/strings.xml. I would like the application to behave as follows: If a user's device is localized to Canada (or their language is set to English(Canada) or French(Canada)), check if we have a string in en-rCA, and if not, fallback to the string in my default strings.xml file. However, my application currently fallbacks to strings from en-rGB when the device is set to a Canadian locale and the string is not found in en-rCA. Therefore, I have two questions:

  1. How can I configure my app such that a device with a Canadian locale searches for a string in en-rCA and then, if it cannot find it, defaults to the string in my default values folder rather than en-rGB?

  2. How can I ensure that a device whose language is set to French (Canada) defaults to en-rCA rather than my default values, as it currently does?

I would be happy to provide an example if it would be helpful. Thanks!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Finale Update:

After opening a bug report on Google Incorrect resource resolution strategy above Android N, defaulting to en_GB and not default strings.xml, they mentioned that this in the intended behaviour for Android N above. en_UK is considered "a representative of International English". The strings will fall back to "International English" strings or its representative before going to default en strings. I'm quoting their reply here:

Starting in N, all English locales (except for US and US territories like Puerto Rico and American Samoa) fall back to some International English variant if such a locale is available.

So for en-CA, we would try these locales first, before falling back on en-GB (which is considered a representative of International English if there is no better International English locale): en-rCA (Canadian English), b+en+001 (International English), en (English). If you don't want en-GB strings to be picked up for en-CA, you should put resources in one of those three directories, as they would be considered a better match for en-CA.


Update 1:

It seems this is not just limited to en_CA. There is another similar question for other English locales : Android 7.0 Nougat picks up default strings when device language is en_US. Looks like a platform bug at this stage.


Original Answer:

Not sure if its a bug or a feature. From API level 24 (Android 7.0), they've updated how Android resolves strings as mentioned Improvements to Resource-Resolution Strategy . Taking an example from the documentation below:

Before Android 7.0:

Lets say if the user has settings of fr_CH and following are the resources available in the app i.e de_DE, es_ES, fr_FR, it_IT. For older API's before Android 7.0, Android tried to find an exact match and if an exact match isn't found it defaults to the values/strings.xml, i.e en. So for en_CA case, if a string is not found in res/values-en-rCA/strings.xml, we can expect it to default to en. Table 1. Resource resolution without an exact locale match.

After Android 7.0

However now in Android 7.0 and above, for the situation of fr_CH, it will fall back to the closest parent dialect i.e fr_FR. Table 2. An improved resolution strategy for when there is no exact locale match.

Applying the same logic to the situation of en_CA and en_GB present in the app, I'm thinking that Android thinks that en_GB is the closest dialect to en_CA and is falling back to it instead of the default en first. I am facing the issue in my app and that's the only plausible explanation I can come up with of why this issue happens only on newer API versions and not on the ones before Android N.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...