Skip to main content

Der vollständige Leitfaden zur Lokalisierung von Android-Apps

Von strings.xml bis zu Play-Store-Metadaten: Lokalisieren Sie Ihre Android-App mit Kotlin, Jetpack Compose, Fastlane und automatisierter KI-Übersetzung.

1

Android-Projekt für die Lokalisierung einrichten

Android verwendet für die Lokalisierung eine ordnerbasierte Konvention. Ihre Standardzeichenfolgen befinden sich in res/values/strings.xml, übersetzte Zeichenfolgen in Locale-spezifischen Ordnern wie res/values-de/, res/values-ja/ usw.

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
Der Ordner res/values/ ist Ihre Fallback-Locale. Fehlt eine Zeichenfolge in einem Locale-spezifischen Ordner, lädt Android sie aus dem Standardordner. Fehlt eine Zeichenfolge jedoch im Standardordner, stürzt Ihre App bei nicht unterstützten Locales ab.
2

strings.xml erstellen

Android-Zeichenfolgenressourcen verwenden XML mit '<string>'-Elementen innerhalb des Wurzelelements '<resources>'. Verwenden Sie %s für Zeichenfolgenplatzhalter, %d für Ganzzahlen und %1$s/%2$s für positionsbezogene Argumente, die Übersetzerinnen und Übersetzer umstellen können.

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>
Nicht maskierte Apostrophe bringen den XML-Parser ohne Fehlermeldung zum Absturz. Verwenden Sie \' oder schließen Sie den Wert in doppelte Anführungszeichen ein. Außerdem führt eine fehlende Zeichenfolge in der standardmäßigen values/strings.xml zu einem vollständigen Absturz und nicht zu einem sanften Fallback wie bei 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

Pluralformen verarbeiten

Android verwendet '&lt;plurals&gt;'-Elemente mit quantity-Attributen: zero, one, two, few, many, other. Jede Zielsprache kann andere Kategorien benötigen – Arabisch verwendet alle sechs, Russisch few/many und Japanisch nur 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
) -->
Das quantity-Attribut wählt die Pluralform anhand der CLDR-Regeln für die Geräte-Locale aus. Schließen Sie stets other als Fallback ein – dies ist die einzige Kategorie, die garantiert in jeder Sprache vorhanden ist.
4

Im Code verwenden: Kotlin und Jetpack Compose

Herkömmliches Android verwendet getString(R.string.key) und resources.getQuantityString(). Jetpack Compose verwendet stringResource(R.string.key) und pluralStringResource(). Beide ermitteln zur Laufzeit anhand der Geräte-Locale die richtige Übersetzung.

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): Der Parameter count wird zweimal übergeben. Das erste Vorkommen wählt die Pluralform, das zweite ist das Formatargument. Ein fehlendes zweites count ist der häufigste Fehler bei Pluralformen in Compose.
5

Zeichenfolgenarrays und formatierte Zeichenfolgen

Verwenden Sie '&lt;string-array&gt;' für geordnete Listen, etwa Dropdown-Optionen oder Einführungsschritte. Verwenden Sie positionsbezogene Formatargumente (%1$s, %2$d) in formatierten Zeichenfolgen, damit Wörter umgestellt werden können, ohne die Satzstruktur zu beschädigen.

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>
Mit positionsbezogenen Argumenten wie %1$s lassen sich Parameter frei umstellen. „Hallo %1$s, Sie haben %2$d Elemente“ kann in Sprachen mit anderer Wortstellung zu „%2$d Elemente für %1$s“ werden – ganz ohne Codeänderungen.
6

Google-Play-Metadaten mit Fastlane lokalisieren

Verwenden Sie den Fastlane-Befehl supply, um Play-Store-Metadaten – Titel, Kurzbeschreibung, vollständige Beschreibung und Änderungsprotokolle – als nach Locale gegliederte Nur-Text-Dateien in Ihrem Repository zu verwalten.

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
Ein lokalisierter Play-Store-Eintrag steigert Downloads in nicht englischsprachigen Märkten um mehr als 30 %. Titel, Kurzbeschreibung und vollständige Beschreibung werden für die Suche indexiert – ihre Übersetzung ist die Lokalisierungsmaßnahme mit der höchsten Rendite.
Google Play

Lokalisierung Ihres Play-Store-Eintrags automatisieren

Verzichten Sie auf manuelles Kopieren und Einfügen. Übersetzen Sie Titel, Beschreibung und Versionshinweise Ihres Play-Store-Eintrags unter Berücksichtigung der Zeichenbegrenzungen in mehr als 175 Locales.

Google-Play-Integration entdecken
7

Lokalisierung testen

Testen Sie mit dem Locale-Wechsel des Emulators, Compose-Vorschauen mit benutzerdefinierter LocaleList und Pseudo-Locales in den Entwickleroptionen. Entfernen Sie mit resConfigs in Gradle unerwünschte Locale-Ressourcen aus Drittanbieterbibliotheken.

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
Testen Sie mit Deutsch (Text wird etwa 30 % länger) und Japanisch (etwa 50 % kürzer), um Layoutprobleme zu erkennen. Aktivieren Sie in den Entwickleroptionen Pseudo-Locales (en-XA für Akzente, ar-XB für RTL), um Layouts ohne echte Übersetzungen zu belasten.

Übersetzungsqualität automatisieren

Erkennen Sie mit i18n-validate fehlende Schlüssel, beschädigte Platzhalter und Probleme mit Pluralformen vor der Veröffentlichung. Testen Sie Ihre Benutzeroberfläche mit i18n-pseudo und Pseudoübersetzungen, bevor echte Übersetzungen vorliegen.
8

Übersetzungen automatisieren

Übersetzen Sie Ihre strings.xml, Pluralformen, Zeichenfolgenarrays und Fastlane-Supply-Metadaten mit KI. Automatisieren Sie sowohl die Übersetzung der Zeichenfolgen in der App als auch der Play-Store-Metadaten für einen vollständig lokalisierten Auftritt.

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 verarbeitet die XML-Maskierung von Android, erhält translatable="false"-Markierungen, berücksichtigt die CLDR-Pluralkategorien jeder Zielsprache und hält positionsbezogene Formatargumente intakt.
JetBrains

Android-Studio-Plug-in verfügbar

Übersetzen Sie Android-XML-Ressourcen direkt aus Ihrer IDE mit dem i18n-Agent-Plug-in für IntelliJ / Android Studio.

Install
+

Bonus: intelligenter Locale-Fallback mit LocaleChain

Der Ressourcen-Fallback von Android wird durch das Betriebssystem gesteuert. Fehlen pt-BR-Übersetzungen, überspringt Android pt-PT vollständig und zeigt Englisch an. LocaleChain fängt Zeichenfolgenabfragen ab und durchläuft eine konfigurierbare Fallback-Kette, sodass Personen mit regionalen Einstellungen die ähnlichste verfügbare Übersetzung sehen.

LocaleChain für Android ist eine quelloffene Kotlin-Bibliothek. Auf GitHub ansehen

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

Häufige Fallstricke

Fehlende Standardzeichenfolgen verursachen Abstürze

Anders als iOS, das den unverarbeiteten Schlüssel anzeigt, stürzt Android mit einer ResourceNotFoundException ab, wenn eine Zeichenfolge in der standardmäßigen res/values/strings.xml fehlt. Stellen Sie stets sicher, dass jeder Schlüssel in der Standarddatei vorhanden ist.

Sprachaufteilungen von App Bundles verhindern den Sprachwechsel in der App

Google Play App Bundles teilen APKs nach Sprache auf – Personen erhalten nur die Zeichenfolgen ihrer Gerätesprache. Wenn Sie einen Sprachwechsel in der App anbieten, fügen Sie bundle '{ language { enableSplit = false } }' zu Ihrer build.gradle.kts hinzu.

RTL-Layouts werden beschädigt

Ursachen sind left/right statt start/end in Layouts oder ein fehlendes android:supportsRtl="true" in AndroidManifest.xml. Verwenden Sie Refactor > Add RTL Support in Android Studio, um vorhandene Layouts automatisch zu konvertieren.

Verunreinigung durch Bibliotheksressourcen

Drittanbieterbibliotheken enthalten eigene values-XX/strings.xml-Dateien, sodass Android annimmt, Ihre App unterstütze Sprachen, die sie tatsächlich nicht unterstützt. Beschränken Sie mit resConfigs in build.gradle.kts die enthaltenen Locales auf die tatsächlich übersetzten.

Empfohlene Dateistruktur

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

i18n Agent jetzt testen

Legen Sie Ihre Übersetzungsdatei hier ab

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

oder zum Auswählen klicken

Zielsprachen

Keine Registrierung erforderlichSofortiges Angebot

Locale-Fallback mit locale-chain-android

Fehlt ein Übersetzungsschlüssel in einer regionalen Locale wie pt-BR, wechselt Android direkt zum Standardressourcenordner, statt zuerst die übergeordnete Locale pt zu prüfen.

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

In unserem Leitfaden zu Locale-Fallbacks finden Sie die vollständige Liste unterstützter Frameworks und 75 integrierter Ketten. Learn more →

Häufig gestellte Fragen zur Android-Lokalisierung