Skip to main content

Den komplette guiden til lokalisering av Android-apper

Fra strings.xml til Play Store-metadata: lokaliser Android-appen din med Kotlin, Jetpack Compose, Fastlane og automatisert AI-oversettelse.

1

Sett opp Android-prosjektet for lokalisering

Android bruker en mappebasert konvensjon for lokalisering. Standardstrengene dine ligger i res/values/strings.xml, og oversatte strenger legges i lokalitetsspesifikke mapper som res/values-de/, res/values-ja/ osv.

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
Mappen res/values/ er reserveløsningen din. Hvis en streng mangler i en lokalitetsspesifikk mappe, laster Android den fra standarden. Men hvis en streng mangler i standarden, krasjer appen på lokaliteter som ikke støttes.
2

Opprett strings.xml

Android-strengressurser bruker XML med '<string>'-elementer inni en '<resources>'-rot. Bruk %s for strengplassholdere, %d for heltall, og %1$s/%2$s for posisjonelle argumenter som oversettere kan endre rekkefølgen på.

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>
Uunnslupne apostrofer krasjer XML-parseren stille. Bruk \' eller sett verdien i doble anførselstegn. I tillegg: en manglende streng i standard values/strings.xml forårsaker et hardt krasj, ikke en elegant reserveløsning som på 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

Håndter flertallsformer

Android bruker '&lt;plurals&gt;'-elementer med quantity-attributter: zero, one, two, few, many, other. Hvert målspråk kan trenge ulike kategorier. Arabisk bruker alle 6, russisk trenger few/many, japansk bruker bare 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
) -->
Quantity-attributtet velger flertallsformen basert på CLDR-reglene for enhetens lokalitet. Ta alltid med 'other' som reserveløsning. Det er den eneste kategorien som er garantert å finnes i alle språk.
4

Bruk i kode: Kotlin og Jetpack Compose

Tradisjonell Android bruker getString(R.string.key) og resources.getQuantityString(). Jetpack Compose bruker stringResource(R.string.key) og pluralStringResource(). Begge løser opp riktig oversettelse basert på enhetens lokalitet ved kjøretid.

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): count-parameteren sendes to ganger. Den første velger flertallsformen, den andre er formateringsargumentet. Å glemme den andre count-en er den vanligste feilen ved flertallshåndtering i Compose.
5

Strengtabeller og formaterte strenger

Bruk '&lt;string-array&gt;' for ordnede lister (f.eks. nedtrekksalternativer, introduksjonstrinn). Bruk posisjonelle formateringsargumenter (%1$s, %2$d) i formaterte strenger, slik at oversettere kan endre rekkefølgen på ord uten å ødelegge setningsstrukturen.

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>
Posisjonelle argumenter som %1$s lar oversettere endre rekkefølgen på parametere fritt. 'Hello %1$s, you have %2$d items' kan bli til '%2$d items for %1$s' i språk med annen ordstilling, uten noen kodeendringer.
6

Lokaliser Google Play-metadata med Fastlane

Bruk Fastlanes supply-kommando til å administrere Play Store-metadata (tittel, kort beskrivelse, full beskrivelse og endringslogger) som vanlige tekstfiler organisert etter lokalitet i repositoriet ditt.

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
Å lokalisere Play Store-oppføringen din øker nedlastinger med over 30 % i ikke-engelskspråklige markeder. Tittel, kort beskrivelse og full beskrivelse indekseres for søk. Å oversette dem er den lokaliseringen som gir høyest avkastning.
Google Play

Automatiser lokaliseringen av Play Store-oppføringen din

Slipp manuell klipp-og-lim. Oversett tittelen, beskrivelsen og utgivelsesnotatene for Play Store til over 175 lokaliteter, med hensyn til tegngrensene.

Utforsk Google Play-integrasjonen
7

Test lokaliseringen din

Test med lokalitetsbytte i emulator, Compose-forhåndsvisninger med tilpasset LocaleList, og pseudolokaliteter i utvikleralternativene. Bruk resConfigs i Gradle for å fjerne uønskede lokalitetsressurser fra tredjepartsbiblioteker.

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
Test med tysk (teksten utvides med ca. 30 %) og japansk (krymper med ca. 50 %) for å fange opp layoutproblemer. Aktiver pseudolokaliteter (en-XA for aksenter, ar-XB for RTL) i utvikleralternativene for å stressteste layouter uten ekte oversettelser.

Automatiser oversettelseskvalitet

Fang opp manglende nøkler, ødelagte plassholdere og problemer med flertallsformer før de driftsettes, med i18n-validate. Test grensesnittet ditt med pseudo-oversettelser ved hjelp av i18n-pseudo før de ekte oversettelsene kommer.
8

Automatiser oversettelser

Oversett strings.xml, flertallsformer, strengmatriser og Fastlane Supply-metadata med AI. Automatiser oversettelsen av både strenger i appen og Play Store-metadata for en fullstendig lokalisert tilstedeværelse.

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 håndterer escape-tegn i Android-XML, bevarer translatable="false"-markører, respekterer CLDR-flertallskategorier for hvert målspråk, og holder posisjonelle formateringsargumenter intakte.
JetBrains

Tillegg til Android Studio tilgjengelig

Oversett Android XML-ressurser direkte fra IDE-en din med i18n Agent-tillegget for IntelliJ / Android Studio.

Install
+

Bonus: Smart lokalitetsreserveløsning med LocaleChain

Androids ressursreserveløsning styres av operativsystemet. Når pt-BR-oversettelser mangler, hopper Android helt over pt-PT og viser engelsk. LocaleChain fanger opp strengoppslag og går gjennom en konfigurerbar reservekjede, slik at regionale brukere ser den nærmeste tilgjengelige oversettelsen.

LocaleChain for Android er et Kotlin-bibliotek med åpen kildekode. Se på 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"))
)

Vanlige fallgruver

Manglende standardstrenger forårsaker krasj

I motsetning til iOS, som viser den rå nøkkelen, krasjer Android med en ResourceNotFoundException hvis en streng mangler i standard res/values/strings.xml. Sørg alltid for at hver nøkkel finnes i standardfilen.

Språkoppdeling i App Bundle ødelegger språkbytte i appen

Google Play App Bundles deler opp APK-er etter språk. Brukere mottar bare strengene for enhetens språk. Hvis du tilbyr språkbytte i appen, legger du til bundle '{ language { enableSplit = false } }' i build.gradle.kts.

RTL-layouter som ødelegges

Å bruke left/right i stedet for start/end i layouter, eller manglende android:supportsRtl="true" i AndroidManifest.xml. Bruk Android Studios Refactor > Add RTL Support for å konvertere eksisterende layouter automatisk.

Forurensning av biblioteksressurser

Tredjepartsbiblioteker pakker med sine egne values-XX/strings.xml-filer, noe som får Android til å tro at appen din støtter språk den ikke gjør. Bruk resConfigs i build.gradle.kts for å begrense inkluderte lokaliteter til bare de du faktisk oversetter.

Anbefalt filstruktur

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

Prøv i18n Agent nå

Slipp oversettelsesfilen din her

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

eller klikk for å bla gjennom

Målspråk

Ingen registrering krevesUmiddelbart estimat

Lokalitetsreserveløsning med locale-chain-android

Når en oversettelsesnøkkel mangler i en regional lokalitet som pt-BR, hopper Android rett til standardressursmappen i stedet for først å sjekke foreldrelokaliteten 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"),
    )
)

Se vår guide til lokalitetsreserveløsning for den fullstendige listen over støttede rammeverk og 75 innebygde kjeder. Learn more →

Ofte stilte spørsmål om Android-lokalisering