Android 利用 ICU 库和 CLDR 项目提供 Unicode 和其他国际化支持。本页对 Unicode 和国际化支持的讨论分为两个部分:Android 6.0(API 级别 23)及更低版本,以及 Android 7.0(API 级别 24)及更高版本。
Android 6.0(API 级别 23)及更早版本的 Unicode 和国际化支持
Android 平台使用 ICU 和 CLDR 来实现各种类,以处理拉丁语和非拉丁语拼写,并公开了诸如 Locale
、Character
以及 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 级别的一些基本信息。然后,它解释了您需要了解的 ICU4J 在 Android 上的特定实现。最后,它告诉您如何在 Android 框架中使用 ICU4J API。
Android 上的 ICU4J
Android 通过 android.icu
包公开了 ICU4J API 的子集,而不是 com.ibm.icu
。Android 框架未公开某些 ICU4J API,原因包括这些 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
java
和 android
包中的某些类与 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
库公开了 ICU4C API 的子集,而不是 libicuuc.so
或 libicui18n.so
。这些 API 从 Android 12(API 级别 31)开始可用。NDK 头文件从 NDK r22b 版本开始可用。Android NDK 未公开任何 C++ API。部分 C API 不可用。
版本控制
Android 平台的后续版本对应于更新的 ICU 版本以及相应的 CLDR 和 Unicode 版本。表 3 显示了从 Android 7.0(API 级别 24)开始的这种对应关系。使用 VersionInfo.ICU_VERSION
API(自 Android 7.0 起可用)可在运行时获取 ICU 版本信息。
表 3. 从 Android 7.0(API 级别 24)到 Android 15(API 级别 35)的 Android 版本中使用的 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 - 32) | 68.2 | 38.1 | 13.0 |
Android 13(API 级别 33) | 70.1 | 40 | 14.0 |
Android 14(API 级别 34) | 72.1 | 42 | 15.0 |
Android 15(API 级别 35) | 75.1 | 45 | 15.1 |
24 小时/12 小时时间格式设置
Android 上的 ICU 不遵循从DateFormat.is24HourFormat()
获取的用户 24 小时/12 小时时间格式设置。要遵循此设置,请使用 DateFormat
或 DateUtils
时间格式化方法,或者使用带有适当小时模式符号(12 小时制为 'h',24 小时制为 'H')的 ICU 时间格式化模式,以适应不同的 is24HourFormat()
返回值。例如,此代码生成一个字符串,其中包含遵循用户 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());
Transliterator 的稳定性
从 Android 10(API 级别 29)开始,提供了Transliterator
用于将文本从一种格式音译到另一种格式。可用音译 ID 的集合在不同的 Android 版本和设备上不稳定。设备制造商可能会添加额外的音译 ID。开发者在音译文本之前必须检查从 Transliterator.getAvailableIDs()
获取的可用 ID。许可
ICU4J 根据 ICU 许可发布。有关详细信息,请参阅 ICU 用户指南。