Skip to main content

Android アプリのローカリゼーション完全ガイド

strings.xml から Play Store メタデータまで。Kotlin、Jetpack Compose、Fastlane、AI 自動翻訳を使用して Android アプリをローカライズする方法を解説します。

1

Android プロジェクトにローカリゼーションを設定

Android のローカリゼーションでは、フォルダーに基づく規則を使用します。デフォルトの文字列は res/values/strings.xml に置き、翻訳済みの文字列は res/values-de/、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
res/values/ フォルダーがフォールバックロケールになります。ロケール別フォルダーに文字列がない場合、Android はデフォルトから読み込みます。ただし、デフォルトに文字列がないと、未対応のロケールでアプリがクラッシュします。
2

strings.xml を作成

Android の文字列リソースでは、ルートの '<resources>' 内に '<string>' 要素を記述する XML を使用します。文字列のプレースホルダーには %s、整数には %d、翻訳者が順序を入れ替えられる位置引数には %1$s/%2$s を使用します。

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>
エスケープされていないアポストロフィがあると、XML パーサーは通知なくクラッシュします。\' を使用するか、値を二重引用符で囲んでください。また、デフォルトの values/strings.xml に文字列がないと、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

複数形を処理

Android では、zero、one、two、few、many、other の quantity 属性を持つ '&lt;plurals&gt;' 要素を使用します。必要なカテゴリは対象言語によって異なります。アラビア語では 6 種類すべて、ロシア語では few と many、日本語では 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 属性は、デバイスのロケールに対応する CLDR ルールに基づいて複数形を選択します。フォールバックとして必ず 'other' を含めてください。すべての言語に必ず存在する唯一のカテゴリです。
4

コードで使用:Kotlin と Jetpack Compose

従来の Android では getString(R.string.key) と resources.getQuantityString() を使用します。Jetpack Compose では stringResource(R.string.key) と pluralStringResource() を使用します。どちらも実行時にデバイスのロケールに基づいて適切な翻訳を解決します。

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 パラメーターは 2 回渡します。最初の値で複数形を選択し、2 番目の値を形式引数として使用します。2 番目の count の指定漏れは、Compose で最も多い複数形処理のバグです。
5

文字列配列と書式付き文字列

順序のあるリスト(ドロップダウンの選択肢、オンボーディングの手順など)には '&lt;string-array&gt;' を使用します。翻訳者が文の構造を壊さずに語順を変更できるよう、書式付き文字列には位置形式引数(%1$s、%2$d)を使用します。

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>
%1$s のような位置引数を使うと、翻訳者はパラメーターを自由に並べ替えられます。語順が異なる言語では、コードを変更することなく、'Hello %1$s, you have %2$d items' を '%2$d items for %1$s' に変更できます。
6

Fastlane で Google Play メタデータをローカライズ

Fastlane の supply コマンドを使用すると、Play Store のメタデータ(タイトル、簡単な説明、詳しい説明、変更履歴)を、ロケール別のプレーンテキストファイルとしてリポジトリで管理できます。

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
Play Store の掲載情報をローカライズすると、英語圏以外の市場でダウンロード数が 30% 以上増加します。タイトル、簡単な説明、詳しい説明は検索用にインデックスされるため、その翻訳は最も高い ROI が期待できるローカリゼーション施策です。
Google Play

Play Store 掲載情報のローカリゼーションを自動化

手作業でのコピー&ペーストは不要です。文字数制限を考慮しながら、Play Store のタイトル、説明、リリースノートを 175 以上のロケールに翻訳します。

Google Play 統合を見る
7

ローカリゼーションをテスト

エミュレーターのロケール切り替え、独自の LocaleList を使用する Compose プレビュー、開発者向けオプションの疑似ロケールでテストします。Gradle の resConfigs を使用して、サードパーティライブラリから不要なロケールリソースを除外できます。

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
ドイツ語(テキストが約 30% 長くなります)と日本語(約 50% 短くなります)でテストし、レイアウトの問題を検出します。開発者向けオプションで疑似ロケール(アクセント付きの en-XA、RTL の ar-XB)を有効にすると、実際の翻訳がなくてもレイアウトを厳しく検証できます。

翻訳品質を自動管理

i18n-validate を使用し、キー不足、壊れたプレースホルダー、複数形の問題をリリース前に検出します。実際の翻訳が完成する前に、i18n-pseudo の疑似翻訳で UI をテストできます。
8

翻訳を自動化

AI を使用して、strings.xml、複数形、文字列配列、Fastlane Supply のメタデータを翻訳します。アプリ内文字列と Play Store メタデータの両方を自動翻訳し、あらゆる要素をローカライズできます。

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 は Android XML のエスケープを処理し、translatable="false" マーカーを保持します。また、対象言語ごとの CLDR 複数形カテゴリを順守し、位置形式引数をそのまま維持します。
JetBrains

Android Studio プラグインを提供

IntelliJ / Android Studio 向け i18n Agent プラグインを使用して、IDE から Android XML リソースを直接翻訳できます。

Install
+

追加機能:LocaleChain によるスマートなロケールフォールバック

Android のリソースフォールバックは OS によって制御されます。pt-BR の翻訳がない場合、Android は pt-PT を経由せずに英語を表示します。LocaleChain は文字列検索を仲介して、設定可能なフォールバックチェーンを順に確認するため、地域ロケールのユーザーには最も近い翻訳が表示されます。

Android 向け LocaleChain は、オープンソースの Kotlin ライブラリです。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"))
)

よくある落とし穴

デフォルト文字列の不足によりクラッシュする

未処理のキーを表示する iOS とは異なり、デフォルトの res/values/strings.xml に文字列がない場合、Android は ResourceNotFoundException でクラッシュします。すべてのキーがデフォルトファイルに存在することを必ず確認してください。

App Bundle の言語分割によりアプリ内切り替えが機能しない

Google Play App Bundle は APK を言語別に分割するため、ユーザーにはデバイス言語の文字列しか配信されません。アプリ内で言語を切り替えられるようにする場合は、build.gradle.kts に bundle '{ language { enableSplit = false } }' を追加してください。

RTL レイアウトが崩れる

レイアウトで start/end ではなく left/right を使用しているか、AndroidManifest.xml に android:supportsRtl="true" が指定されていません。Android Studio の Refactor > Add RTL Support を使用すると、既存のレイアウトを自動変換できます。

ライブラリのリソースによる対応言語の混入

サードパーティライブラリには独自の values-XX/strings.xml ファイルが含まれているため、実際には未対応の言語を Android がアプリの対応言語と判断する場合があります。build.gradle.kts で resConfigs を使用し、含めるロケールを実際に翻訳するものだけに制限してください。

推奨ファイル構成

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 を今すぐ試す

翻訳ファイルをここにドロップ

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

またはクリックしてファイルを選択

翻訳先言語

登録不要すぐに見積もり

locale-chain-android によるロケールフォールバック

pt-BR のような地域ロケールで翻訳キーが不足している場合、Android は最初に親ロケールの 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"),
    )
)

対応フレームワークと 75 種類の組み込みチェーンの完全な一覧については、ロケールフォールバックガイドをご覧ください。 Learn more →

Android ローカリゼーションに関するよくある質問