Skip to main content

Potpun vodič za lokalizaciju Android aplikacije

Od strings.xml do Play Store metapodataka: lokalizujte Android aplikaciju pomoću Kotlin, Jetpack Compose, Fastlane i automatizovanog AI prevođenja.

1

Podesite Android projekat za lokalizaciju

Android koristi pravilo fascikli za lokalizaciju. Podrazumevani tekstovi su u res/values/strings.xml, a prevedeni u fasciklama lokala kao što su res/values-de/ i res/values-ja/.

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
Fascikla res/values/ je rezervni lokal. Ako tekst nedostaje u fascikli lokala, Android ga učitava iz podrazumevane. Ali ako tekst nedostaje u podrazumevanoj fascikli, aplikacija se ruši na nepodržanim lokalima.
2

Napravite strings.xml

Android resursi teksta koriste XML sa elementima '<string>' u korenu '<resources>'. Koristite %s za tekstualna mesta, %d za cele brojeve i %1$s/%2$s za pozicione argumente koje prevodioci mogu da premeste.

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>
Apostrofi bez izlaza neprimetno ruše XML analizator. Koristite \' ili stavite vrednost pod dvostruke navodnike. Takođe, nedostajući tekst u podrazumevanoj values/strings.xml datoteci izaziva rušenje, a ne neprimetan rezervni izbor kao 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

Obradite množinu

Android koristi elemente '&lt;plurals&gt;' sa atributima quantity: zero, one, two, few, many, other. Svakom ciljnom jeziku mogu biti potrebne druge kategorije — arapski koristi svih šest, ruskom trebaju few/many, a japanski samo 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
) -->
Atribut quantity bira oblik množine prema CLDR pravilima lokala uređaja. Uvek uključite „other" kao rezervnu vrednost — to je jedina kategorija koja postoji u svakom jeziku.
4

Koristite u kodu: Kotlin i Jetpack Compose

Tradicionalni Android koristi getString(R.string.key) i resources.getQuantityString(). Jetpack Compose koristi stringResource(R.string.key) i pluralStringResource(). Oba pri izvršavanju pronalaze ispravan prevod prema lokalu uređaja.

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) — parametar count se prosleđuje dva puta. Prvi bira oblik množine, drugi je argument formata. Izostavljanje drugog count parametra je najčešća greška Compose množine.
5

Nizovi tekstova i formatirani tekstovi

Koristite '&lt;string-array&gt;' za uređene liste (npr. opcije padajućeg menija i korake uvođenja). U formatiranim tekstovima koristite pozicione argumente (%1$s, %2$d) kako bi prevodioci mogli da promene redosled reči bez kvarenja rečenice.

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>
Pozicioni argumenti kao %1$s omogućavaju prevodiocima da slobodno premeste parametre. „Hello %1$s, you have %2$d items" može postati „%2$d items for %1$s" u jeziku sa drugim redosledom reči, bez izmene koda.
6

Lokalizujte Google Play metapodatke pomoću Fastlane

Koristite Fastlane komandu supply da upravljate Play Store metapodacima — naslovom, kratkim i punim opisom i evidencijom izmena — kao običnim tekstualnim datotekama organizovanim po lokalu u repozitorijumu.

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
Lokalizacija Play Store stranice povećava preuzimanja za više od 30% na tržištima van engleskog govornog područja. Naslov, kratak i pun opis indeksiraju se u pretrazi — njihovo prevođenje ima najveći povraćaj ulaganja.
Google Play

Automatizujte lokalizaciju Play Store stranice

Preskočite ručno kopiranje. Prevedite Play Store naslov, opis i napomene o izdanju na više od 175 lokala uz poštovanje ograničenja znakova.

Istražite Google Play integraciju
7

Testirajte lokalizaciju

Testirajte promenom lokala emulatora, Compose pregledima sa prilagođenim LocaleList i pseudolokalima u Developer Options. Koristite resConfigs u Gradle da uklonite neželjene resurse lokala iz nezavisnih biblioteka.

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
Testirajte na nemačkom (tekst je oko 30% duži) i japanskom (oko 50% kraći) da otkrijete probleme rasporeda. Uključite pseudolokale (en-XA za akcentovani tekst, ar-XB za RTL) u Developer Options radi testiranja bez pravih prevoda.

Automatizujte kvalitet prevoda

Otkrijte nedostajuće ključeve, neispravna mesta za promenljive i probleme množine pomoću i18n-validate pre objavljivanja. Testirajte UI pseudoprevodima pomoću i18n-pseudo pre nego što stignu pravi prevodi.
8

Automatizujte prevode

Prevedite strings.xml, množinu, nizove tekstova i Fastlane Supply metapodatke pomoću AI. Automatizujte prevod tekstova u aplikaciji i Play Store metapodataka radi potpuno lokalizovanog prisustva.

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 obrađuje Android XML izlaz, čuva oznake translatable="false", poštuje CLDR kategorije množine za svaki ciljni jezik i ne menja pozicione argumente formata.
JetBrains

Dostupan je Android Studio dodatak

Prevodite Android XML resurse direktno iz IDE okruženja pomoću i18n Agent dodatka za IntelliJ / Android Studio.

Install
+

Dodatno: pametni rezervni lokal sa LocaleChain

Rezervni izbor Android resursa kontroliše operativni sistem. Kada nedostaju pt-BR prevodi, Android potpuno preskače pt-PT i prikazuje engleski. LocaleChain presreće pretragu teksta i prolazi podesivi rezervni lanac, pa regionalni korisnici vide najbliži dostupan prevod.

LocaleChain za Android je Kotlin biblioteka otvorenog koda. Pogledajte na GitHub-u

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"))
)

Uobičajene zamke

Nedostajući podrazumevani tekstovi izazivaju rušenje

Za razliku od iOS sistema koji prikazuje neobrađeni ključ, Android se ruši sa ResourceNotFoundException ako tekst nedostaje u podrazumevanoj res/values/strings.xml datoteci. Uvek obezbedite da svaki ključ postoji u podrazumevanoj datoteci.

Jezičke podele App Bundle paketa kvare promenu jezika u aplikaciji

Google Play App Bundles dele APK po jeziku, pa korisnici dobijaju samo tekstove jezika uređaja. Ako nudite promenu jezika u aplikaciji, dodajte bundle '{ language { enableSplit = false } }' u build.gradle.kts.

RTL rasporedi se kvare

Uzrok je korišćenje left/right umesto start/end u rasporedima ili nedostatak android:supportsRtl="true" u AndroidManifest.xml. Koristite Android Studio Refactor > Add RTL Support da automatski pretvorite postojeće rasporede.

Kontaminacija resursima biblioteke

Nezavisne biblioteke sadrže sopstvene values-XX/strings.xml datoteke, pa Android misli da aplikacija podržava jezike koje ne podržava. Koristite resConfigs u build.gradle.kts da ograničite uključene lokale samo na one koje zaista prevodite.

Preporučena struktura datoteka

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

Isprobajte i18n Agent sada

Pustite datoteku za prevođenje ovde

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

ili kliknite za izbor

Ciljni jezici

Registracija nije potrebnaTrenutna procena

Rezervni lokali sa locale-chain-android

Kada u regionalnom lokalu kao što je pt-BR nedostaje ključ prevoda, Android odmah prelazi u podrazumevanu fasciklu resursa umesto da najpre proveri nadređeni lokal 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"),
    )
)

Pogledajte naš vodič za rezervne lokale za celu listu podržanih sistema i 75 ugrađenih lanaca. Learn more →

Česta pitanja o Android lokalizaciji