我的应用程序(Java 11,最小值:API 29,目标:API 30 = Android 11)目前支持两种语言:德语(默认)和英语
“build.gradle(Module:app)”文件包含resConfigs("de", "en")
,并且有两个包含翻译的strings.xml
文件。
根据官方文档,Locale.getDefault()
应该返回:
此Java虚拟机示例的指定类别的默认区域设置的当前值。
如果我理解正确,那么这就是应用程序当前使用的Locale
。getLocales()
的文档只说:
获取语言环境列表。这是获取语言环境的首选方式(而不是使用直接访问器来访问语言环境,因为它只提供主要语言环境)。
.但根据多线程,这个函数也应该返回应用程序当前使用的Locale
。我想知道这是哪种语言,所以我用下面的print做了一些测试:
Log.d(TAG,"1="+Locale.getDefault()+", 2="+getResources().getConfiguration().getLocales().get(0));
字符串
- 将模拟器设置为“English(US)”->正确选择英语,打印“1=en_US,2=en_US”
- 德语(CH)->德语选择正确,打印“1=de_CH,2=de_CH”
- 德语+英语(美国)->德语选择正确,打印“1=de_CH,2=de_CH”
- 丹麦语+德语(CH)->德语选择正确,打印“1=de_CH,2=de_CH”
- 丹麦语+英语(美国)->英语选择正确,打印“1=en_US,2=en_US”
- 正确选择丹麦语+意大利语->德语,打印“1=da_DK,2=da_DK”
- 意大利语+西班牙语->德语选择正确,打印“1=in_IT,2=in_IT”
看起来它们要么设置为应用支持的语言,要么设置为用户在Android设置中选择的语言,或者如果应用不支持它们,则设置为用户选择的第一种语言。
我的应用程序有一个微调器,可以更改语言。调用例如Locale.setDefault(Locale.English)
将所有内容切换为英语,但如果我从第一个Activity切换到第二个Activity,则此值将重置。例如:
德语+英语(美国)->德语自动选择(打印“1=de_CH,2=de_CH”)->切换到英语-> UI元素也切换->切换活动->在onCreateView
中打印“1=de_CH,2=en”,而所有UI元素都是英语;使用丹麦语+意大利语时,它打印“1=da_DK,2=en”
我知道getResources().getConfiguration().getLocales().get(0)
需要调用onConfigurationChanged
才能更改,而Locale.setDefault()
会立即应用更改,但为什么后者会突然重置?为什么我得到的是我在测试中得到的结果,而不是目前使用的Locale
?如何获得应用程序实际使用的Locale
的可靠结果(不可能只是this,对吧?)
或者更好:这两个函数实际上是如何工作的?它们只是有缺陷吗?
文档没有提到任何这一点,但只有如何Locale
选择应用程序启动(here)和latest changes的语言偏好只适用于Android 13+。
1条答案
按热度按时间xlpyo6sf1#
我用我的语言
Spinner
做了一些测试(第一个练习中的菜单):A.
Locale.getDefault()
返回应用选择使用的设备语言,每次切换Activity时都会重置(如果在片段之间切换,它似乎不会改变!)。在我的测试中,Locale.setDefault
不会影响任何TextView
s,EditText
s或其他UI元素(除了:见下文)。B.
getResources().getConfiguration().getLocales().get(0)
返回相同的语言,但您使用onConfigurationChanged
应用的更改“粘滞”,即使在切换活动之后。它至少影响TextView
s、EditText
s、Switch
es和Button
s(同样,请参见下文),但是只有在膨胀视图之前调用它、在膨胀视图之后刷新视图或者覆盖onConfigureChanged
时,更改才会应用。听起来很简单,但事实并非如此。让我们看一个例子,让我们在等式中添加
DatePicker
和TimePicker
(在活动2中):onConfigurationChanged
)。A和B都打印“de_CH”。TextView
s都是德语,但DatePicker和TimePicker仍然是英语。要更改两个pickers的语言,您必须在
onCreateView
的开始处使用A(例如Locale.setDefault(getResources().getConfiguration().getLocales().get(0))
-看起来很容易,但还有另一个问题,见下文),甚至在膨胀视图之前,在调用例如datePicker = view.findViewById(R.id.datePicker)
之前。之后A和B都再次打印“de_CH”,pickers是德语的。如果Android设备被设置为丹麦语+英语,这也会以同样的方式工作:英语会自动选择,即使在第二个Activity中,B也会记得切换到德语。
我还没有能够让它完全工作与
DatePickerDialog
,但这是一个different problem。回到另一个更复杂的例子:丹麦语+意大利语
应用程序以德语正确启动,A和B都打印“da_DK”。在不使用微调器更改应用程序内的语言的情况下,Activity 2中的拾取器现在是丹麦语。如果我在切换Activity之前通过菜单更改语言,那么拾取器将使用所选的正确语言(因为微调器将B设置为特定语言,B记住了它)。
从这里拿走什么:
不要依赖A或B,除非你能绝对确定用户的手机使用至少一种你的应用支持的语言。可悲的是,似乎真的最好只使用建议的解决方案here:将包含该特定语言代码的键值对添加到本地化文件中,在应用程序启动后检查它,然后为该语言设置
Locale
,手动更改和更新它,在活动之间传递它,并在需要时使用它(例如,对于DatePicker)。