# General Translation Knowledge Base: strings.xml で Android アプリをローカライズするには？
URL: https://generaltranslation.com/ja/kb/localize-android-app.mdx
Docs index: https://generaltranslation.com/llms.txt
Description: デフォルトの文字列はすべて res/values/strings.xml に置き、values-es や values-b+zh+Hant+TW のようなロケール修飾子付きフォルダーに言語ごとの strings.xml を追加して、stringResource または getString でテキストを読み込みます。翻訳は手作業、Play Console、または General Translation の CLI で行えます。CLI は各 values フォルダーを自動で書き出し、対象言語ごとに複数形を再構築します。
Category: 国際化
Last updated: 2026-10-28
Authors: General Translation Team
Published: 2026-10-28

Android は実行時に、デバイスのロケールに対応する名前のフォルダーからリソースを選びます。デフォルトのテキストは `res/values/strings.xml` に置き、各翻訳は `res/values-es/` のようなフォルダーに、同じリソース名を持つ別の `strings.xml` として配置します。つまり、やるべきことは 2 つです。ユーザーに表示される文字列をすべて `strings.xml` に集めること、そして各言語フォルダーに質の高い翻訳を用意することです。

## 文字列リソースを設定する

### すべての文字列を res/values/strings.xml に記述する

デフォルトのファイルには、アプリで使用するすべての文字列を含める必要があります。Android のローカライゼーションガイドによると、文字列が 1 つでも欠けているとアプリは「実行されず、エラーが表示されます」。一方、翻訳済みファイルには文字列の部分集合だけを含めることができ、含まれていない文字列はデフォルトにフォールバックします ([Android: Localize your app](https://developer.android.com/guide/topics/resources/localization)) 。

以下は、必要なパターンをそれぞれ注釈付きで示したデフォルトファイルの例です。

```xml title="res/values/strings.xml"
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <!-- カート内の商品の支払いを開始するボタン。 -->
    <string name="checkout">Checkout</string>

    <!-- 位置指定引数を使うと、翻訳側で値の順序を入れ替えられます。 -->
    <plurals name="welcome">
        <item quantity="one">Hi %1$s, you have %2$d new message.</item>
        <item quantity="other">Hi %1$s, you have %2$d new messages.</item>
    </plurals>

    <!-- アポストロフィはエスケープしてください。エスケープしないとビルドが失敗します。 -->
    <string name="cart_empty">Your cart\'s empty</string>

    <!-- xliff:g は翻訳対象外のテキストを示します。 -->
    <string name="countdown"><xliff:g id="time" example="5 days">%1$s</xliff:g> until your trial ends</string>

    <plurals name="items_in_cart">
        <item quantity="one">%d item</item>
        <item quantity="other">%d items</item>
    </plurals>

    <string-array name="sort_options">
        <item>Newest</item>
        <item>Price: low to high</item>
    </string-array>
</resources>
```

Compose では `stringResource`、`pluralStringResource`、`stringArrayResource` で読み込みます。Views の場合は `context.getString` と `resources.getQuantityString` を使用します ([Android: String resources](https://developer.android.com/guide/topics/resources/string-resource)) 。複数形の場合は、まず形式を選択するための数を渡し、続いてプレースホルダーに入れる値を渡します。この値には数そのものも含めます。

```kotlin
val greeting = pluralStringResource(R.plurals.welcome, count, name, count)
val cart = pluralStringResource(R.plurals.items_in_cart, count, count)
val sortOptions = stringArrayResource(R.array.sort_options)
```

React Native アプリにもこのファイルがあります。テンプレートに含まれる `android/app/src/main/res/values/` 配下の `strings.xml` には、Android がアイコンの下に表示するラベル `app_name` が定義されています。一方、JavaScript 側の UI は別途翻訳します。 ([React Native アプリを翻訳するには？](/kb/translate-react-native-app)を参照してください。)

### 言語ごとにフォルダに名前を付ける

言語フォルダの名前は、`values-` にリソース修飾子を付けたものです。言語は ISO 639-1 コードで指定し、リージョンには小文字の `r` プレフィックスを付けます。文字体系や数値のリージョンを含む場合は BCP 47 形式を使用します。これは `b+` の後に `+` で連結したサブタグを続ける形式で、Android 7.0 (API 24) 以降でサポートされています ([Android: App resources overview](https://developer.android.com/guide/topics/resources/providing-resources)) 。

| 言語               | ロケールコード      | フォルダ                       |
| ---------------- | ------------ | -------------------------- |
| スペイン語            | `es`         | `res/values-es/`           |
| ポルトガル語 (ブラジル)    | `pt-BR`      | `res/values-pt-rBR/`       |
| スペイン語 (ラテンアメリカ)  | `es-419`     | `res/values-b+es+419/`     |
| 中国語 (繁体字、台湾)     | `zh-Hant-TW` | `res/values-b+zh+Hant+TW/` |

地域別のフォルダには、内容が異なる文字列だけを追加してください。Android の例では、英語の文字列はすべて `values/` に置き、英国式の綴りだけを `values-en-rGB/` に置いています。それ以外の文字列はフォールバックされます ([ロケールコードとは？](/kb/locale-codes)を参照) 。

### 翻訳で壊れない文字列を書く

Android の [文字列リソースガイド](https://developer.android.com/guide/topics/resources/string-resource) にある以下のルールに従えば、翻訳が原因でビルドが失敗したり文法が崩れたりするのを防げます。

* **複数形は各言語の文法に従います。** 数量には `zero`、`one`、`two`、`few`、`many`、`other` がありますが、各言語が使うのは文法上必要なものだけです。英語は 0 でも `zero` を使わず、中国語と韓国語は常に `other` のみを使います。「項目なし」を表すために `<plurals>` を `if` 文代わりに使わず、別の文字列を用意してください。
* **位置指定引数を使います。** `%1$s` や `%2$d` を使えば、対象言語の語順に合わせて、翻訳者が名前を数量の後ろに移動できます。
* **アポストロフィと引用符をエスケープします。** `\'` と書くか、文字列全体をダブルクォートで囲みます。引用符そのものを表すには `\"` と書きます。先頭の `@` や `?` は `\@` や `\?` のようにエスケープしてください。エスケープしないと、Android はその値をリソース参照として解釈します。
* **変更してはいけない部分を保護します。** カウントダウン文字列の例のように、プレースホルダーや URL を `<xliff:g>` でラップし、`id` と `example` を指定します ([Android: Localize your app](https://developer.android.com/guide/topics/resources/localization)) 。
* **翻訳不要のリソースを明示します。** アプリ名などの値には `translatable="false"` を追加するか、`donottranslate.xml` ファイルに移動します。
* **コメントを残します。** リソースの上にコメントを書いておけば、テキストが表示される場所や使えるスペースを翻訳者に伝えられます。「Checkout」だけでは、名詞なのか動詞なのか判断できません。

## ユーザーがアプリの言語を選択できるようにする

Android 13 (API 33) 以降では、サポートする言語を宣言しているアプリであれば、ユーザーがシステム設定からアプリごとに言語を設定できます。`generateLocaleConfig` を有効にすると、Android Gradle Plugin (AGP) 8.1 以降がビルド時に `values-*` フォルダから言語リストを自動生成します。これには `compileSdk` 33 以上と、デフォルトフォルダのロケールを指定した `res/resources.properties` ファイル (例：`unqualifiedResLocale=en-US`) が必要です。言語を手動で列挙する場合は、代わりに `res/xml/locale_config.xml` を追加し、マニフェストの `android:localeConfig` でこのファイルを指定してください。両方を設定するとビルドが失敗します ([Android: Per-app language preferences](https://developer.android.com/guide/topics/resources/app-languages)) 。

```kotlin title="app/build.gradle.kts"
android {
    androidResources {
        generateLocaleConfig = true
    }
}
```

アプリ内に言語選択を実装するには、AppCompat 1.6.0 以降を使用し、メインスレッドで `setApplicationLocales` を呼び出します。この呼び出しによってアクティビティが再作成されます。また、Compose を使用する場合は、アクティビティが `AppCompatActivity` を継承している必要があります。

```kotlin
// メインスレッドで呼び出してください。Activity が再起動される場合があります。
AppCompatDelegate.setApplicationLocales(LocaleListCompat.forLanguageTags("es"))
```

Android 12 以前では、マニフェストに AppCompat の `AppLocalesMetadataHolderService` を追加して `autoStoreLocales` を `true` に設定すると、ユーザーの選択を AppCompat が自動で保存してくれます。 (言語選択 UI の設計については、[言語切り替え機能のベストプラクティス](/kb/language-switcher)を参照してください。)

## 不足している文字列とハードコードされた文字列を検出する

Android Studio の **Translations Editor** では、すべてのキーが言語ごとに 1 列ずつのグリッドで表示され、問題のある箇所は赤色で示されます。`strings.xml` を右クリックし、**Open Translations Editor** を選択してください。地球アイコンから言語を追加すると、その言語の `values-*` フォルダが作成されます。また、**Untranslatable** チェックボックスをオンにすると、`translatable="false"` が自動的に追加されます ([Android: Translations Editor](https://developer.android.com/studio/write/translations-editor)) 。

Android Lint を使えば、CI でも同じ項目をチェックできます。

* [`MissingTranslation`](https://googlesamples.github.io/android-custom-lint-rules/checks/MissingTranslation.md.html) (error) は、特定の言語で不足している文字列を検出します。リソース単位で抑制するには `tools:ignore="MissingTranslation"` を使用します。また、lint がデフォルトファイルの言語を認識できるよう、そのファイルの `<resources>` 要素に `tools:locale` を設定してください。
* [`ExtraTranslation`](https://googlesamples.github.io/android-custom-lint-rules/checks/ExtraTranslation.md.html) (fatal) は、デフォルトが存在しない翻訳済み文字列を検出します。このような文字列があると、その文字列が定義されていないロケールでアプリがクラッシュする可能性があります。
* [`HardcodedText`](https://googlesamples.github.io/android-custom-lint-rules/checks/HardcodedText.md.html) (warning) は、レイアウト XML 内のリテラルテキストを検出します。ただし、Compose の `Text("...")` 呼び出しは検出対象外です。 ([翻訳されていないハードコードされた文字列を見つけるには？](/kb/find-hardcoded-strings)を参照してください。)

## すべての言語をテストする

Android には、翻訳が揃う前のテスト用に 2 つの疑似ロケールが用意されています。`en-XA` はアクセント記号を付加し、テキストを長くし、各メッセージを括弧で囲むため、切り詰めや文の連結による問題を発見しやすくなります。`ar-XB` はテキストを右から左の表示に切り替えます。デバッグ用のビルドタイプで `isPseudoLocalesEnabled = true` を設定し、デバイスで開発者向けオプションを有効にしたうえで、言語設定から疑似ロケールを選択します ([Android: Test with pseudolocales](https://developer.android.com/guide/topics/resources/pseudolocales)) 。 ([疑似ローカライゼーションとは？](/kb/pseudo-localization)を参照してください。) 

アラビア語、ヘブライ語、ペルシア語に対応するには、`<application>` 要素に `android:supportsRtl="true"` を設定し、`left` と `right` の代わりに `start` と `end` の属性 (`paddingStart`、`layout_marginEnd`) を使用して、レイアウトが左右反転するようにします。方向性のある drawable には `android:autoMirrored="true"` を追加します。また、文中に挿入する値はすべて `BidiFormatter.unicodeWrap()` でラップし、住所や数値の書字方向が崩れないようにします ([Android: Support different languages and cultures](https://developer.android.com/training/basics/supporting-devices/languages)) 。Compose では、`@Preview(locale = "ar")` を使うと画面を右から左でプレビューできます。 (Web での対応方法については [CSS で RTL (右から左) 言語をサポートするには？](/kb/right-to-left-css)を参照してください。) 

Google Play のストア掲載情報は、アプリとは別に翻訳する必要があります。Play Console でストア掲載情報を開き、**Manage translations** をクリックして、言語ごとにタイトル、簡単な説明、詳しい説明、ローカライズしたグラフィックを追加します ([Play Console Help: Translate and localize your app](https://support.google.com/googleplay/android-developer/answer/9844778)) 。

## 翻訳方法を選ぶ

`values-*` フォルダを埋める方法には、次のようなものがあります。

| 方法                            | 翻訳する人                           | 翻訳者が得られる文脈                    | リリースごとに繰り返せるか                                                      | 自分で対応すること                                    |
| ----------------------------- | ------------------------------- | ----------------------------- | ------------------------------------------------------------------ | -------------------------------------------- |
| Translations Editor で入力する     | 自分、またはバイリンガルのチームメンバー            | アプリ全体                         | いいえ                                                                | すべての言語のすべての文字列を手作業で入力                        |
| Play Console のアプリ文字列翻訳        | Play Console の Gemini モデル (無料)  | `strings.xml`                 | はい (下書きリリースにアップロードするバンドルごと)                                        | 翻訳はリポジトリではなく Play 上に保存され、選択した言語の既存の翻訳は上書きされる |
| 翻訳者または翻訳管理システム (TMS) にファイルを送る | プロの翻訳者                          | コメントと、添付したスクリーンショット           | TMS の同期機能で対応                                                       | リリースごとのやり取りと、その待ち時間                          |
| 機械翻訳や LLM で XML をスクリプト処理する    | モデルまたは翻訳 API                    | スクリプトが送信する内容のみ                | はい                                                                 | 言語ごとの複数形カテゴリ、エスケープ、`<xliff:g>` 要素、書式引数、レビュー  |
| General Translation CLI       | GT の翻訳サービス                      | リソースのコメントに加え、共有の用語集とカスタムプロンプト | ビルド前に [`gt translate`](/docs/cli/reference/commands/translate) を実行 | ダッシュボードまたは Android Studio でのレビューと、アプリのテスト    |

Play Console でアプリ自体を翻訳することもできます。アプリ文字列翻訳を有効にすると、下書きリリースにアップロードしたアプリバンドルごとに、最新の `strings.xml` から翻訳が生成されます。生成された翻訳は、公開前にエミュレータでプレビューして編集できます。なお、言語を選択すると、その言語の既存の翻訳はすべて置き換えられます。個々の文字列は **Translate** チェックボックスで翻訳対象から外せます ([Play Console ヘルプ](https://support.google.com/googleplay/android-developer/answer/9844778)) 。

自分が話せる 1〜2 言語だけなら、Translations Editor が適しています。Google Play で公開していて、翻訳をコードベースに含める必要がなければ、Play Console の翻訳を使いましょう。翻訳済みの `strings.xml` ファイルをリリースごとにコミットし、iOS アプリや Web サイトと用語を統一したい場合は、General Translation がおすすめです。プロの翻訳者や既存の翻訳ベンダーに作業を任せる場合は、[TMS](/kb/what-is-a-translation-management-system) を使いましょう。

## General Translation で strings.xml を翻訳する

General Translation の CLI である `gt` では、`androidStrings` ファイルキーを使って Android の文字列リソースを翻訳できます (`gt` 2.19.0 以降) 。デフォルトのファイルはパスにロケールを含まないため、`include` でそのファイルを指定し、`transform` で各翻訳を対応する言語フォルダに振り分けてください：

```json title="gt.config.json"
{
  "defaultLocale": "en",
  "locales": ["es", "pt-BR", "zh-Hant-TW"],
  "files": {
    "androidStrings": {
      "include": ["app/src/main/res/values/strings.xml"],
      "transform": {
        "match": "res/values/(.*)",
        "replace": "res/values-{locale}/$1"
      }
    }
  }
}
```

CLI は各ロケールを Android が想定する修飾子に変換するため、この設定では `values-es/`、`values-pt-rBR/`、`values-b+zh+Hant+TW/` が書き出されます。標準的なプロジェクトでは `values-[locale]` パターンを使用しないでください。このパターンでは `values-en/` フォルダを探すことになり、何も一致しないため、何も翻訳されません。

CLI は Node.js 20 以降で動作します。[CLI クイックスタート](/docs/cli/quickstart)の手順に従ってインストールし、[`npx gt login`](/docs/cli/reference/commands/login) でサインインしたうえで、`GT_PROJECT_ID` を設定します ([CLI の認証情報](/docs/cli/guides/configuring#credentials)) 。既存の翻訳があるアプリでは、[`npx gt upload`](/docs/cli/reference/commands/upload) でそれらをインポートします。その後、[`npx gt translate`](/docs/cli/reference/commands/translate) を実行します。CI では、**Files &gt; Write** と **Translation queue &gt; Enabled** の権限を持つプロジェクトの APIキーを `GT_API_KEY` として保存してください。

翻訳済みファイルでは、リソース名、`<xliff:g>` 要素、書式引数、インラインマークアップが保持されます。また、翻訳された各文字列について、これらの要素に加え、Android のビルドで必要となるアポストロフィと引用符のエスケープもチェックされます。`<plurals>` は対象言語のカテゴリに合わせて再構築されます。ポーランド語では `one`、`few`、`many`、`other`、アラビア語では 6 つすべて、中国語では `other` のみが生成され、その言語で使われないカテゴリ (翻訳元の `zero` を含む) は削除されます。リソースの直前に記述されたコメントは文脈として送信されます。`translatable="false"` が指定されたリソース、別のリソースを参照する値、`<color>` などのテキスト以外の型は、CLI では翻訳されません ([strings.xml リファレンス](/docs/cli/reference/formats/android-strings-files)を参照) 。

対象に含めたファイル内で `translatable="false"` が指定されたリソースは、各翻訳済みファイルにそのままコピーされ、Android Lint の [`Untranslatable`](https://googlesamples.github.io/android-custom-lint-rules/checks/Untranslatable.md.html) チェックによって、そのコピーすべてに警告が出されます。こうした値は `res/values/donottranslate.xml` にまとめ、`strings.xml` のみを対象に含めてください。

翻訳は[ダッシュボード](/docs/platform/dashboard/guides/reviewing-translations)または Android Studio でレビューできます。ローカルでファイルを編集した場合は、[`npx gt save-local`](/docs/cli/reference/commands/save-local) を実行しておくと、以降の実行でも変更が保持されます。Android、[iOS](/kb/localize-ios-app)、Web の各プロジェクトに同じ[コンテキストグループ](/docs/platform/dashboard/guides/defining-context-for-translations)を割り当てれば、プラン名などの用語集の用語をすべてのプラットフォームで統一して翻訳できます。Partiful は、Web、iOS、Android にわたる 2 つ以上のロケールで General Translation を利用しています ([本番環境でのデプロイ事例](https://generaltranslation.com/enterprise)) 。

## よくある質問

### 英語用の values-en フォルダーは必要ですか？

いいえ。修飾子なしの `values/` フォルダーは、翻訳していないすべてのロケールで使用されます。`generateLocaleConfig` を有効にすると、そのフォルダーがどのロケールのものかが `resources.properties` を通じてビルドに伝えられます。

### 翻訳したアプリで一部の文字列が英語のまま表示されるのはなぜですか？

翻訳済みの `strings.xml` にそれらの名前が含まれていないため、Android が `values/` にフォールバックしています。Lint の `MissingTranslation` チェックを使うと、不足している名前を言語ごとに確認できます。

### Google Play はストアの掲載情報を自動で翻訳しますか？

翻訳を用意していない言語で掲載情報を閲覧しているユーザーは、自動翻訳を選んで表示できます。**Manage translations** で独自の翻訳を追加すると、追加した言語では自動翻訳の代わりにその翻訳が表示されます。

## 重要なポイント

* `res/values/strings.xml` にはすべての文字列を含める必要があります。翻訳済みフォルダには一部の文字列 (部分集合) だけを置くこともでき、不足分はこのファイルにフォールバックします。
* フォルダ名には修飾子を使用します。リージョンは `values-pt-rBR`、文字体系は `values-b+zh+Hant+TW` のように指定します。
* `%1$s` などの位置指定引数を使い、アポストロフィはエスケープします。また、`<plurals>` のカテゴリは言語ごとに定義できるようにします。
* Android 13 のアプリ別言語設定に対応するには `generateLocaleConfig` (AGP 8.1 以降) を有効にし、疑似ロケール `en-XA` と `ar-XB` でテストします。
* General Translation の CLI は、`androidStrings` と `transform` を使って `strings.xml` を翻訳し、`values-{locale}` に出力します。その際、Android が想定する修飾子でフォルダを作成し、複数形も言語ごとに再構築します。

## Related questions

- [String Catalog を使って iOS アプリをローカライズするには？](https://generaltranslation.com/ja/kb/localize-ios-app.mdx): Xcode で言語を追加し、SwiftUI の Text や String(localized:) などのローカライズ可能な API でユーザー向けテキストを記述してからビルドすると、Xcode がそれらの文字列を String Catalog（.xcstrings）に収集します。翻訳は Xcode 上または XLIFF 経由で行えます。リリースに合わせてカタログを更新し、Web サイトや Android アプリと用語を共有したい場合は、General Translation の CLI を使用してください。
- [React Native アプリを翻訳するにはどうすればよいですか？](https://generaltranslation.com/ja/kb/translate-react-native-app.mdx): コンポーネント内のテキストをマークし、言語ごとに翻訳ファイルを生成して Intl ポリフィルを追加し、デバイスの言語に対応するファイルを読み込みます。General Translation の実験的な gt-react-native では、テキストを `<T>` でラップするだけで、Babel プラグインがポリフィルを追加し、npx gt translate がファイルを書き出します。
- [疑似ローカライゼーションとは？](https://generaltranslation.com/ja/kb/pseudo-localization.mdx): 疑似ローカライゼーションは、原文をアクセント記号付きで約40%長く水増しし、括弧で囲んだ改変版に置き換えるテストです。これにより、ハードコードされた文字列、切り詰め、フォントの表示崩れ、文の連結といった問題を、翻訳を用意する前に発見できます。Android にはこの用途向けに en-XA と ar-XB の疑似ロケールが用意されています。
- [翻訳されていないハードコードされた文字列を見つけるにはどうすればよいですか？](https://generaltranslation.com/ja/kb/find-hardcoded-strings.mdx): CI でリンターを実行し、ユーザー向けの文字列リテラルを検出します。たとえば JSX なら eslint-plugin-i18next の no-literal-string ルール、Android なら Android Lint の HardcodedText チェック、Rails なら erb_lint の HardCodedString リンターが使えます。さらに、疑似ロケールでアプリを一通り操作し、静的チェックでは追跡できないテキストを洗い出します。
- [CSS で RTL（右から左）言語をサポートするには？](https://generaltranslation.com/ja/kb/right-to-left-css.mdx): lang だけでは書字方向は変わらないため、html 要素に dir="rtl" と lang の両方を指定します。そのうえで、margin-left などの物理的な CSS を margin-inline-start などの論理プロパティに置き換えます。flex の行、グリッドの列、デフォルトのテキストの配置は自動的に反転しますが、translateX()、left、right は反転しません。

## Previous and next questions

- Previous question: [SEO用のタイトルとメタディスクリプションはどのように翻訳すればよいですか？](https://generaltranslation.com/ja/kb/translate-seo-metadata.mdx)
- Next question: [TanStack Start に i18n を追加するには？](https://generaltranslation.com/ja/kb/add-i18n-to-tanstack-start.mdx)

## Sitemap

See the [Knowledge Base sitemap](https://generaltranslation.com/ja/kb/sitemap.md) for every article.
