Skip to main content

Ghidul complet pentru localizarea aplicațiilor Android

De la strings.xml la metadatele Play Store: localizați-vă aplicația Android cu Kotlin, Jetpack Compose, Fastlane și traducere automată bazată pe IA.

1

Configurați-vă proiectul Android pentru localizare

Android utilizează o convenție bazată pe dosare pentru localizare. Șirurile implicite se află în res/values/strings.xml, iar șirurile traduse sunt plasate în dosare specifice limbii și regiunii, precum 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
Dosarul res/values/ reprezintă limba de rezervă. Dacă lipsește un șir dintr-un dosar specific unei limbi și regiuni, Android îl încarcă din dosarul implicit. Însă, dacă șirul lipsește din cel implicit, aplicația se blochează pentru limbile și regiunile neacceptate.
2

Creați strings.xml

Resursele de șiruri Android utilizează XML, cu elemente '<string>' într-un element-rădăcină '<resources>'. Utilizați %s pentru substituenții de tip șir, %d pentru numere întregi și %1$s/%2$s pentru argumentele poziționale pe care traducătorii le pot reordona.

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>
Apostrofurile neprotejate blochează analizorul XML fără mesaj de eroare. Utilizați \' sau încadrați valoarea între ghilimele duble. De asemenea, absența unui șir din fișierul implicit values/strings.xml provoacă blocarea completă a aplicației, nu o revenire controlată la o valoare de rezervă, ca în 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

Gestionați formele de plural

Android utilizează elemente '&lt;plurals&gt;' cu atribute quantity: zero, one, two, few, many, other. Fiecare limbă-țintă poate necesita categorii diferite: araba le utilizează pe toate cele 6, rusa necesită few/many, iar japoneza utilizează numai 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
) -->
Atributul quantity selectează forma de plural pe baza regulilor CLDR pentru limba și regiunea dispozitivului. Includeți întotdeauna 'other' ca variantă de rezervă: este singura categorie a cărei existență este garantată în fiecare limbă.
4

Utilizarea în cod: Kotlin și Jetpack Compose

Android tradițional utilizează getString(R.string.key) și resources.getQuantityString(). Jetpack Compose utilizează stringResource(R.string.key) și pluralStringResource(). Ambele returnează traducerea corectă la momentul execuției, în funcție de limba și regiunea dispozitivului.

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) — parametrul count este transmis de două ori. Prima apariție selectează forma de plural, iar a doua reprezintă argumentul de formatare. Omiterea celui de-al doilea count este principala eroare de pluralizare din Compose.
5

Matrice de șiruri și șiruri formatate

Utilizați '&lt;string-array&gt;' pentru liste ordonate (de exemplu, opțiuni din liste derulante sau pași de inițiere). Utilizați argumente de formatare poziționale (%1$s, %2$d) în șirurile formatate, astfel încât traducătorii să poată reordona cuvintele fără a afecta structura propoziției.

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>
Argumentele poziționale precum %1$s le permit traducătorilor să reordoneze liber parametrii. 'Hello %1$s, you have %2$d items' poate deveni '%2$d items for %1$s' în limbile cu o ordine diferită a cuvintelor, fără nicio modificare a codului.
6

Localizați metadatele Google Play cu Fastlane

Utilizați comanda supply din Fastlane pentru a gestiona metadatele Play Store — titlul, descrierea scurtă, descrierea completă și jurnalele de modificări — sub formă de fișiere text simplu, organizate în depozit după limbă și regiune.

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
Localizarea paginii dumneavoastră din Play Store crește descărcările cu peste 30% pe piețele în care nu se vorbește engleza. Titlul, descrierea scurtă și descrierea completă sunt indexate pentru căutare, iar traducerea lor oferă cel mai bun randament al investiției în localizare.
Google Play

Automatizați localizarea paginii dumneavoastră din Play Store

Evitați copierea și lipirea manuală. Traduceți titlul, descrierea și notele de versiune din Play Store în peste 175 de limbi și regiuni, cu respectarea limitelor de caractere.

Explorați integrarea cu Google Play
7

Testați localizarea

Testați schimbând limba și regiunea emulatorului, utilizând previzualizări Compose cu un LocaleList personalizat și activând limbile pseudolocalizate din Developer Options. Utilizați resConfigs în Gradle pentru a elimina resursele nedorite pentru limbi și regiuni din bibliotecile terțe.

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
Testați cu germana (textul se extinde cu aproximativ 30%) și japoneza (textul se restrânge cu aproximativ 50%) pentru a identifica problemele de dispunere. Activați limbile pseudolocalizate (en-XA pentru caractere accentuate, ar-XB pentru RTL) în Developer Options pentru a supune dispunerile unor teste riguroase fără traduceri reale.

Automatizați controlul calității traducerilor

Identificați cheile lipsă, substituenții nevalizi și problemele de plural înainte de lansare cu i18n-validate. Testați interfața cu pseudotraduceri folosind i18n-pseudo înainte de sosirea traducerilor reale.
8

Automatizați traducerile

Traduceți cu ajutorul IA fișierele strings.xml, formele de plural, matricele de șiruri și metadatele Fastlane Supply. Automatizați traducerea atât a șirurilor din aplicație, cât și a metadatelor Play Store, pentru o prezență localizată complet.

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 gestionează caracterele escape din XML-ul Android, păstrează marcajele translatable="false", respectă categoriile de plural CLDR pentru fiecare limbă-țintă și menține intacte argumentele de formatare poziționale.
JetBrains

Este disponibil un plugin pentru Android Studio

Traduceți resursele XML Android direct din IDE cu pluginul i18n Agent pentru IntelliJ / Android Studio.

Install
+

Bonus: mecanism inteligent de rezervă pentru setările regionale cu LocaleChain

Revenirea la resurse de rezervă în Android este controlată de sistemul de operare. Când lipsesc traducerile pt-BR, Android omite complet pt-PT și afișează limba engleză. LocaleChain interceptează căutările de șiruri și parcurge un lanț configurabil de variante de rezervă, astfel încât utilizatorii regionali să vadă cea mai apropiată traducere disponibilă.

LocaleChain pentru Android este o bibliotecă Kotlin cu sursă deschisă. Vedeți pe 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"))
)

Capcane frecvente

Absența șirurilor implicite provoacă blocări

Spre deosebire de iOS, care afișează cheia brută, Android se blochează cu ResourceNotFoundException dacă un șir lipsește din fișierul implicit res/values/strings.xml. Asigurați-vă întotdeauna că fiecare cheie există în fișierul implicit.

Separarea limbilor în App Bundle împiedică schimbarea limbii în aplicație

Google Play App Bundles separă APK-urile după limbă, astfel încât utilizatorii primesc numai șirurile pentru limba dispozitivului lor. Dacă oferiți schimbarea limbii în aplicație, adăugați bundle '{ language { enableSplit = false } }' în build.gradle.kts.

Probleme cu dispunerile RTL

Cauzele includ utilizarea left/right în loc de start/end în dispuneri sau absența android:supportsRtl="true" din AndroidManifest.xml. Utilizați Refactor > Add RTL Support din Android Studio pentru a converti automat dispunerile existente.

Contaminarea resurselor de către biblioteci

Bibliotecile terțe includ propriile fișiere values-XX/strings.xml, ceea ce face ca Android să considere că aplicația acceptă limbi pe care nu le oferă. Utilizați resConfigs în build.gradle.kts pentru a limita limbile și regiunile incluse numai la cele pe care le traduceți efectiv.

Structura de fișiere recomandată

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

Încercați acum i18n Agent

Plasați aici fișierul de traducere

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

sau faceți clic pentru a-l selecta

Limbi țintă

Nu este necesară înregistrareaEstimare instantanee

Mecanism de rezervă pentru setările regionale cu locale-chain-android

Când lipsește o cheie de traducere într-o variantă regională precum pt-BR, Android trece direct la dosarul implicit de resurse, fără să verifice mai întâi limba părinte 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"),
    )
)

Consultați Ghidul nostru privind mecanismele de rezervă pentru setările regionale, care conține lista completă a cadrelor acceptate și cele 75 de lanțuri incluse. Learn more →

Întrebări frecvente despre localizarea Android