Skip to main content

Potpun vodič za lokalizaciju Android aplikacije

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

1

Postavite Android projekt za lokalizaciju

Android za lokalizaciju primjenjuje pravila imenovanja mapa. Zadani nizovi nalaze se u res/values/strings.xml, a prijevodi u mapama lokalnih postavki poput 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
Mapa res/values/ služi kao pričuvna lokalna postavka. Ako niz nedostaje u mapi lokalne postavke, Android ga učitava iz zadane mape. No ako nedostaje u zadanoj mapi, aplikacija se ruši na nepodržanim lokalnim postavkama.
2

Napravite strings.xml

Androidovi resursi nizova upotrebljavaju XML s elementima '<string>' unutar korijenskog elementa '<resources>'. Upotrebljavajte %s za rezervirana mjesta nizova, %d za cijele brojeve te %1$s/%2$s za pozicijske argumente koje prevoditelji mogu premještati.

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 neprimjetno ruše XML analizator. Koristite \' ili stavite vrijednost pod dvostruke navodnike. Također, nedostajući tekst u zadanoj values/strings.xml datoteci izaziva rušenje, a ne neprimjetan 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 upotrebljava elemente '&lt;plurals&gt;' s atributima quantity: zero, one, two, few, many, other. Svakom ciljnom jeziku mogu trebati različite kategorije — arapski upotrebljava svih šest, ruskom trebaju few/many, a japanskom 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. Uvijek uključite „other" kao rezervnu vrijednost — 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 prijevod 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 prosljeđuje dva puta. Prvi bira oblik množine, drugi je argument formata. Izostavljanje drugog count parametra je najčešća pogreška Compose množine.
5

Nizovi tekstova i formatirani tekstovi

Upotrebljavajte '&lt;string-array&gt;' za uređene popise (npr. opcije padajućeg izbornika i korake uvođenja). U formatiranim nizovima upotrebljavajte pozicijske argumente (%1$s, %2$d) kako bi prevoditelji mogli promijeniti redoslijed riječi bez narušavanja 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>
Pozicijski argumenti poput %1$s omogućuju prevoditeljima slobodno premještanje parametara. „Hello %1$s, you have %2$d items" može u jeziku s drukčijim redoslijedom riječi postati „%2$d items for %1$s" bez izmjene koda.
6

Lokalizirajte Google Play metapodatke pomoću Fastlane

Upotrijebite Fastlaneovu naredbu supply za upravljanje metapodacima trgovine Play Store — naslovom, kratkim i punim opisom te zapisom promjena — kao običnim tekstnim datotekama organiziranima prema lokalnoj postavci u repozitoriju.

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

Automatizirajte 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 promjenom lokalne postavke emulatora, pretpregledima Compose s prilagođenim LocaleList i pseudolokalnim postavkama u Developer Options. Upotrijebite resConfigs u Gradleu kako biste uklonili neželjene resurse lokalnih postavki iz biblioteka drugih proizvođača.

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 njemačkom (nizovi su oko 30% dulji) i japanskom (oko 50% kraći) kako biste otkrili probleme s rasporedom. Uključite pseudolokalne postavke (en-XA za tekst s dijakritičkim znakovima, ar-XB za RTL) u Developer Options radi testiranja bez stvarnih prijevoda.

Automatizirajte kvalitetu prijevoda

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

Automatizirajte prevođenje

Prevedite strings.xml, množinu, nizove tekstova i Fastlane Supply metapodatke pomoću AI. Automatizirajte prijevod tekstova u aplikaciji i Play Store metapodataka radi potpuno lokaliziranog 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 mijenja pozicione argumente formata.
JetBrains

Dostupan je Android Studio dodatak

Prevodite Androidove XML resurse izravno iz IDE-a pomoću dodatka i18n Agent za IntelliJ / Android Studio.

Install
+

Dodatno: pametni pričuvni odabir lokalne postavke uz LocaleChain

Pričuvnim odabirom Androidovih resursa upravlja operacijski sustav. Kada nedostaju prijevodi za pt-BR, Android potpuno preskače pt-PT i prikazuje engleski. LocaleChain presreće dohvaćanje nizova i prolazi kroz prilagodljiv pričuvni lanac, pa regionalni korisnici vide najbliži dostupan prijevod.

LocaleChain za Android Kotlinova je knjižnica otvorenog koda. Pogledajte na GitHubu

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 zadani tekstovi izazivaju rušenje

Za razliku od iOS-a, koji prikazuje neobrađeni ključ, Android se ruši uz ResourceNotFoundException ako niz nedostaje u zadanoj datoteci res/values/strings.xml. Uvijek osigurajte da svaki ključ postoji u zadanoj datoteci.

Jezične podjele App Bundle paketa kvare promjenu jezika u aplikaciji

Google Play App Bundles dijele APK-ove prema jeziku, pa korisnici dobivaju samo nizove za jezik svojeg uređaja. Ako nudite promjenu jezika u aplikaciji, dodajte bundle '{ language { enableSplit = false } }' u build.gradle.kts.

RTL rasporedi se kvare

Uzrok je upotreba left/right umjesto start/end u rasporedima ili izostavljen android:supportsRtl="true" u AndroidManifest.xml. Upotrijebite Android Studio Refactor > Add RTL Support za automatsku pretvorbu postojećih rasporeda.

Kontaminacija resursima biblioteke

Neovisne biblioteke sadrže vlastite 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 odmah

Povucite datoteku za prijevod ovdje

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

ili kliknite za odabir

Ciljni jezici

Registracija nije potrebnaProcjena odmah

Pričuvni odabir lokalne postavke uz locale-chain-android

Kada u regionalnoj lokalnoj postavci poput pt-BR nedostaje ključ prijevoda, Android izravno prelazi na zadanu mapu resursa umjesto da najprije provjeri nadređenu lokalnu postavku 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 cijelu listu podržanih sustava i 75 ugrađenih lanaca. Learn more →

Česta pitanja o Android lokalizaciji