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)及更低版本为目标平台,则必须包含 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 框架可为以 Android 7.0(API 级别 24)及更高版本为目标平台的应用提供更全面的 Unicode 和国际化支持。本页的下一部分将详细介绍这一支持。

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

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

ICU4J API 使用设备上存在的本地化数据。因此,您不需要将 ICU4J 库编译到应用中,而在框架中调用它们,从而可以减少应用占用的空间。如果您这样做,则可能需要提供多个版本的 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。由于 API 已废弃或未声明为“稳定”等原因,Android 框架不会公开某些 ICU4J API。如果 ICU 团队在未来废弃某些 API,Android 也会将其标为已废弃,但会继续将它们包含在内。

以下为几点注意事项:

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

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

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

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

从其他 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 上的 ICU4C

Android 通过 libicu.so 库(而不是 libicuuc.solibicui18n.so)公开了一部分 ICU4C API。这些 API 从 Android 12(API 级别 31)开始提供。NDK 标头从 NDK 版本 r22b 开始提供。没有通过 Android NDK 公开的 C++ API。部分 C API 尚不可用。

版本控制

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
Android 11(API 级别 30) 66.1 36 13.0
Android 12(API 级别 31) 68.2 38.1 13.0

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

Android 上的 ICU 不遵循用户的 24 小时/12 小时制时间格式设置(从 DateFormat.is24HourFormat() 获取)。如要遵循此设置,请使用 DateFormatDateUtils 时间格式化方法,或使用 ICU 时间格式设置模式,该模式会针对不同的 is24HourFormat() r返回值采用相应的小时制模式符号(“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 用户指南