
Ang Kumpletong Gabay sa Android App Localization
Mula strings.xml hanggang Play Store metadata: i-localize ang Android app ninyo gamit ang Kotlin, Jetpack Compose, Fastlane, at automated AI translation.
I-set Up ang Android Project Ninyo para sa Localization
Gumagamit ang Android ng folder-based na convention para sa localization. Nasa res/values/strings.xml ang mga default string ninyo, at napupunta ang mga isinaling string sa mga locale-specific na folder tulad ng res/values-de/, res/values-ja/, atbp.
// 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-rTWGumawa ng strings.xml
Gumagamit ang Android string resources ng XML na may mga <string> element sa loob ng <resources> root. Gamitin ang %s para sa mga string placeholder, %d para sa mga integer, at %1$s/%2$s para sa mga positional argument na puwedeng i-reorder ng mga tagasalin.
<!-- 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><!-- ❌ 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>Hawakan ang Plurals
Gumagamit ang Android ng <plurals> element na may quantity attribute: zero, one, two, few, many, other. Maaaring magkaiba ang kailangang kategorya ng bawat target na wika—ginagamit ng Arabic ang lahat ng 6, kailangan ng Russian ang few/many, at other lang ang ginagamit ng Japanese.
<!-- 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
) -->Gamitin sa Code: Kotlin at Jetpack Compose
Gumagamit ang tradisyonal na Android ng getString(R.string.key) at resources.getQuantityString(). Gumagamit ang Jetpack Compose ng stringResource(R.string.key) at pluralStringResource(). Pareho nitong nireresolba ang tamang pagsasalin batay sa device locale sa runtime.
// 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
))
}String Arrays at Formatted Strings
Gumamit ng <string-array> para sa mga ordered list (hal., mga opsyon sa dropdown, mga onboarding step). Gumamit ng mga positional format arg (%1$s, %2$d) sa mga formatted string para ma-reorder ng mga tagasalin ang mga salita nang hindi nasisira ang istruktura ng pangungusap.
<!-- 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>I-localize ang Google Play Metadata gamit ang Fastlane
Gamitin ang supply command ng Fastlane para i-manage ang Play Store metadata—title, short description, full description, at changelog—bilang mga plain text file na nakaayos ayon sa locale sa repository ninyo.
# 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 supplyI-automate ang Localization ng Play Store Listing Ninyo
Laktawan ang manu-manong copy-paste. Isalin ang Play Store title, description, at release notes sa 175+ locale na may awareness sa character limit.
Tuklasin ang Integrasyon sa Google PlayI-test ang Inyong Localization
Mag-test gamit ang emulator locale switching, Compose preview na may custom LocaleList, at mga pseudolocale sa Developer Options. Gamitin ang resConfigs sa Gradle para alisin ang hindi gustong locale resource mula sa mga third-party library.
// 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 mirroringI-automate ang Kalidad ng Pagsasalin
I-automate ang mga Pagsasalin
Isalin ang strings.xml, plurals, string array, at Fastlane Supply metadata ninyo gamit ang AI. I-automate ang pagsasalin ng parehong in-app string at Play Store metadata para sa ganap na na-localize na presensya.
# 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.2sAvailable ang Android Studio Plugin
Isalin ang Android XML resource nang direkta mula sa inyong IDE gamit ang i18n Agent plugin para sa IntelliJ / Android Studio.
Bonus: Smart Locale Fallback gamit ang LocaleChain
OS-controlled ang Android resource fallback. Kapag nawawala ang mga pagsasalin sa pt-BR, nilalaktawan ng Android ang pt-PT at ipinapakita ang English. Hinahadlangan ng LocaleChain ang mga string lookup at sinusundan ang isang configurable fallback chain—kaya nakikita ng mga regional user ang pinakamalapit na magagamit na pagsasalin.
Ang LocaleChain para sa Android ay isang open-source Kotlin library. View on GitHub
// build.gradle.kts (app module)
dependencies {
implementation("com.i18nagent:locale-chain-android:0.1.0")
}// 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"))
)Mga Karaniwang Pitfall
Nagdudulot ng Pagka-crash ang Nawawalang Default String
Nasasira ng App Bundle Language Split ang In-App Switching
Nasirang RTL Layout
Kontaminasyon ng Resource ng Library
Iminungkahing File 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.ktsSubukan ang i18n Agent Ngayon
I-drop dito ang inyong translation file
JSON, YAML, PO, XML, CSV, Markdown, Properties
o i-click para mag-browse
Mga target language
Locale Fallback gamit ang locale-chain-android
Kapag nawawala ang translation key sa isang regional locale tulad ng pt-BR, diretsong tumatalon ang Android sa default resource folder sa halip na i-check muna ang parent locale na pt.
implementation("com.i18nagent:locale-chain-android:0.1.0")import com.i18nagent.localechain.LocaleChain
LocaleChain.configure(
overrides = mapOf(
"pt-BR" to listOf("pt", "en"),
"zh-Hant-HK" to listOf("zh-Hant", "zh", "en"),
)
)Tingnan ang aming Locale Fallback Guide para sa buong listahan ng mga sinusuportahang framework at 75 built-in chain. Learn more →