萬國碼 (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 7.0 (API 級別 24) 以上版本為目標的應用程式,Android 架構提供更全面的 Unicode 和國際化支援。本頁下一節將詳細說明這類支援。

Android 7.0 (API 級別 24) 以上版本中的 Unicode 和國際化支援

對於 Android 7.0 (API 級別 24) 以上版本,Android 平台會公開一部分的 ICU4J API,供應用程式開發人員在 android.icu 套件下使用。ICU4J 是一種開放原始碼組合,廣泛用於 Java 程式庫,為軟體應用程式提供 Unicode 和國際化支援。

ICU4J API 會使用裝置中顯示的本地化資料。因此,您不需將 ICU4J 程式庫編譯到應用程式內,而是改從架構中呼叫程式庫,便能縮減應用程式占用的空間。如果採取這種做法,建議您提供多個 APK 版本,讓執行 Android 7.0 (API 級別 24) 以下版本的使用者可下載包含 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 也會將其標示為已淘汰,但仍會繼續納入這些 API。

請注意以下幾點提醒事項:

  • 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) 開始的對應情況。使用 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 不會遵行使用者的 24 小時/12 小時時間格式設定 (從 DateFormat.is24HourFormat() 取得)。如果要採行此設定,您可以使用 DateFormatDateUtils 時間格式方法,或搭配合適的小時模式符號 (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,將文字從一種格式音譯成另一種格式。在不同的 Android 版本和裝置上,可用的音譯 ID 組合並不穩定,因為裝置製造商可能會加入額外的音譯 ID。所以,開發人員必須先檢查有哪些 ID 可用 (從 Transliterator.getAvailableIDs() 取得),之後才能音譯文字。

授權

ICU4J 是根據 ICU 授權發布。詳情請參閱 ICU 使用手冊