Android获取当前区域设置,而不是默认设置

Posted

技术标签:

【中文标题】Android获取当前区域设置,而不是默认设置【英文标题】:Android get current Locale, not default 【发布时间】:2013-01-01 14:21:28 【问题描述】:

如何在 android 中获取用户当前的语言环境?

我可以得到默认的,但这可能不是当前的正确吗?

基本上我想要来自当前语言环境的两个字母的语言代码。不是默认的。没有Locale.current()

【问题讨论】:

default() 是一个相当安全的选择,只是不要将它用于处理(就像文档说的那样)。 @A--C 用于处理? 是的,看看docs 怎么说:一些语言环境将使用',' 作为小数点和'.'用于数字分组。 所以像 parseInt() 这样的东西可能会失败。请注意,他们仍然建议使用default(),但不推荐用于可能破坏代码的内容。 【参考方案1】:

默认Locale 是在运行时根据系统属性设置为您的应用程序进程静态构造的,因此它将代表应用程序启动时在该设备上选择的Locale。通常,这很好,但这确实意味着如果用户在您的应用程序进程运行后更改其设置中的LocalegetDefaultLocale() 的值可能不会立即更新。

如果您出于某种原因需要在应用程序中捕获此类事件,则可以尝试从资源 Configuration 对象中获取可用的 Locale,即

Locale current = getResources().getConfiguration().locale;

如果您的应用程序需要更改设置,您可能会发现此值更新得更快。

【讨论】:

当您在系统中更改默认区域设置时,是否有人检查过应用程序中的默认区域设置未更改?我认为这是破坏和重新创建活动的“配置更改”之一 我测试了它,在我不断改变语言环境的同时输出两者;结果是,输出是一样的。因此 Locale.getDefault() 可以安全使用,因为它会立即更新。 Log.d("localeChange", "Default locale lang: " + Locale.getDefault().getLanguage()); Log.d("localeChange", "Config locale lang: " + getResources().getConfiguration().locale.getLanguage()); 这已在 Configuration 类中被弃用,有关此建议,请参阅最新文档:locale This field was deprecated in API level 24. Do not set or read this directly. Use getLocales() and setLocales(LocaleList). If only the primary locale is needed, getLocales().get(0) is now the preferred accessor. 他们为什么不添加一个 getFirstLocale() 方法来避免奇怪的 getLocales().get(0)? 如果要支持新旧版本的api怎么办?【参考方案2】:

Android N(Api 级别 24)更新(无警告):

   Locale getCurrentLocale(Context context)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
            return context.getResources().getConfiguration().getLocales().get(0);
         else
            //noinspection deprecation
            return context.getResources().getConfiguration().locale;
        
    

【讨论】:

支持库中有什么东西可以避免 if-else 吗? @TargetApi(Build.VERSION_CODES.N) 如果包含 if 和回退代码,则代码中不需要 如果用户安装了多种语言,这可能不起作用。您应该使用LocaleList.getDefault().get(0);,因为这将返回按首选语言排序的区域设置。 @FedericoPonzi @for3st 我在ConfigurationCompat 中找到了这个,ConfigurationCompat.getLocales(getResources().getConfiguration()).get(0) 为什么不直接使用Locale.getDefault()【参考方案3】:

如果您使用的是 Android 支持库,则可以使用 ConfigurationCompat 而不是 @Makalele 的方法来消除弃用警告:

Locale current = ConfigurationCompat.getLocales(getResources().getConfiguration()).get(0);

或在 Kotlin 中:

val currentLocale = ConfigurationCompat.getLocales(resources.configuration)[0]

【讨论】:

如果您没有任何上下文,您也可以这样做ConfigurationCompat.getLocales(Resources.getSystem().getConfiguration()).get(0); @QuentinG。可以,但在这种情况下最好使用Application 上下文。 所以要明确一点,这不会返回默认语言环境,而是用户首选语言环境?【参考方案4】:

来自getDefault 的文档:

返回用户的首选语言环境。这可能已被 setDefault(Locale) 覆盖。

同样来自Locale 文档:

默认区域设置适用于涉及向用户呈现数据的任务。

看来你应该只使用它。

【讨论】:

这个答案是错误的,有一个默认的语言环境,但如果用户在飞行中更改它,它会显示错误。下一个答案是正确的 同意,错误的答案。就我而言,我正在寻找一种不必使用 getResources() 的方法,这意味着我需要一个上下文。我的问题是一个没有上下文的助手类,但我想我必须把它传递进去。如果你有一个应用程序可以让人们改变他们的语言环境并让视图的字符串、数字格式等发生变化,那么你需要使用 Devunwired 的回复 为我工作。如果我在Locale.setDefault() 设置断点,那么当我将设备语言至少改回 Android 5.0 时会调用它(就我测试而言)【参考方案5】:

以上所有答案 - 无效。 所以我在这里放一个适用于 4 和 9 android 的函数

private String getCurrentLanguage()
   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
      return LocaleList.getDefault().get(0).getLanguage();
    else
      return Locale.getDefault().getLanguage();
   

【讨论】:

在设备级别返回用户首选语言方向的少数答案之一。如果您使用 AndroidX,也可以使用LocaleListCompat.getDefault()【参考方案6】:

根据官方documentation ConfigurationCompat 在支持库中已弃用

可以考虑使用

LocaleListCompat.getDefault()[0].toLanguageTag() 第 0 个位置将是用户首选的语言环境

要在第 0 位获得默认语言环境将是 LocaleListCompat.getAdjustedDefault()

【讨论】:

是的,但是还没换成androidx ConfigurationCompat版本,见developer.android.com/reference/androidx/core/os/… 正确,可能是因为androidx迁移才提到的【参考方案7】:

我用过这个:

String currentLanguage = Locale.getDefault().getDisplayLanguage();
if (currentLanguage.toLowerCase().contains("en")) 
   //do something

【讨论】:

注意:ISO 639 不是一个稳定的标准——一些语言的代码已经改变。 Locale 的构造函数识别代码已更改的语言的新代码和旧代码,但此函数始终返回旧代码。如果要检查代码已更改的特定语言,请不要执行 if (locale.getLanguage().equals("he")) // BAD! 而是执行 if (locale.getLanguage().equals(new Locale("he").getLanguage())) 有关@Ari 描述的更多信息,请参阅此链接:developer.android.com/reference/java/util/Locale#getLanguage()【参考方案8】:

目前,我们可以使用ConfigurationCompat 类来避免警告和不必要的样板。

Locale current = ConfigurationCompat.getLocales(getResources().getConfiguration()).get(0);

【讨论】:

以上是关于Android获取当前区域设置,而不是默认设置的主要内容,如果未能解决你的问题,请参考以下文章

获取以美元为单位的 SKProduct 价格,而不是商店区域设置价格

如何将 Android M 默认 USB 配置设置为 MTP 而不是“仅充电”?

获取特定语言环境的本地化字符串

区域设置:应用程序的当前语言

如何在 C# 中获取当前的区域设置?

android中的Listview设置刷新时,Item是当前的Item,而不是第一个Item