使用区域设置来检测是否使用英制单位

时间:2011-02-04 13:01:24

标签: android localization internationalization units-of-measurement

我正在开发一款想要以厘米(cm)或英寸(“)显示长度的应用。有没有办法从语言环境中选择正确的单位?无论如何我也会去添加一个选项,以便用户可以覆盖语言环境设置。

美国,利比里亚和缅甸应使用英制单位和世界其他地区的正常单位。一种方法是在我自己的类中加入这个逻辑,但我更喜欢使用任何内置逻辑(如果可用)。有什么指针吗?

6 个答案:

答案 0 :(得分:46)

最后,我采用了以下解决方案。

public class UnitLocale {
    public static UnitLocale Imperial = new UnitLocale();
    public static UnitLocale Metric = new UnitLocale();

    public static UnitLocale getDefault() {
            return getFrom(Locale.getDefault());
    }
    public static UnitLocale getFrom(Locale locale) {
        String countryCode = locale.getCountry();
        if ("US".equals(countryCode)) return Imperial; // USA
        if ("LR".equals(countryCode)) return Imperial; // Liberia
        if ("MM".equals(countryCode)) return Imperial; // Myanmar
        return Metric;
    }
}

例如,可以这样使用它。

if (UnitLocale.getDefault() == UnitLocale.Imperial) convertToimperial();

如果还需要转换方法,最好将它们添加到UnitLocale的子类中。我只需要检测 wheter以使用英制单位并将其发送到服务器。

在java对象上使用int具有极其微小的性能提升,并使代码更难阅读。比较java中的两个引用的速度与比较两个ints的速度相当。使用对象还允许我们向UnitLocale类或子类添加方法,例如convertToMetric等。

如果您愿意,也可以使用枚举。

答案 1 :(得分:3)

  1. 编程
  2. 从@vidstige

    中对解决方案进行小幅改进

    我会使用getCountry()。toUpperCase()来保证安全,并将检查更改为交换机以获得更干净的代码。像这样:

    public static UnitLocale getFrom(Locale locale) {
        String countryCode = locale.getCountry().toUpperCase();
        switch (countryCode) {
            case "US":
            case "LR":
            case "MM":
                return Imperial;
            default:
                return Metric;
        }
    }
    
    1. 来自资源
    2. 另一种解决方案可能是为每个国家/地区创建资源文件夹,例如:[values_US] [values_LR] [values_MM],布尔资源更改为true。然后从代码中读取该布尔资源。

答案 2 :(得分:2)

只需让用户选择设置菜单中的首选单位即可。如果是旅行用户,您不希望应用程序在地理位置上识别,IMO。

答案 3 :(得分:2)

LocaleData.getMeasurementSystem在API级别28及更高版本中可用。它返回您正在寻找的信息。

答案 4 :(得分:1)

在这里基于其他不错的解决方案的基础上,您还可以将其实现为Locale对象的Kotlin扩展功能:

fun Locale.isMetric(): Boolean {
    return when (country.toUpperCase()) {
        "US", "LR", "MM" -> false
        else -> true
    }
}

这样,您只需要打电话:

val metric = Locale.getDefault().isMetric()

答案 5 :(得分:0)

这种方法或多或少是完整的。

科特琳:

private fun Locale.toUnitSystem() =
    when (country.toUpperCase()) {
        // https://en.wikipedia.org/wiki/United_States_customary_units
        // https://en.wikipedia.org/wiki/Imperial_units
        "US" -> UnitSystem.IMPERIAL_US
        // UK, Myanmar, Liberia, 
        "GB", "MM", "LR" -> UnitSystem.IMPERIAL
        else -> UnitSystem.METRIC
    }

请注意,英国和美国的帝国制之间存在差异,请参阅Wiki文章以获取更多详细信息。