Skip to main content

Le guide complet de la localisation d'applications Android

De strings.xml aux métadonnées du Play Store : localisez votre application Android avec Kotlin, Jetpack Compose, Fastlane et la traduction automatisée par IA.

1

Configurez votre projet Android pour la localisation

Android utilise une convention basée sur des dossiers pour la localisation. Vos chaînes par défaut se trouvent dans res/values/strings.xml, et les chaînes traduites vont dans des dossiers spécifiques à chaque locale, comme res/values-de/, res/values-ja/, etc.

Android Project Structure
// Android project structure for localization:
// res/
// ├── values/              ← Default (fallback) locale
// │   └── strings.xml
// ├── values-de/           ← German
// │   └── strings.xml
// ├── values-ja/           ← Japanese
// │   └── strings.xml
// └── values-es/           ← Spanish
//     └── strings.xml
//
// Folder naming: values-{language} or values-{language}-r{Region}
// Examples: values-pt-rBR, values-zh-rCN, values-zh-rTW
Le dossier res/values/ est votre locale de repli. Si une chaîne est manquante dans un dossier spécifique à une locale, Android la charge depuis le dossier par défaut. Mais si une chaîne est manquante dans le dossier par défaut — votre application plante sur les locales non prises en charge.
2

Créez strings.xml

Les ressources de chaînes Android utilisent du XML avec des éléments '<string>' à l'intérieur d'une racine '<resources>'. Utilisez %s pour les espaces réservés de chaînes, %d pour les entiers, et %1$s/%2$s pour les arguments positionnels que les traducteurs peuvent réorganiser.

res/values/strings.xml
<!-- res/values/strings.xml -->
<resources>
    <string name="welcome_title">Welcome to MyApp</string>
    <string name="login_button">Sign In</string>
    <string name="settings_label">Settings</string>
    <string name="greeting">Hello, %s!</string>        <!-- %s = string -->
    <string name="item_count">%d items</string>          <!-- %d = integer -->
    <string name="app_name" translatable="false">MyApp</string>
</resources>
Les apostrophes non échappées font planter l'analyseur XML silencieusement. Utilisez \' ou placez la valeur entre guillemets doubles. Autre point : une chaîne manquante dans le fichier values/strings.xml par défaut provoque un plantage complet — pas un repli en douceur comme sur iOS.
Common strings.xml Mistakes
<!-- ❌ Common mistakes in strings.xml: -->

<!-- Unescaped apostrophe — crashes XML parser silently -->
<string name="message">It's a great day</string>

<!-- Missing from default values/strings.xml — app crashes -->
<!-- (only exists in values-de/strings.xml) -->

<!-- ✅ Correct versions: -->
<string name="message">It\'s a great day</string>
<!-- Or wrap in double quotes: -->
<string name="message">"It's a great day"</string>
3

Gérer les pluriels

Android utilise des éléments '&lt;plurals&gt;' avec des attributs quantity : zero, one, two, few, many, other. Chaque langue cible peut nécessiter des catégories différentes — l'arabe utilise les 6, le russe a besoin de few/many, le japonais n'utilise que other.

res/values/strings.xml
<!-- res/values/strings.xml -->
<resources>
    <plurals name="items_count">
        <item quantity="zero">No items</item>
        <item quantity="one">%d item</item>
        <item quantity="other">%d items</item>
    </plurals>
</resources>

<!-- Usage in Kotlin: -->
<!-- val text = resources.getQuantityString(
    R.plurals.items_count,
    count,    // selects plural form
    count     // format argument
) -->
L'attribut quantity sélectionne la forme plurielle selon les règles CLDR de la locale de l'appareil. Incluez toujours 'other' en repli — c'est la seule catégorie garantie d'exister dans toutes les langues.
4

Utilisation dans le code : Kotlin et Jetpack Compose

Android traditionnel utilise getString(R.string.key) et resources.getQuantityString(). Jetpack Compose utilise stringResource(R.string.key) et pluralStringResource(). Les deux résolvent la traduction correcte selon la locale de l'appareil à l'exécution.

WelcomeScreen.kt
// Traditional Android (Activity/Fragment)
val title = getString(R.string.welcome_title)
val greeting = getString(R.string.greeting, userName)
val items = resources.getQuantityString(
    R.plurals.items_count, count, count
)

// Jetpack Compose
@Composable
fun WelcomeScreen(userName: String, itemCount: Int) {
    // ✅ stringResource — Compose-aware, triggers recomposition
    Text(text = stringResource(R.string.welcome_title))

    // ✅ With format arguments
    Text(text = stringResource(R.string.greeting, userName))

    // ✅ Plurals — count passed TWICE
    Text(text = pluralStringResource(
        R.plurals.items_count,
        itemCount,    // selects plural form
        itemCount     // format argument
    ))
}
pluralStringResource(R.plurals.items, count, count) — le paramètre count est passé deux fois. Le premier sélectionne la forme plurielle, le second est l'argument de formatage. L'oubli du second count est le bug de pluralisation Compose numéro un.
5

Tableaux de chaînes et chaînes formatées

Utilisez '&lt;string-array&gt;' pour les listes ordonnées (par exemple, les options d'une liste déroulante, les étapes d'intégration). Utilisez des arguments de formatage positionnels (%1$s, %2$d) dans les chaînes formatées afin que les traducteurs puissent réorganiser les mots sans casser la structure de la phrase.

res/values/strings.xml
<!-- res/values/strings.xml -->
<resources>
    <!-- String array for dropdown/list -->
    <string-array name="sort_options">
        <item>Most Recent</item>
        <item>Most Popular</item>
        <item>Price: Low to High</item>
        <item>Price: High to Low</item>
    </string-array>

    <!-- Positional format args for reordering -->
    <string name="welcome_message">
        Hello %1$s, you have %2$d new messages
    </string>
    <!-- Translators can reorder: -->
    <!-- %2$d neue Nachrichten für %1$s -->
</resources>
Les arguments positionnels comme %1$s permettent aux traducteurs de réorganiser librement les paramètres. 'Hello %1$s, you have %2$d items' peut devenir '%2$d items for %1$s' dans les langues à l'ordre des mots différent — sans aucune modification du code.
6

Localisez les métadonnées Google Play avec Fastlane

Utilisez la commande supply de Fastlane pour gérer les métadonnées du Play Store — titre, description courte, description complète et journaux des modifications — sous forme de fichiers texte brut organisés par locale dans votre dépôt.

Terminal
# Install Fastlane
$ gem install fastlane

# Initialize supply for Play Store metadata
$ fastlane supply init

# Directory structure created:
# fastlane/metadata/android/
# ├── en-US/
# │   ├── title.txt              # App name (50 chars)
# │   ├── short_description.txt  # Short desc (80 chars)
# │   ├── full_description.txt   # Full desc (4000 chars)
# │   └── changelogs/
# │       └── default.txt        # What's New
# ├── de-DE/
# │   └── ...
# └── ja-JP/
#     └── ...

# Push metadata to Play Store:
$ fastlane supply
Localiser votre fiche Play Store augmente les téléchargements de plus de 30 % sur les marchés non anglophones. Le titre, la description courte et la description complète sont indexés pour la recherche — les traduire est la localisation au meilleur retour sur investissement que vous puissiez faire.
Google Play

Automatisez la localisation de votre fiche Play Store

Oubliez le copier-coller manuel. Traduisez le titre, la description et les notes de version de votre fiche Play Store dans plus de 175 locales, en tenant compte des limites de caractères.

Découvrez l'intégration Google Play
7

Tester votre localisation

Testez avec le changement de locale de l'émulateur, les aperçus Compose avec un LocaleList personnalisé, et les pseudo-locales dans les options pour les développeurs. Utilisez resConfigs dans Gradle pour retirer les ressources de locales indésirables des bibliothèques tierces.

Testing Localization
// 1. Emulator: Settings > System > Language > Add language

// 2. Compose Preview with locale:
@Preview
@Composable
fun WelcomePreview() {
    val config = Configuration(resources.configuration).apply {
        setLocale(Locale("de"))
    }
    val localContext = LocalContext.current
    val localizedContext = localContext.createConfigurationContext(config)
    CompositionLocalProvider(
        LocalContext provides localizedContext
    ) {
        WelcomeScreen()
    }
}

// 3. Restrict library locales in build.gradle.kts:
android {
    defaultConfig {
        // Only include locales you actually translate
        resourceConfigurations += listOf("en", "de", "ja", "es", "fr")
    }
}

// 4. Enable pseudolocales in Developer Options:
// en-XA (accented) — detects hardcoded strings
// ar-XB (RTL) — tests layout mirroring
Testez avec l'allemand (le texte s'allonge d'environ 30 %) et le japonais (il se réduit d'environ 50 %) pour détecter les problèmes de mise en page. Activez les pseudo-locales (en-XA pour les accents, ar-XB pour le RTL) dans les options pour les développeurs afin de soumettre vos mises en page à rude épreuve sans traductions réelles.

Automatiser la qualité des traductions

Détectez les clés manquantes, les espaces réservés cassés et les problèmes de pluriel avant leur mise en production grâce à i18n-validate. Testez votre interface avec des pseudo-traductions grâce à i18n-pseudo avant l'arrivée des traductions réelles.
8

Automatiser les traductions

Traduisez vos fichiers strings.xml, vos pluriels, vos tableaux de chaînes et vos métadonnées Fastlane Supply grâce à l'IA. Automatisez la traduction des chaînes intégrées à l'application comme des métadonnées du Play Store pour une présence entièrement localisée.

Terminal
# Translate strings.xml files
> Translate res/values/strings.xml
  to Japanese, German, and Spanish

# Translate Play Store metadata too
> Translate fastlane/metadata/android/en-US/
  to de-DE, ja-JP, es-ES

✓ 6 files translated in 3.2s
i18n Agent gère l'échappement XML Android, préserve les marqueurs translatable="false", respecte les catégories de pluriel CLDR propres à chaque langue cible et conserve intacts les arguments de formatage positionnels.
JetBrains

Plugin Android Studio disponible

Traduisez les ressources XML Android directement depuis votre IDE grâce au plugin i18n Agent pour IntelliJ / Android Studio.

Install
+

Bonus : repli de locale intelligent avec LocaleChain

Le repli des ressources Android est contrôlé par le système d'exploitation. Lorsque les traductions pt-BR sont manquantes, Android ignore complètement pt-PT et affiche l'anglais. LocaleChain intercepte les recherches de chaînes et parcourt une chaîne de repli configurable — les utilisateurs régionaux voient ainsi la traduction disponible la plus proche.

LocaleChain pour Android est une bibliothèque Kotlin open source. Voir sur GitHub

build.gradle.kts
// build.gradle.kts (app module)
dependencies {
    implementation("com.i18nagent:locale-chain-android:0.1.0")
}
MyApp.kt / BaseActivity.kt
// 1. Application.onCreate() — configure chains once
class MyApp : Application() {
    override fun onCreate() {
        super.onCreate()
        LocaleChain.configure()
    }
}

// 2. BaseActivity — wrap context per Activity
open class BaseActivity : AppCompatActivity() {
    override fun attachBaseContext(newBase: Context) {
        super.attachBaseContext(LocaleChain.wrap(newBase))
    }
}

// pt-BR user with only pt-PT translations?
// → Shows Portuguese instead of falling back to English

// Custom overrides for your specific locales:
LocaleChain.configure(
    overrides = mapOf("es-MX" to listOf("es-419", "es"))
)

Pièges courants

Les chaînes par défaut manquantes provoquent des plantages

Contrairement à iOS, qui affiche la clé brute, Android plante avec une ResourceNotFoundException si une chaîne est manquante dans le fichier res/values/strings.xml par défaut. Assurez-vous toujours que chaque clé existe dans le fichier par défaut.

Les découpages linguistiques des App Bundles cassent le changement de langue dans l'application

Les App Bundles de Google Play découpent les APK par langue — les utilisateurs ne reçoivent que les chaînes de la langue de leur appareil. Si vous proposez un changement de langue dans l'application, ajoutez bundle '{ language { enableSplit = false } }' à votre build.gradle.kts.

Mises en page RTL cassées

Utiliser left/right au lieu de start/end dans les mises en page, ou l'absence de android:supportsRtl="true" dans AndroidManifest.xml. Utilisez Refactor > Add RTL Support dans Android Studio pour convertir automatiquement les mises en page existantes.

Contamination des ressources par les bibliothèques

Les bibliothèques tierces embarquent leurs propres fichiers values-XX/strings.xml, ce qui laisse croire à Android que votre application prend en charge des langues qu'elle ne prend pas réellement en charge. Utilisez resConfigs dans build.gradle.kts pour restreindre les locales incluses à celles que vous traduisez réellement.

Structure de fichiers recommandée

Project Structure
MyApp/
├── app/
│   └── src/main/
│       ├── res/
│       │   ├── values/
│       │   │   ├── strings.xml          # Default (source) strings
│       │   │   └── plurals.xml          # Plural rules
│       │   ├── values-de/
│       │   │   └── strings.xml
│       │   ├── values-ja/
│       │   │   └── strings.xml
│       │   └── values-es/
│       │       └── strings.xml
│       ├── java/com/example/myapp/
│       └── AndroidManifest.xml
├── fastlane/
│   └── metadata/android/
│       ├── en-US/
│       │   ├── title.txt
│       │   ├── short_description.txt
│       │   ├── full_description.txt
│       │   └── changelogs/default.txt
│       ├── de-DE/
│       └── ja-JP/
├── build.gradle.kts
└── settings.gradle.kts

Essayez i18n Agent maintenant

Déposez votre fichier de traduction ici

JSON, YAML, PO, XML, CSV, Markdown, Properties

ou cliquez pour parcourir

Langues cibles

Aucune inscription requiseEstimation instantanée

Repli de locale avec locale-chain-android

Lorsqu'une clé de traduction est manquante dans une locale régionale comme pt-BR, Android passe directement au dossier de ressources par défaut au lieu de vérifier d'abord la locale parente pt.

Terminal
implementation("com.i18nagent:locale-chain-android:0.1.0")
Configuration
import com.i18nagent.localechain.LocaleChain

LocaleChain.configure(
    overrides = mapOf(
        "pt-BR" to listOf("pt", "en"),
        "zh-Hant-HK" to listOf("zh-Hant", "zh", "en"),
    )
)

Consultez notre guide de repli de locale pour découvrir la liste complète des frameworks pris en charge et les 75 chaînes intégrées. Learn more →

FAQ sur la localisation Android