將應用程式本地化

Android 作業系統在許多地區和裝置上都相當普及;為了盡可能觸及最多使用者,請確保應用程式能以適合在地使用者的方式處理文字、音訊檔案、數字、貨幣和圖形。

本頁會介紹將 Android 應用程式本地化的最佳做法。

您必須具備 Kotlin 或 Java 程式設計的工作知識 並且熟悉 Android 資源載入在 XML 中宣告使用者介面元素 這些開發重點 活動生命週期、 以及國際化和本地化的一般原則

建議您使用 Android 資源架構,盡可能區分應用程式的本地化功能與核心應用程式功能:

  • 請依照本頁和「應用程式資源總覽」中所述,將應用程式使用者介面的大部分或全部「內容」放入資源檔案中。
  • 另一方面,使用者介面的「行為」是由以 Kotlin 或 Java 為基礎的程式碼所驅動。舉例來說,如果使用者輸入的資料須依語言代碼而有不同的格式設定或排序,那麼請使用 Kotlin 或 Java 程式設計語言,透過程式輔助的方法處理資料。本頁內容不包括如何本地化以 Kotlin 或 Java 為基礎的程式碼。

如需本地化應用程式字串的簡易指南,請參閱「支援不同語言和文化」。

總覽:Android 中的資源切換

資源是文字字串、版面配置、音效、圖形,以及 Android 應用程式所需的任何其他靜態資料。應用程式可以包含多組資源,每組資源都針對不同的裝置設定自訂。當使用者執行應用程式時,Android 會自動選取並載入與裝置最相符的資源。

本頁內容著重於本地化和語言代碼。如需資源切換和所有可指定的設定類型 (螢幕方向、觸控螢幕類型等) 的完整說明,請參閱「提供額外資源」。

編寫應用程式時,您可建立應用程式要使用的預設和額外資源。當使用者執行應用程式時,Android 系統會根據裝置的語言代碼選取要載入的資源。如要建立資源,請將檔案放在專案 res/ 目錄的專屬名稱子目錄中。

預設資源的重要性

只要應用程式使用的語言代碼不是您提供的特定語言代碼文字,Android 就會從 res/values/strings.xml 載入預設字串。如果缺少這個預設檔案,或是缺少應用程式所需的字串,應用程式就不會執行,而且會顯示錯誤。以下範例說明預設文字檔案不完整時可能發生的情況。

範例:

應用程式以 Kotlin 或 Java 為基礎的程式碼僅參照兩個字串:text_atext_b。此應用程式包含會以英文定義 text_atext_b 的本地化資源檔案 (res/values-en/strings.xml),也包含預設的資源檔案 (res/values/strings.xml),其中含有 text_a (但沒有 text_b) 的定義:

  • 當此應用程式在語言代碼設為英文的裝置中啟動時,也許可以正常執行,這是因為 res/values-en/strings.xml 包含所需的兩個文字字串。
  • 但是,在設為使用非英文的裝置中啟動該應用程式時,使用者會看到錯誤訊息和「強制關閉」按鈕,應用程式也不會載入。

為了避免發生這種情況,請確認 res/values/strings.xml 檔案確實存在,且定義了所有必要字串。這種情況適用於所有類型的資源,並非只有字串:您需要建立一組預設資源檔案,其中包含應用程式呼叫的所有資源,例如版面配置、可繪項目或動畫。如要進一步瞭解測試,請參閱「測試預設資源」。

使用資源進行本地化

本節會說明如何建立預設資源和額外資源,也會談到如何指派資源的優先順序,以及如何在程式碼中參照資源。

建立預設資源

將應用程式的預設文字放入 res/values/strings.xml 中。這類字串應使用預設語言,也就是您預期大部分應用程式使用者都會使用的語言。

預設資源集也包含任何預設的可繪項目和版面配置,而且可納入其他類型的資源,例如動畫。這些資源位於以下目錄:

  • res/drawable/:必要目錄,至少要包含一個圖片檔讓應用程式在 Google Play 顯示圖示
  • res/layout/:必要目錄,包含定義預設版面配置的 XML 檔案
  • res/anim/:如有任何 res/anim-<qualifiers> 資料夾,則為必要目錄
  • res/xml/:如有任何 res/xml-<qualifiers> 資料夾,則為必要目錄
  • res/raw/:如有任何 res/raw-<qualifiers> 資料夾,則為必要目錄

提示:在程式碼中檢查各個 Android 資源的參照。確認每個資源都已定義預設資源。此外,請確認預設字串檔案完整:「本地化」字串檔案可以包含部分字串,但「預設」字串檔案必須包含全部。

建立額外資源

將應用程式本地化時,絕大多數都是為其他語言提供替代文字。在某些情況下,您也必須提供替代圖形、音效、版面配置和其他語言代碼特定資源。

應用程式可以指定多個 res/<qualifiers>/ 目錄,每個都有不同的限定詞。如要建立不同語言代碼的額外資源,請使用會指定語言或語言地區組合的限定詞。資源目錄的名稱必須符合「提供額外資源」中所述的命名配置,否則應用程式無法編譯。

範例:

假設應用程式的預設語言為英文,而您希望將應用程式中的所有文字翻譯成法文,並將應用程式中的大部分文字 (應用程式名稱除外) 翻譯成日文。在此情況下,您可以建立三個 strings.xml 檔案,每個檔案都儲存在特定語言代碼的資源目錄中:

  1. res/values/strings.xml
    包含應用程式所用全部字串的英文文字,包括 title 字串的文字。
  2. res/values-fr/strings.xml
    包含所有字串的法文文字,包括 title
  3. res/values-ja/strings.xml
    包含所有字串的日文文字,title「除外」。

如果以 Kotlin 或 Java 為基礎的程式碼參照 R.string.title,則執行階段會發生以下情況:

  • 如果裝置設定使用的語言不是法文,Android 就會從 res/values/strings.xml 檔案載入 title
  • 如果裝置設定使用的語言是法文,Android 會從 res/values-fr/strings.xml 檔案載入 title

如果裝置設定使用的語言是日文,Android 會在 res/values-ja/strings.xml 檔案中尋找 title。不過,由於該檔案不包含此類字串,Android 會改回使用預設設定,並從 res/values/strings.xml 檔案以英文載入 title

哪些資源的優先順序最高?

如果有多個資源檔案符合裝置的設定,Android 會根據一組規則來決定要使用的檔案。在可於資源目錄名稱中指定的限定詞中,語言代碼幾乎一律會優先處理。

範例:

假設應用程式包含一組預設的圖形和另外兩組圖形,每組都根據不同的裝置設定最佳化:

  • res/drawable/
    包含預設圖形。
  • res/drawable-small-land-stylus/
    包含為預期使用觸控筆輸入,且有橫向 QVGA 低密度螢幕的裝置使用而最佳化的圖形。
  • res/drawable-ja/
    包含為日文使用最佳化的圖形。

如果應用程式在設定為使用日文的裝置中執行,即使裝置預期會使用觸控筆輸入,且配有橫向 QVGA 低密度螢幕,Android 都會從 res/drawable-ja/ 載入圖形。

例外:在選取過程中,唯一優先順序超過語言代碼的限定詞是行動裝置國家/地區代碼 (MCC) 和行動網路識別碼 (MNC)。

範例:

假設您遇到下列情況:

  • 應用程式程式碼呼叫 R.string.text_a
  • 您有兩個相關的資源檔案可用:
    • res/values-mcc404/strings.xml,其中包含應用程式預設語言的 text_a,本例則為英文。
    • res/values-hi/strings.xml,包含印度文的 text_a
  • 應用程式在有下列設定的裝置中執行:
    • SIM 卡已連上印度的行動網路 (MCC 404)。
    • 語言已設為印度文 (hi)。

即使裝置設定為使用印度文,Android 也會從 res/values-mcc404/strings.xml 載入 text_a (英文)。這是因為在資源選取過程中,Android 會優先使用 MCC 比對,而非語言比對。

選取過程並不是每次都像上述範例所示的那樣簡單。如需更詳細的過程說明,請參閱「Android 如何尋找最相符資源。」我們會按照「應用程式資源總覽」中的優先順序逐一列出並介紹限定詞。

在程式碼中參照資源

在應用程式以 Kotlin 或 Java 為基礎的程式碼中,您可以使用語法 R.resource_type.resource_nameandroid.R.resource_type.resource_name 來參照資源。詳情請參閱「存取應用程式資源」。

管理本地化字串

本節介紹的最佳做法可讓您管理與本地化相關的字串。

將所有字串移至 strings.xml

建構應用程式時,請勿對任何字串進行硬式編碼。相反地,請在預設的 strings.xml 檔案中將所有字串宣告為資源,讓字串的更新和本地化作業變得更容易。然後您就可以輕鬆擷取及翻譯 strings.xml 檔案中的字串,也可以將這些字串反向整合至應用程式中 (使用合適的限定詞),而不用對已編譯的程式碼做出任何更動。

如果您要產生含有文字的圖片,一樣請將這些字串放入 strings.xml 中,然後在翻譯後重新產生圖片。

遵循 Android 的 UI 字串指南

設計及開發 UI 時,請務必留意您對使用者說明的方式。一般來說,請以簡潔扼要的方式提供簡短易懂的說明,並維持所有 UI 的風格一致。

請務必詳閱並遵循 Material Design 針對行文方式和用詞提供的建議,這可讓您為使用者呈現設計更完善的應用程式,並有助於使用者更快瞭解您的 UI。

除此之外,請盡量使用 Android 標準術語,例如處理應用程式列、選項選單、系統列和通知等 UI 元素時,就應遵循這個做法。正確使用 Android 術語並保持一致,可以讓翻譯作業更容易進行,進而為使用者提供更好的產品使用體驗。

為宣告的字串提供足夠的結構定義

strings.xml 檔案中宣告字串時,請務必說明結構定義,因為系統會在結構定義中使用字串。這項資訊對翻譯人員非常重要,不僅可提高翻譯品質,還能讓您以更有效率的方式管理字串。

範例如下:

<!-- The action for submitting a form. This text is on a button that can fit 30 chars -->
<string name="login_submit_button">Sign in</string>

建議提供的結構定義資訊包括:

  • 這個字串的作用是什麼?向使用者顯示的時機及位置為何?
  • 這會在版面配置的何處顯示?舉例來說,文字方塊的翻譯會比按鈕翻譯更靈活。

標記未翻譯的訊息部分

字串中往往包含不應翻譯成其他語言的文字。常見的範例包括程式碼的片段、某個值的預留位置、某個特殊符號或名稱。在準備要翻譯的字串時,請找出並標示不得翻譯的文字,這樣翻譯人員才不會變更內容。

如要標示不需翻譯的文字,請使用 <xliff:g> 預留位置標記。以下標記範例顯示文字 "%1$s" 在翻譯期間不會變更,這可避免訊息出現不完整的情況:

<string name="countdown">
  <xliff:g id="time" example="5 days">%1$s</xliff:g> until holiday
</string>

宣告預留位置標記時,請新增 ID 屬性,說明預留位置的作用。如果應用程式之後會取代預留位置值,請務必提供範例屬性,說明預計用途。

以下是其他預留位置標記的範例:

<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- Example placeholder for a special Unicode symbol -->
<string name="star_rating">Check out our 5
    <xliff:g id="star">\u2605</xliff:g>
</string>
<!-- Example placeholder for a URL -->
<string name="app_homeurl">
    Visit us at <xliff:g
    id="application_homepage">http://my/app/home.html</xliff:g>
</string>
<!-- Example placeholder for a name -->
<string name="prod_name">
    Learn more at <xliff:g id="prod_gamegroup">Game Group</xliff:g>
</string>
<!-- Example placeholder for a literal -->
<string name="promo_message">
    Please use the "<xliff:g id="promotion_code">ABCDEFG</xliff:g>" to get a discount.
</string>
...
</resources>

本地化檢查清單

如需本地化和發布 Android 應用程式的完整程序總覽,請點選這裡,瞭解如何翻譯應用程式,將內容本地化。

本地化提示

請按照下列提示將應用程式本地化。

將應用程式設計為可在任何語言代碼下運作

請不要對使用者執行應用程式時使用的裝置預設任何立場。裝置可能會搭載超出您預期的硬體,也可能會設為使用您無法測試 (甚至是您從未計劃採用) 的語言代碼。因此,設計應用程式時,請確保應用程式不論在哪一種裝置上都可以正常運作或結束運作。

重要事項:請確認應用程式內含一套完整的預設資源:包括 res/drawable/res/values/ 資料夾 (資料夾名稱不含其他額外修飾符),兩者中皆有應用程式需要的所有圖片和文字。

如果裝置設為使用不支援的語言代碼,那麼即使應用程式只缺少一個預設資源,也無法在這類裝置上執行。舉例來說,如果 res/values/strings.xml 預設檔案缺少應用程式所需的某個字串,當應用程式以不支援的語言代碼執行,並嘗試載入 res/values/strings.xml 時,使用者就會看到錯誤訊息和「強制關閉」按鈕。

詳情請參閱「測試預設資源」一節。

設計靈活的版面配置

如果您需要依照特定語言重新安排版面配置,可以針對該語言建立額外的版面配置,例如為德文版面配置使用 res/layout-de/main.xml。不過,這個做法可能會導致維護應用程式時的難度增加,因此建議您建立更具彈性的單一版面配置。

另一個常見情況是,語言對版面配置的要求有所不同。舉例來說,您可能有一份聯絡表單,其中包含應用程式以日文執行時的兩個名稱欄位,以及應用程式以其他語言執行時的三個名稱欄位。有兩種方式可以處理這種情況:

  • 根據語言建立一個可透過程式啟用/停用欄位的版面配置。
  • 在主要版面配置中納入另一個含有可變更欄位的版面配置。第二種版面配置可針對不同語言有不同的設定。

避免建立過多不必要的資源檔案和文字字串

您也許不必為應用程式中的每個資源建立特定語言代碼的額外資源。舉例來說,res/layout/main.xml 檔案中定義的版面配置可能適用於任何語言代碼,因此您不需要建立任何額外的版面配置檔案。

此外,您可能不需要為每個字串建立額外文字。舉例來說,假設:

  • 應用程式的預設語言為美式英文。應用程式使用的每一個字串,都會在 res/values/strings.xml 中定義,並使用美式英文拼字。
  • 對於少數重要的詞組,您想要提供英式英文拼字。您希望應用程式在英國的裝置上執行時,可以使用這些額外字串。

為此,請建立一個名為 res/values-en-rGB/strings.xml 的小檔案,其中僅包含當應用程式在英國執行時會使用的不同字串。對於所有其他字串,應用程式則會改回預設設定,並使用 res/values/strings.xml 中定義的值。

使用 Android Context 物件進行手動語言代碼查詢

您可以使用 Android 提供的 Context 物件查詢語言代碼,如以下範例所示:

Kotlin

val primaryLocale: Locale = context.resources.configuration.locales[0]
val locale: String = primaryLocale.displayName

Java

Locale primaryLocale = context.getResources().getConfiguration().getLocales().get(0);
String locale = primaryLocale.getDisplayName();

使用應用程式翻譯服務

應用程式翻譯服務已整合至 Play 管理中心。此服務可以讓您取得即時報價,並向翻譯公司下訂單。您可以為應用程式 UI 字串、Play 商店資訊文字、應用程式內購名稱和廣告活動文字,訂購一或多種語言的翻譯服務。

測試本地化應用程式

您可以在裝置上或使用 Android Emulator 測試本地化應用程式。請特別測試並確保應用程式已納入所有必要的預設資源。

在裝置上測試

請注意,用於測試的裝置可能與其他地區消費者所用的裝置有極大差異。您的裝置提供的語言代碼可能與其他裝置不同。此外,裝置螢幕的解析度和密度可能也不一樣,這會影響 UI 中字串和可繪項目的顯示方式。

如要變更裝置的語言代碼或語言,請使用「設定」應用程式。

在模擬器上測試

如要進一步瞭解如何使用模擬器,請參閱「在 Android Emulator 上執行應用程式」。

建立及使用自訂語言代碼

「自訂」語言代碼是 Android 系統映像檔未明確支援的語言/地區組合。您可以在模擬器中建立自訂語言代碼,測試應用程式以自訂語言代碼執行的方式。有兩種方式可以協助您測試:

  • 使用可從應用程式分頁存取的「自訂語言代碼」應用程式。建立自訂語言代碼之後,按住語言代碼名稱即可切換使用。
  • adb 殼層變更為自訂語言代碼,如下一節所述。

當您將模擬器設為使用 Android 系統映像檔中未提供的語言代碼時,系統本身會以其預設語言顯示。不過,您的應用程式會正確完成本地化。

從 ADB 殼層變更模擬器語言代碼

如要使用 adb 殼層變更模擬器中的語言代碼,請執行下列步驟:

  1. 選擇要測試的語言代碼,然後判斷其 BCP-47 語言標記,舉例來說,加拿大法文是 fr-CA
  2. 啟動模擬器。
  3. 在主機電腦的指令列殼層中執行下列指令:
    adb shell
    如果裝置已連接,請新增 -e 選項指定您要使用模擬器:
    adb -e shell
  4. adb 殼層提示 (#) 中,執行下列指令:
    setprop persist.sys.locale [BCP-47 language tag];stop;sleep 5;start
    將括號括住的部分替換為步驟 1 中的適當程式碼。

    例如,如要以加拿大法文執行測試,指令會像這樣:
    setprop persist.sys.locale fr-CA;stop;sleep 5;start

這會導致模擬器重新啟動。當主畫面再次顯示時,請重新啟動應用程式,應用程式會以新的語言代碼啟動。

測試預設資源

如要測試應用程式是否包含所需的各個字串資源,請按照下列步驟操作:

  1. 將模擬器或裝置設為使用應用程式不支援的語言。舉例來說,如果應用程式在 res/values-fr/ 中有法文字串,但在 res/values-es/ 中沒有任何西班牙文字串,那麼請將模擬器的語言代碼設為西班牙文。您可以使用「自訂語言代碼」應用程式,將模擬器設為使用不支援的語言代碼。
  2. 執行應用程式。
  3. 如果應用程式顯示錯誤訊息和「強制關閉」按鈕,就表示應用程式可能在尋找無法使用的字串。請確認 res/values/strings.xml 檔案包含應用程式使用的所有字串定義。

如果測試成功,請針對其他設定類型重複執行此測試。舉例來說,如果應用程式有名為 res/layout-land/main.xml 的版面配置檔案,但沒有名為 res/layout-port/main.xml 的檔案,那麼請將模擬器或裝置設為直向,然後查看應用程式是否能夠執行。