Google 致力于为黑人社区推动种族平等。查看具体举措

Unicode 和国际化支持

Android 利用 ICU 库CLDR 项目提供 Unicode 和其他国际化支持。本文对 Unicode 和国际化支持的讨论分为两个部分:首先是 Android 6.0(API 级别 23)及更低版本,然后是 Android 7.0(API 级别 24)及更高版本。

Android 6.0(API 级别 23)及更低版本的 Unicode 和国际化支持

Android 平台使用 ICU 和 CLDR 来实现各种类,以处理拉丁文和非拉丁拼字法,提供像 LocaleCharacter 这样的类以及 java.text 的众多子类。如果应用对国际化功能的需求超出了所提供的类涵盖的范围并且以 Android 6.0(API 级别 23)及更低版本为目标平台,则必须在其 APK 中包含 ICU 库。

版本

Android 平台的后续版本对应于较新版本的 ICU(以及相应的 CLDR 和 Unicode 版本)。表 1 显示了 Android 6.0(API 级别 23)及更低版本的这种对应关系。

表 1. Android 6.0(API 级别 23)及更低版本使用的 ICU 和 CLDR 版本。

平台(API 级别) ICU CLDR Unicode
Android 1.5–2.0(API 级别 3–7) 3.8 1.5 5.0
Android 2.2(API 级别 8) 4.2 1.7 5.1
Android 2.3–3.0(API 级别 9–13) 4.4 1.8 5.2
Android 4.0(API 级别 14–15) 4.6 1.9 6.0
Android 4.1(API 级别 16–17) 4.8 2.0 6.0
Android 4.3(API 级别 18) 50 22.1 6.2
Android 4.4(API 级别 19–20) 51 23 6.2
Android 5.0(API 级别 21–22) 53 25 6.3
Android 6.0(API 级别 23) 55.1 27.0.1 7.0

以 Android 7.0(API 级别 24)或更高版本为目标平台的应用可以利用 Android 框架提供的更全面的 Unicode 和国际化支持。 本文的下一部分将详细介绍这一支持。

Android 7.0(API 级别 24)及更高版本的 Unicode 和国际化支持

从 Android 7.0(API 级别 24)开始,Android 平台通过 android.icu 软件包公开了一部分 ICU4J API 供应用开发者使用。 ICU4J 是一组广泛使用的开源 Java 库,为软件应用提供 Unicode 和国际化支持。

ICU4J API 使用设备上存在的本地化数据。因此,您不需要将 ICU4J 库编译到 APK 中,而只需在框架中调用它们,从而可以减少 APK 占用的空间。(在这种情况下,您可能需要提供多个版本的 APK,以便运行 Android 7.0(API 级别 24)以下 Android 版本的用户可以下载包含 ICU4J 库的应用版本。)

本文首先提供了支持这些库的最低 Android API 级别的一些基本信息,然后介绍了您需要了解的有关 Android 上的具体 ICU4J 实现的信息,最后说明了如何在 Android 框架中使用 ICU4J API。

Android 上的 ICU4J

Android 通过 android.icu 软件包(而不是 com.ibm.icu)公开了一部分 ICU4J API。Android 框架可能出于各种原因而选择不公开某些 ICU4J API:例如,因为 API 已弃用或未声明为“稳定”。如果 ICU 团队在未来弃用某些 API,Android 也会将其标为已弃用,但会继续将它们包含在内。

以下是一些需要注意的重要事项:

  • ICU4J Android 框架 API 不包含所有 ICU4J API。
  • NDK 不支持 Android ICU4C。
  • Android 框架中的 API 并不会取代 Android 对使用资源进行本地化的支持。
  • 在某些情况下,Android 框架支持的字符多于 ICU 库。例如,android.text 类对表情符号的支持就是这种情况。

从 com.ibm.icu 迁移到 android.icu 软件包

如果您已在应用中使用 ICU4J API,并且 android.icu API 符合您的要求,则在迁移到框架 API 时,您需要将 Java 导入从 com.ibm.icu 更改为 android.icu。然后,您可以从 APK 中移除自己的 ICU4J 文件副本。

注意:ICU4J 框架 API 使用 android.icu 命名空间,而非 com.ibm.icu。这是为了避免在包含自己的 com.ibm.icu 库的 APK 中发生命名空间冲突。

从其他 Android SDK API 迁移至 android.icu API

javaandroid 软件包中的某些类与 ICU4J 中的类等效。不过,ICU4J 对标准和语言提供的支持通常更广泛。

表 2 显示了这些等效类的一些示例,以帮助您入门:

表 2.Android 和 Java ICU4J 类

替代选项
java.lang.Character android.icu.lang.UCharacter
java.text.BreakIterator android.icu.text.BreakIterator
java.text.DecimalFormat android.icu.text.DecimalFormat
java.util.Calendar android.icu.util.Calendar
android.text.BidiFormatter android.icu.text.Bidi
android.text.format.DateFormat android.icu.text.DateFormat
android.text.format.DateUtils android.icu.text.DateFormat android.icu.text.RelativeDateTimeFormatter

版本

Android 平台的后续版本对应于较新版本的 ICU(以及相应的 CLDR 和 Unicode 版本)。表 3 显示了 Android 7.0(API 级别 24)及更高版本的这种对应关系。

表 3. Android 7.0(API 级别 24)及更高版本使用的 ICU 和 CLDR 版本。

平台(API 级别) ICU CLDR Unicode
Android 7.0 - 7.1(API 级别 24 - 25) 56 28 8.0
Android 8.0 - 8.1(API 级别 26 - 27) 58.2 30.0.3 9.0
Android 9(API 级别 28) 60.2 32.0.1 10.0
Android 10(API 级别 29) 63.2 34 11.0

24 小时/12 小时制时间格式设置

Android 上的 ICU 不遵循用户的 24 小时/12 小时制时间格式设置(从 DateFormat.is24HourFormat() 获取)。要遵循此设置,请使用 DateFormatDateUtils 时间格式化方法,或使用 ICU 时间格式设置模式,该模式会针对不同的 is24HourFormat() 返回值采用相应的小时制模式符号(“h”表示 12 小时制,“H”表示 24 小时制)。 例如,以下代码将生成一个字符串,其中包含遵循用户的 12小时/24 小时制设置的当前时间信息:

Kotlin

    val skeleton: String = if (DateFormat.is24HourFormat(context)) "Hm" else "hm"
    val formattedTime: String = android.icu.text.DateFormat.getInstanceForSkeleton(
            skeleton,
            Locale.getDefault()).format(Date()
    )
    

Java

    String skeleton = DateFormat.is24HourFormat(context) ? "Hm" : "hm";
    String formattedTime = android.icu.text.DateFormat.getInstanceForSkeleton(skeleton, Locale.getDefault()).format(new Date());
    

音译器的稳定性

Android 10(API 级别 29)及更高版本提供 Transliterator,用于将文字从一种格式音译为另一种格式。在不同的 Android 版本和设备上,可用的音译 ID 组不稳定。设备制造商可能会添加额外的音译 ID。开发者必须先检查可用的 ID(从 Transliterator.getAvailableIDs() 获得),然后在对文字进行音译。

许可

ICU4J 是根据 ICU 许可发布的。有关详情,请参阅 ICU 用户指南。