Localization for Canada defaults to UK; should default to US

一个人想着一个人 提交于 2020-01-29 23:42:11

问题


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!


回答1:


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.

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.

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.




回答2:


  1. Should happen automatically, without you doing anything. If you have values/strings.xml, values-en-rGB/strings.xml and values-en-rCA/strings.xml with the GB and CA versions containing only those strings that differ from the baseline (values/strings.xml) and if the user has his locale as en-CA, the system will load strings from values-en-rCA/strings.xml if not found, it'll fall back to values/strings.xml, the GB version wouldn't come in the picture.

  2. For this you'll have to locally change your app locale. Basically you get the current locale, if it is fr-CA, you manually set the locale to en-CA

    Locale enCALocale = new Locale("en", "CA"); 
    Locale.setDefault(enCALocale);
    Configuration config = new Configuration();
    config.locale = enCALocale;
    getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
    

Update

As Shobhit mentioned, starting Android N, you can now have a list of locales selected in the setting and you can decide their priority:

In the above case the system will try and look for en-rCA/strings, if not found it'll look into en-rGB/strings instead of baseline, something that happened before N.



来源:https://stackoverflow.com/questions/45511769/localization-for-canada-defaults-to-uk-should-default-to-us

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!