|
文档
预约演示平台
平台MCPCLIAPI工作流
指南
更新日志

本地化

  • 概览
  • 翻译 API
  • Web 应用本地化
  • 移动应用本地化
  • iOS 与 String Catalogs
  • Android 与 strings.xml
  • 邮件本地化
  • 静态内容(如 .md、.json)
  • Next.js + Markdoc
  • Rails + i18n

工作流

  • 通过 MCP 配置引擎
  • Jira 智能分诊
  • CI/CD

使用 strings.xml 为 Android 应用做本地化

Lingo.dev CLI 会通过已配置的 本地化引擎 翻译 Android strings.xml字符串资源()。借助 android 格式,CLI 能原生识别 <resources>、<string>、<string-array> 和 <plurals> 元素,既保留 XML 结构,也能为每个目标语言环境生成正确的复数类别。

这篇指南会带你完整走一遍 Android 应用本地化流程:配置 CLI、本地翻译,以及在 CI 中实现自动化,让翻译在每次 push 后都能随版本一起交付。

示例仓库

克隆或 fork lingodotdev/android-app-localization-example,即可跟着一起操作。这个仓库包含一个可直接运行的 Android 项目,内含字符串资源、Lingo.dev CLI 配置,以及已提交到各个目标语言环境的翻译。

Android 本地化如何工作#

Android 采用 资源目录约定,为每个语言环境使用独立的 values-[locale]/ 目录。系统会在运行时根据设备语言设置加载对应的 strings.xml。

text
app/src/main/res/
  values/              # Default (source) strings
    strings.xml
  values-es/           # Spanish
    strings.xml
  values-fr/           # French
    strings.xml
  values-ja/           # Japanese
    strings.xml

一个典型的 strings.xml 通常包含三类元素:

xml
<resources>
  <!-- Simple strings -->
  <string name="app_name">My App</string>
  <string name="welcome_message">Welcome back!</string>

  <!-- String arrays -->
  <string-array name="planets">
    <item>Mercury</item>
    <item>Venus</item>
    <item>Earth</item>
  </string-array>

  <!-- Plurals -->
  <plurals name="items_count">
    <item quantity="one">%d item</item>
    <item quantity="other">%d items</item>
  </plurals>
</resources>

CLI 会解析这三类元素,通过 localization engine 翻译其中内容,并将各语言环境对应的文件写入正确的 values-[locale]/ 目录。

准备工作#

1

创建 localization engine

每次运行 CLI 时,内容都会经过一个本地化引擎——该配置决定使用哪个 LLM 模型,以及应用哪个术语表、品牌语调和规则。在Lingo.dev dashboard中创建一个。

2

确认 Node.js 版本

CLI 要求 Node.js 22 或更高版本:

bash
node -v
3

安装 CLI

全局安装 CLI,这样就可以直接使用 lingo 命令:

bash
npm install -g @lingo.dev/cli
4

登录

使用一次性密码完成身份验证:

bash
lingo login

在 CI 中,则应改用 API key——通过 --api-key 传入,或设置 LINGO_API_KEY。

5

准备 Android 项目

你的项目需要在 strings.xml 中有一个默认的 app/src/main/res/values/。新建项目时,Android Studio 会自动生成这个文件。关于资源目录的设置方式,可参考 Android 的 本地化指南。

配置 CLI#

在项目根目录运行 lingo init,创建 .lingo/config.json,写入源语言环境、目标语言环境和文件匹配模式;然后再运行 lingo link,关联你的组织和引擎。最终效果如下:

json
{
  "orgId": "org_...",
  "engineId": "eng_...",
  "sourceLocale": "en",
  "targetLocales": ["es", "fr", "de", "ja"],
  "files": [
    {
      "pattern": "app/src/main/res/values/strings.xml",
      "format": "android"
    }
  ]
}

该模式指向默认资源目录,也就是未限定的 values/——正是 Android 期望存放源字符串的位置。这里不会出现语言环境代码,也不需要出现。

为什么要显式设置 `format`

CLI 会根据文件扩展名自动识别大多数格式,但 .xml 有歧义,因此 Android 资源文件需要在 files 条目中显式指定 "format": "android"。

多个资源文件

如果你的项目将字符串拆分在多个文件中(例如 strings.xml 和 arrays.xml),请为每个文件分别添加一个 files 条目:

json
{
  "files": [
    {
      "pattern": "app/src/main/res/values/strings.xml",
      "format": "android"
    },
    {
      "pattern": "app/src/main/res/values/arrays.xml",
      "format": "android"
    }
  ]
}

将 .lingo/config.json 提交到仓库中。

语言环境目录与限定符#

Android 会将默认语言放在未限定的 values/ 目录中,因此源路径本身不包含语言环境代码。CLI 也遵循这一规则:它会将不带限定符的 values/ 视为源语言环境,并为其他每种语言环境追加对应的目标限定符。

语言环境资源目录
en(源)values/
esvalues-es/
pt-BRvalues-pt-rBR/
zh-Hansvalues-b+zh+Hans/

这里需要特别理解区域和书写系统语言环境,因为资源限定符并不是原始的 BCP 47 标签。Android 支持两种写法:传统的语言-地区形式(values-pt-rBR/),以及带 b+ 前缀的 BCP 47 形式(values-b+pt+BR/,适用于 API 24 及以上)。如果目录命名为 values-pt-BR/,Android 会直接忽略——字符串虽然存在,但永远不会被加载。

设置 "format": "android" 后,CLI 会自动为你生成正确的写法:能用传统形式表达的语言环境就使用传统形式;涉及书写系统、三字母语言代码和数字区域时,则使用 b+。

从旧配置升级

较早版本的 CLI 要求在源路径中包含语言环境,本指南过去也曾建议使用 values-en -> values 符号链接来衔接这两种约定。从 @lingo.dev/cli 1.12.0 开始,这已经不再需要——将模式指向 values/strings.xml,然后删除该符号链接即可。

本地翻译#

运行 CLI。首次运行时——或者每次新增目标语言环境时——请使用 --backfill-missing,这样现有的所有字符串都会被翻译:

bash
lingo push --backfill-missing

CLI 会读取源 strings.xml,基于 运行状态 找出尚未翻译的条目,通过你的本地化引擎翻译这些增量内容,并将结果写入目标 values-[locale]/ 目录。打开任意目标文件,就能看到翻译后的字符串。

后续再运行时,lingo push 只会翻译发生变更的内容:

bash
lingo push

如果你只想让某次运行作用于特定文件,可以传入一个 glob。模式会基于源路径进行匹配,因此应按源文件限定范围,而不是目标文件:

bash
lingo push "app/src/main/res/values/strings.xml"

如果要把在其他地方生成的翻译(例如由 CI 生成)拉取到当前工作树中,运行 lingo pull 即可。

复数处理#

Android 使用 <plurals> 元素,并配合 CLDR quantity strings(zero、one、two、few、many、other)来处理复数形式。不同语言所需的复数类别不同——英语需要两类(one 和 other),俄语需要四类,阿拉伯语需要六类。

CLI 会在翻译时保留 <plurals> 结构,并为每个目标语言环境生成正确的 quantity 条目。比如一个只包含两个类别的源条目:

xml
<plurals name="messages_count">
  <item quantity="one">%d new message</item>
  <item quantity="other">%d new messages</item>
</plurals>

就能为每种目标语言生成正确的类别。localization engine 知道每个语言环境适用哪些 CLDR plural rules,并且只会生成该语言真正需要的类别。

键锁定#

有些字符串值在所有语言中都应保持完全一致——例如品牌名称、API 端点或格式模式。这时可以使用 key locking,直接复制这些值而不进行翻译:

json
{
  "files": [
    {
      "pattern": "app/src/main/res/values/strings.xml",
      "format": "android",
      "lockedKeys": ["app_name", "api_base_url"]
    }
  ]
}

被锁定的键会从源文件直接复制到所有目标文件,不会进入翻译流程。

在 CI 中实现自动化#

想要持续保持翻译最新,推荐使用 Lingo.dev GitHub App。它在服务端运行,读取你已提交的 .lingo/config.json 和 engineId,并自动创建翻译更新——无需 runner、无需存储 secret,也不用你自己管理 lockfile。安装后将它连接到你的仓库,就能在每次 push 时自动完成翻译。

如果你更希望在自己的流水线里运行 CLI,可以添加一个工作流,安装 CLI 并执行 lingo push:

yaml
name: Translate
on:
  push:
    branches: [main]
permissions:
  contents: write
jobs:
  translate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
      - run: npm install -g @lingo.dev/cli
      - run: lingo push --backfill-missing
        env:
          LINGO_API_KEY: ${{ secrets.LINGO_API_KEY }}

在 GitHub 仓库的 Settings > Secrets and variables > Actions 中,将你的 API key 保存为 LINGO_API_KEY,然后在后续步骤中提交更新后的目标文件(或创建一个 pull request)。

部署前先校验#

你也可以把 lingo check 作为部署门禁,确保未翻译的字符串不会进入生产环境。如果仍有条目需要翻译,这个命令会以非零状态码退出:

bash
lingo check

可以在构建前把它作为单独的 CI 步骤加入:

yaml
- name: Verify translations
  run: lingo check
  env:
    LINGO_API_KEY: ${{ secrets.LINGO_API_KEY }}

下一步#

移动应用本地化
移动平台本地化总览——iOS、Android、Flutter、React Native
CI/CD 工作流
GitHub Actions、GitLab CI、Bitbucket Pipelines 的常见模式
术语表
锁定品牌名称和技术术语,避免被翻译
键锁定
无需翻译,直接复制指定值

这个页面对你有帮助吗?

Max PrilutskiyMax Prilutskiy·已更新 8 天前·3 分钟阅读