Android 系统运行在不同区域的多种设备上。为了覆盖尽可能多的用户,请确保您的应用能够以适合其使用地区的方式处理文本、音频文件、数字、货币和图形。
本页面介绍了本地化 Android 应用的最佳实践。
您需要具备 Kotlin 的实践知识,并熟悉 Android 资源加载、诸如 Activity 生命周期之类的开发注意事项,以及国际化和本地化的一般原则。
最佳实践是使用 Android 资源框架,尽可能地将应用的本地化部分与核心应用功能分离。
请将应用用户界面的大部分或全部内容放入资源文件中,如本页面以及 应用资源概览 中所述。
另一方面,用户界面的行为则由基于 Kotlin 的代码驱动。例如,如果用户输入的数据需要根据语言区域以不同方式进行格式化或排序,则您可以使用 Kotlin 以编程方式处理这些数据。本页面不涵盖如何本地化基于 Kotlin 的代码。
本指南涵盖了所有 Android 应用通用的核心 Android 本地化系统。要了解如何在 Jetpack Compose UI 中加载这些本地化资源,请参阅 Compose 中的资源。
有关本地化应用中字符串的简短指南,请参阅 支持不同的语言和文化。
概览:Android 中的资源切换
资源是指 Android 应用所需的文本字符串、声音、图形以及任何其他静态数据。应用可以包含多组资源,每组资源都针对不同的设备配置进行了自定义。当用户运行应用时,Android 会自动选择并加载最匹配该设备的资源。
本页面侧重于本地化和语言区域 (locale)。有关资源切换的完整说明以及您可以指定的各种配置类型(例如屏幕方向或触摸屏类型),请参阅 提供备用资源。
在编写应用时,您需要创建默认资源和备用资源供应用使用。当用户运行应用时,Android 系统会根据设备的语言区域选择要加载的资源。要创建资源,您需要将文件放入项目 res/ 目录下专门命名的子目录中。
为什么默认资源很重要
当应用在任何您未提供特定语言文本的地区运行时,Android 会从 res/values/strings.xml 加载默认字符串。如果缺少此默认文件,或者缺少应用所需的某个字符串,则应用无法运行并会显示错误。以下示例说明了当默认文本文件不完整时可能发生的情况。
示例
应用的 Kotlin 代码仅引用了两个字符串:text_a 和 text_b。应用包含一个本地化资源文件 (res/values-en/strings.xml),其中定义了英语的 text_a 和 text_b。应用还包含一个默认资源文件 (res/values/strings.xml),其中包含了对 text_a 的定义,但没有 text_b 的定义。
当此应用在语言区域设置为英语的设备上启动时,应用可能会正常运行,因为 res/values-en/strings.xml 包含了这两个所需的文本字符串。
然而,当此应用在英语以外的语言设备上启动时,用户会看到一条错误消息和一个强制关闭按钮。应用无法加载。
为了防止这种情况,请确保存在 res/values/strings.xml 文件,并且它定义了所有需要的字符串。这种情况适用于所有类型的资源,而不仅仅是字符串:您需要创建一组包含应用调用的所有资源的默认资源文件,例如可绘制对象 (drawables)、字体或颜色。有关测试的信息,请参阅 测试默认资源 部分。
使用资源进行本地化
本节讨论如何创建默认资源和备用资源。它还解释了资源如何分配优先级以及如何在代码中引用资源。
创建默认资源
将应用的默认文本放在 res/values/strings.xml 中。对于这些字符串,请使用默认语言(您期望大多数应用用户所使用的语言)。
默认资源集还包括任何默认的可绘制对象,并可包含其他类型的资源,例如图标或字符串。这些资源放在以下目录中:
res/drawable/:必需目录,至少包含一个图形文件,用于应用在 Google Play 上的图标。
res/xml/:如果您有任何 res/xml-
res/raw/:如果您有任何 res/raw-
提示:在代码中,检查对 Android 资源的每个引用。确保每个引用都有定义的默认资源。还要确保默认字符串文件是完整的:本地化字符串文件可以仅包含字符串的子集,但默认字符串文件必须包含所有字符串。
创建备用资源
本地化应用的一大部分工作是为不同的语言提供备用文本。在某些情况下,您还需要提供备用的图形、声音和其他特定于区域的资源。
应用可以指定许多 res/
示例
假设您的应用默认语言是英语,并且您想将应用中的所有文本本地化为法语,将除应用标题之外的所有文本本地化为日语。在这种情况下,您需要创建三个 strings.xml 文件,每个文件存储在特定于区域的资源目录中:
res/values/strings.xml包含应用使用的所有字符串的英文文本,包括名为 title 的字符串文本。
res/values-fr/strings.xml包含所有字符串的法文文本,包括 title。
res/values-ja/strings.xml包含除 title 之外的所有字符串的日文文本。
如果您的 Kotlin 代码引用了 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/包含针对日语环境优化的图形。
如果应用在设置为日语的设备上运行,Android 会从 res/drawable-ja/ 加载图形,即使该设备恰好是需要手写笔输入且具有 QVGA 低密度横向屏幕的设备。
例外:在选择过程中,唯一比语言区域具有更高优先级的限定符是移动国家码 (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 代码中,您可以使用 R.resource_type.resource_name 或 android.R.resource_type.resource_name 的语法引用资源。更多信息,请参阅 访问应用资源。
管理本地化字符串
本节介绍了管理与本地化相关的字符串的最佳实践。
将所有字符串移至 strings.xml
在构建应用时,不要硬编码任何字符串。相反,应将所有字符串声明为默认 strings.xml 文件中的资源,这使得更新和本地化变得容易。strings.xml 文件中的字符串可以轻松提取、翻译并添加适当的限定符后集成回应用,而无需更改编译后的代码。
例如,在 Compose 中,您可以这样加载字符串:
// In the res/values/strings.xml file
//
// In your Compose code
Text(
text = stringResource(R.string.compose)
)ResourcesSnippets.kt
如果您生成的图像中包含文本,请也将这些字符串放入 strings.xml 中,并在翻译后重新生成图像。
遵循 Android UI 字符串准则
在设计和开发 UI 时,请密切注意与用户的沟通方式。通常,使用简洁友好的风格,并在整个 UI 中保持一致。
请务必阅读并遵循 Material Design 关于 写作风格和措辞选择 的建议。这样做能让您的应用在用户眼中更显精致,并帮助用户更快地理解您的 UI。
此外,尽可能始终使用 Android 标准术语,例如应用栏、选项菜单、系统栏和通知等 UI 元素。正确且一致地使用 Android 术语使翻译更容易,并为用户带来更好的最终产品。
为声明的字符串提供足够的上下文
在 strings.xml 文件中声明字符串时,请务必描述该字符串的使用环境。此信息对译者来说非常有价值,能带来更高质量的翻译,也有助于您更有效地管理字符串。
以下是一个示例:
考虑提供如下上下文信息:
这个字符串的用途是什么?它在何时何地呈现给用户?
它在 UI 的什么位置?例如,按钮中的翻译比文本框中的翻译灵活性要低。
标记不需要翻译的消息部分
通常,字符串包含不打算翻译成其他语言的文本。常见的例子包括一段代码、值的占位符、特殊符号或名称。在准备翻译字符串时,请查找并标记必须保持原样的文本,以免译者对其进行更改。
要标记不需要翻译的文本,请使用
声明占位符标签时,请添加一个 ID 属性来解释占位符的用途。如果您的应用稍后会替换占位符值,请务必提供一个示例属性来阐明预期的用法。
以下是占位符标签的更多示例:
Visit us at id="application_homepage">http://my/app/home.html
Learn more at
Please use the "
...
本地化清单
有关本地化和分发 Android 应用流程的完整概述,请参阅 翻译和本地化您的应用。
本地化提示
在本地化应用时遵循以下提示。
设计您的应用以在任何语言区域运行
不要对用户运行您应用设备的任何情况做出假设。设备可能具有您未预料到的硬件,或者设置为您未计划或无法测试的语言区域。请设计您的应用,使其无论在什么设备上运行,都能正常运行或优雅地失败。
重要:确保您的应用包含一套完整的默认资源:包含 res/drawable/ 和 res/values/ 文件夹,且文件夹名称中没有任何额外的修饰符,其中包含应用所需的所有图像和文本。
如果应用缺少哪怕一个默认资源,它在设置为不受支持的语言区域的设备上将无法运行。例如,如果默认的 res/values/strings.xml 文件缺少一个应用所需的字符串,当应用在不受支持的语言区域运行并尝试加载 res/values/strings.xml 时,用户会看到错误消息和强制关闭按钮。
有关详细信息,请参阅 测试默认资源 部分。
避免创建超出需要的资源文件和文本字符串
您可能不需要为应用中的每个资源都创建特定于区域的备用版本。例如,在 res/drawable/ 目录中定义的应用程序徽标可能适用于任何语言区域,在这种情况下无需创建任何备用图形文件。
此外,您可能不需要为每个字符串都创建备用文本。例如,假设以下情况:
应用的默认语言是美式英语。应用使用的每个字符串都在 res/values/strings.xml 中使用美式英语拼写定义。
对于一些重要的短语,您想提供英式英语拼写。您希望在英国的设备上运行应用时使用这些备用字符串。
为此,请创建一个名为 res/values-en-rGB/strings.xml 的小文件,其中仅包含应用在英国运行时不同的字符串。对于所有其他字符串,应用会回退到默认设置,并使用 res/values/strings.xml 中定义的字符串。
使用 LocalConfiguration 进行手动区域查找
您可以使用 Android 提供的 LocalConfiguration 查找语言区域,如以下示例所示:
val locale = LocalConfiguration.current.locales[0]
使用应用翻译服务
应用翻译服务已集成到 Play 管理中心中。它让您可以获得即时报价并向翻译公司下订单。您可以为应用 UI 字符串、Play 商店详情信息、内购名称和广告活动文本订购一种或多种语言的翻译。
使用 Gemini 翻译应用字符串
您可以在 Android Studio 中使用 Gemini 直接在项目中翻译应用的字符串资源。有关详细信息,请参阅 翻译和本地化您的应用。
测试本地化应用
在设备上或使用 Android 模拟器测试您的本地化应用。特别要注意测试您的应用,以确保包含所有必要的默认资源。
在设备上测试
请记住,您测试所用的设备可能与消费者在其他地方使用的设备有很大不同。您设备上可用的语言区域可能与其他设备不同。此外,设备屏幕的分辨率和密度可能不同,这可能会影响 UI 中字符串和图形的显示。
要更改设备上的语言区域或语言,请使用“设置”应用。
使用可组合预览测试
在设备上测试之前,您可以使用 Android Studio 中的 可组合预览来测试本地化的 UI,而无需部署到模拟器。要以不同语言预览您的 UI,请使用 @Preview 注解(例如 @Preview(locale = "fr"))。您还可以通过指定从右到左 (RTL) 的区域(如 @Preview(locale = "ar"))来测试 RTL 布局。
在模拟器上测试
有关使用模拟器的详细信息,请参阅 在 Android 模拟器上运行应用。
创建并使用自定义语言区域
“自定义”语言区域是 Android 系统映像未明确支持的语言或地区组合。您可以通过在模拟器中创建自定义语言区域来测试应用在自定义语言区域中的运行情况。有两种方法可以做到这一点:
使用 Custom Locale 应用,该应用可从应用标签页访问。创建自定义语言区域后,通过长按语言区域名称切换到该区域。
从 adb shell 更改为自定义语言区域,如下节所述。
当您将模拟器设置为 Android 系统映像中不可用的语言区域时,系统本身会以其默认语言显示。但是,您的应用会正确地进行本地化。
从 adb shell 更改模拟器语言区域
要使用 adb shell 更改模拟器中的语言区域,请执行以下操作:
选择您要测试的语言区域并确定其 BCP-47 语言标签,例如 fr-CA(加拿大法语)。
启动模拟器。
在主机计算机的命令行 shell 中,运行以下命令:
adb shell或者,如果您连接了设备,请通过添加 -e 选项来指定您想要操作模拟器:
adb -e shell
在 adb shell 提示符 (#) 下,运行此命令:
setprop persist.sys.locale [BCP-47 语言标签];stop;sleep 5;start将括号中的部分替换为第 1 步中的相应代码。
例如,要测试加拿大法语:
setprop persist.sys.locale fr-CA;stop;sleep 5;start
这将导致模拟器重启。当主屏幕再次出现后,重新启动您的应用,应用将以新的语言区域启动。
测试默认资源
要测试应用是否包含其所需的所有字符串资源,请执行以下操作:
将模拟器或设备设置为您的应用不支持的语言。例如,如果应用在 res/values-fr/ 中有法语字符串,但在 res/values-es/ 中没有任何西班牙语字符串,则将模拟器的语言区域设置为西班牙语。您可以使用 Custom Locale 应用将模拟器设置为不受支持的语言区域。
运行应用。
如果应用显示错误消息和强制关闭按钮,它可能正在寻找不可用的字符串。确保您的 res/values/strings.xml 文件包含应用使用的每个字符串的定义。
如果测试成功,请对其他类型的配置重复此操作。例如,如果应用有一个名为 res/values-land/strings.xml 的字符串文件,但没有名为 res/values-port/strings.xml 的文件,则将模拟器或设备设置为纵向模式,看看应用是否能运行。
其他资源
有关本地化的详细信息,请参阅以下其他资源:
文档
应用资源概览
翻译和本地化您的应用
视图内容
本地化您的应用 (Views)