La CLI de Lingo.dev traduce los recursos de texto de Android (strings.xml) a través de un motor de localización configurado. El tipo de bucket android de la CLI interpreta de forma nativa los elementos <resources>, <string>, <string-array> y <plurals>, conservando la estructura XML y generando las categorías de plural correctas para cada idioma de destino.
En esta guía verás cómo localizar una app Android de principio a fin: configurar la CLI, traducir en local y automatizar el proceso con GitHub Actions para que las traducciones se publiquen con cada push.
Repositorio de ejemplo
Clona o haz un fork de lingodotdev/android-app-localization-example para seguir el proceso paso a paso. El repositorio incluye un proyecto Android funcional con recursos de texto, una configuración de la CLI de Lingo.dev y un flujo de trabajo de GitHub Actions.
Cómo funciona la localización en Android#
Android sigue una convención de directorios de recursos en la que cada idioma tiene su propio directorio values-[locale]/. En tiempo de ejecución, el sistema carga el strings.xml adecuado según el idioma configurado en el dispositivo.
app/src/main/res/
values/ # Default (source) strings
strings.xml
values-es/ # Spanish
strings.xml
values-fr/ # French
strings.xml
values-ja/ # Japanese
strings.xmlUn archivo strings.xml típico contiene tres tipos de elementos:
<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>La CLI analiza los tres tipos de elementos, traduce su contenido mediante el motor de localización y escribe archivos por idioma en los directorios values-[locale]/ correspondientes.
Requisitos previos#
Crea un motor de localización
Cada ejecución de la CLI envía el contenido a través de un motor de localización, la configuración que determina qué modelo LLM, glosario, voz de marca e instrucciones se aplican. Crea uno en el panel de Lingo.dev y genera una API key.
Comprueba Node.js
La CLI requiere Node.js 18 o superior:
node -vPrepara tu proyecto Android
Tu proyecto necesita un archivo strings.xml por defecto en app/src/main/res/values/. Android Studio crea este archivo al iniciar un proyecto nuevo. Consulta la guía de localización de Android para configurar los directorios de recursos.
Configura la CLI#
Crea un archivo i18n.json en la raíz de tu proyecto. El bucket android indica a la CLI que analice los recursos XML de Android y cree archivos independientes por idioma:
{
"$schema": "https://lingo.dev/schema/i18n.json",
"version": "1.15",
"locale": {
"source": "en",
"targets": ["es", "fr", "de", "ja"]
},
"buckets": {
"android": {
"include": ["app/src/main/res/values-[locale]/strings.xml"]
}
}
}El marcador de posición [locale] se resuelve en tiempo de ejecución como cada código de idioma configurado. La CLI sustituye el idioma de origen en el patrón, así que con source: "en" buscará values-en/strings.xml. Los idiomas de destino generan values-es/strings.xml, values-fr/strings.xml, etc.
Conecta el directorio del idioma por defecto#
Android guarda las cadenas por defecto en values/ (sin sufijo de idioma), pero la CLI resuelve [locale] de forma literal y busca values-en/strings.xml. Crea un enlace simbólico para salvar esa diferencia entre convenciones:
cd app/src/main/res
ln -s values values-enAsí, las cadenas de origen quedan visibles tanto en values/strings.xml (donde Android las espera) como en values-en/strings.xml (donde la CLI las busca). Haz commit del enlace simbólico en tu repositorio: git hace seguimiento de los symlinks de forma nativa en macOS y Linux.
Windows
En Windows, Git puede extraer los symlinks como archivos de texto plano según tu configuración. Si trabajas en Windows, ejecuta git config core.symlinks true antes de clonar, o bien copia el directorio values/ a values-en/.
Varios archivos de recursos
Si tu proyecto reparte las cadenas entre varios archivos (por ejemplo, strings.xml y arrays.xml), inclúyelos todos. El enlace simbólico cubre todo el directorio, así que todos los archivos dentro de values/ estarán accesibles desde values-en/:
{
"buckets": {
"android": {
"include": [
"app/src/main/res/values-[locale]/strings.xml",
"app/src/main/res/values-[locale]/arrays.xml"
]
}
}
}Traduce en local#
Configura tu API key y ejecuta la CLI:
export LINGO_API_KEY="your-api-key"
npx lingo.dev@latest runLa CLI lee el archivo fuente strings.xml, identifica las entradas sin traducir mediante el lockfile, traduce el delta a través de tu motor de localización y escribe el resultado en los directorios de destino values-[locale]/. Abre cualquier archivo de destino para ver las cadenas traducidas.
Para apuntar a un idioma concreto durante el desarrollo:
npx lingo.dev@latest run --target-locale esPlurales#
Android usa elementos <plurals> con cadenas de cantidad de CLDR (zero, one, two, few, many, other) para gestionar las formas plurales. Cada idioma requiere categorías de plural distintas: el inglés necesita dos (one y other), el ruso necesita cuatro y el árabe, seis.
La CLI conserva la estructura de <plurals> durante la traducción y genera las entradas de cantidad correctas para cada idioma de destino. Una entrada de origen con dos categorías:
<plurals name="messages_count">
<item quantity="one">%d new message</item>
<item quantity="other">%d new messages</item>
</plurals>Genera las categorías correctas para cada idioma de destino. El motor de localización sabe qué reglas de plural de CLDR se aplican a cada idioma y genera solo las categorías que ese idioma necesita.
Bloqueo de claves#
Algunos valores de texto deben mantenerse idénticos en todos los idiomas: nombres de marca, endpoints de API o patrones de formato. Usa el bloqueo de claves para copiar esos valores sin traducirlos:
{
"buckets": {
"android": {
"include": ["app/src/main/res/values-[locale]/strings.xml"],
"lockedKeys": ["app_name", "api_base_url"]
}
}
}Las claves bloqueadas se copian del origen a todos los archivos de destino sin pasar por el flujo de traducción.
Automatiza con GitHub Actions#
Añade un archivo de flujo de trabajo en .github/workflows/translate.yml para traducir con cada push:
Las traducciones se confirman directamente en main: cero fricción, ideal para equipos pequeños:
name: Translate
on:
push:
branches: [main]
permissions:
contents: write
jobs:
translate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Lingo.dev
uses: lingodotdev/lingo.dev@main
with:
api-key: ${{ secrets.LINGODOTDEV_API_KEY }}Guarda tu API key como LINGODOTDEV_API_KEY en Settings > Secrets and variables > Actions dentro de tu repositorio de GitHub.
Verifica antes de desplegar#
Usa la marca --frozen como control previo al despliegue para asegurarte de que no lleguen cadenas sin traducir a producción. La CLI finaliza con un estado distinto de cero si alguna entrada necesita traducción:
npx lingo.dev@latest run --frozenAñádelo como un paso de CI independiente antes del build:
- name: Verify translations
run: npx lingo.dev@latest run --frozen