多言語ユーザーは、多くの場合、特定のアプリに対してシステムに設定した言語(英語など)とは別の言語(オランダ語、中国語、ヒンディー語など)を選択します。Android 13 では、このようなユーザーのエクスペリエンスを改善するために、複数の言語をサポートするアプリ向けに以下の機能を導入しています。
システム設定: ユーザーがアプリごとに使用する言語を一元的に選択できる場所。
アプリ別の言語設定のサポートとシステム設定への表示に必要なファイルを自動的に生成するようにアプリを構成できます。詳しくは、アプリ別の言語の自動サポートを有効にするをご覧ください。
その他の API:
LocaleManager
のsetApplicationLocales()
およびgetApplicationLocales()
メソッドといった公開 API を使用すると、アプリは実行時にシステム言語とは異なる言語を設定できます。これらの API はシステム設定と自動的に同期されます。そのため、これらの API を使用してカスタムのアプリ内言語選択ツールを作成するアプリでは、言語設定の選択内容にかかわらず、一貫したユーザー エクスペリエンスを提供できます。公開 API を使用すると、ボイラープレート コードの量を減らし、分割 APK をサポートして、アプリの自動バックアップによってアプリレベルの言語設定を保存できるようになります。
以前の Android バージョンとの下位互換性を維持するため、AndroidX でも等価の API を使用できます。ただし、Android 12(API レベル 32)以前の場合、下位互換性のある API は、アプリ コンテキストではなく AppCompatActivity コンテキストで動作します。下位互換性のある API にアクセスするには、Appcompat 1.6.0 以降が必要です。
この機能の実装の概要
次の表に、さまざまなユースケースに基づくおすすめの実装方法を示します。
ユースケース | おすすめの実装方法 |
---|---|
アプリにアプリ内言語選択ツールがない |
|
アプリにすでにアプリ内言語選択ツールがある |
|
ユーザーのためのシステム設定
Android 13 以降の Android では、アプリ別の言語設定を一元的に行う場所がシステム設定に用意されています。Android 13 以降を搭載したデバイスのシステム設定でアプリの言語を設定できるようにするには、アプリ別の言語の自動サポートを有効にするか(推奨)、手動でサポートを構成します。
アプリ別の言語の自動サポートを有効にする
Android Studio Giraffe と AGP 8.1 以降では、アプリで自動的にアプリ別の言語設定をサポートするように設定できます。AGP は、プロジェクト リソースに基づいて LocaleConfig
ファイルを生成し、そのファイルへの参照を最終マニフェスト ファイルに追加します。そのため、手動で行う必要はありません。AGP は、アプリ モジュールの res
フォルダ内のリソースと、ライブラリ モジュールの依存関係を使用して、LocaleConfig
ファイルに含めるロケールを決定します。そのため、アプリに新しい言語のリソースを追加しても、LocaleConfig
ファイルの更新を考慮する必要はありません。
自動のアプリ別の言語機能は、Android 13(API レベル 33)以降を実行するアプリをサポートしています。この機能を使用するには、compileSdkVersion
を 33 以上に設定する必要があります。以前のバージョンの Android のアプリ別の言語設定を設定するには、API とアプリ内言語選択ツールを使用する必要があります。
アプリ別の言語の自動サポートを有効にする手順は次のとおりです。
- この機能を有効にするには、モジュール レベルの
build.gradle.kts
ファイル(Groovy を使用している場合はbuild.gradle
ファイル)のandroidResources {}
ブロックでgenerateLocaleConfig
設定を使用します。デフォルトでは無効になっています。Kotlin
android { androidResources { generateLocaleConfig = true } }
Groovy
android { androidResources { generateLocaleConfig true } }
- デフォルトのロケールを指定します。
- アプリ モジュールの
res
フォルダに、resources.properties
という名前の新しいファイルを作成します。 resources.properties
ファイルで、unqualifiedResLocale
ラベルを使用してデフォルトのロケールを設定します。ロケール名をフォーマットするには、ロケール名を作成する方法をご覧ください。
- アプリ モジュールの
AGP は、このデフォルトのロケールと、res
フォルダの values-*
ディレクトリを使用して指定した代替ロケールを、自動生成された LocaleConfig
ファイルに追加します。
ロケール名を作成する方法
ロケール名を作成するには、言語コードをスクリプトや地域コード(省略可)と組み合わせ、それぞれをダッシュで区切ります。
- 言語: 2 文字または 3 文字の ISO 639-1 コードを使用します。
- スクリプト(省略可): ISO 15924 コードを使用します。
- 地域(省略可): 2 文字の ISO 3166-1-alpha-2 コードまたは 3 桁の UN_M.49 コードを使用します。
たとえば、デフォルトのロケールがアメリカ英語である場合は次のとおりです。
unqualifiedResLocale=en-US
android:localeConfig
を使用して対応言語をシステム設定に追加する
Android 13 以降を搭載したデバイスのシステム設定でアプリの言語を設定できるように、アプリを手動でセットアップできます。そのためには、locales_config
XML ファイルを作成し、android:localeConfig
属性を使用してアプリのマニフェストに追加します。android:localeConfig
マニフェスト エントリを省略すると、ユーザーはシステム設定で、システムの言語とは別にアプリの言語を設定できなくなります。
アプリの対応言語をユーザーのシステム設定に手動で追加するには:
res/xml/locales_config.xml
というファイルを作成し、アプリの言語を指定します。これにはアプリの最終的なフォールバック ロケール(res/values/strings.xml
で指定されるロケール)が含まれます。形式の要件については、ロケール名を作成する方法をご覧ください。よく使用されるロケールの一覧については、サンプル
locale_config.xml
ファイルもご覧ください。たとえば、次の言語をサポートするアプリでは、次のように
locales_config.xml
ファイルをフォーマットします。- 英語(米国)(最終的なフォールバック ロケール)
- 英語(英国)
- フランス語
- 日本語
- 中国語(簡体、マカオ)
- 中国語(繁体、マカオ)
<?xml version="1.0" encoding="utf-8"?> <locale-config xmlns:android="http://schemas.android.com/apk/res/android"> <locale android:name="en-US"/> <locale android:name="en-GB"/> <locale android:name="fr"/> <locale android:name="ja"/> <locale android:name="zh-Hans-MO"/> <locale android:name="zh-Hant-MO"/> </locale-config>
マニフェストにこの新しいファイルを指す行を追加します。
<manifest> ... <application ... android:localeConfig="@xml/locales_config"> </application> </manifest>
アプリの localeConfig
を LocaleManager.setOverrideLocaleConfig
で動的に更新して、Android の設定にあるアプリ別の言語リストに表示する言語セットをカスタマイズできます。これにより、
地域ごとに言語リストをカスタマイズし、A/B テストを実施して、
アプリでサーバーサイドのローカライズ プッシュを使用している場合は、
次の例をご覧ください。
Kotlin
//For setOverrideLocaleConfig val localeManager = applicationContext .getSystemService(LocaleManager::class.java) localeManager.overrideLocaleConfig = LocaleConfig( LocaleList.forLanguageTags("en-US,ja-JP,zh-Hans-SG") ) //For getOverrideLocaleConfig // The app calls the API to get the override LocaleConfig val overrideLocaleConfig = localeManager.overrideLocaleConfig // If the returned overrideLocaleConfig isn't equal to NULL, then the app calls the API to get the supported Locales val supportedLocales = overrideLocaleConfig.supportedLocales()
Java
//For setOverrideLocaleConfig mContext.getSystemService(LocaleManager.class).setOverrideLocaleConfig(new LocaleConfig(LocaleList.forLanguageTags("en-US,ja-JP,zh-Hans-SG"))); //For getOverrideLocaleConfig // The app calls the API to get the override LocaleConfig LocaleConfig overrideLocaleConfig = mContext.getSystemService(LocaleManager.class).getOverrideLocaleConfig(); // If the returned overrideLocaleConfig isn't equal to NULL, then the app calls the API to get the supported Locales LocaleList supportedLocales = overrideLocaleConfig.getSupportedLocales();
さらに、IME は
LocaleManager.getApplicationLocales
現在のアプリの UI 言語を把握し、キーボード言語を
表示:
Kotlin
val currentAppLocales: LocaleList = applicationContext.getSystemService(LocaleManager::class.java).getApplicationLocales(appPackageName)
Java
LocaleList currentAppLocales = mContext.getSystemService(LocaleManager.class).getApplicationLocales(appPackageName);
Gradle でサポートされる言語を指定する
まだ存在しない場合は、アプリのモジュール レベルの build.gradle
ファイルの resourceConfigurations
プロパティを使用して同じ言語を指定します。
android {
...
defaultConfig {
resourceConfigurations += ["en", "en-rGB", "fr", "ja", "b+zh+Hans+MO", "b+zh+Hant+MO"]
}
}
resourceConfigurations
プロパティが存在する場合、ビルドシステムは、これらの指定された言語の APK の言語リソースのみを使用します。そのため、アプリでサポートされていない言語をサポートしている可能性がある他のライブラリから翻訳済み文字列が読み込まれることはありません。詳細については、アプリがサポートする言語を指定するをご覧ください。
ユーザーがシステム設定でアプリの言語を選択する方法
ユーザーは、システム設定を使用してアプリごとの使用言語を選択できます。この設定にアクセスするには、次の 2 つの方法があります。
システム設定からアクセスする
[設定] > [システム] > [言語と入力] > [アプリの言語] >(アプリを選択)
アプリ設定からアクセスする
[設定] > [アプリ] >(アプリを選択)> [言語]
アプリ内言語選択ツールを処理する
アプリ内言語選択ツールをすでに備えているか使用する予定があるアプリの場合、アプリにおけるユーザーの使用言語の設定と取得を処理するには、アプリのカスタム ロジックの代わりに公開 API を使用してください。アプリ内言語選択ツールに公開 API を使用する場合、ユーザーがアプリ内エクスペリエンスで選択した言語に一致するように、デバイスのシステム設定が自動的に更新されます。
以前の Android バージョンとの下位互換性を維持するため、アプリ内言語選択ツールを実装する際に AndroidX サポート ライブラリを使用することを強くおすすめします。ただし必要に応じて、フレームワーク API を直接実装することもできます。
AndroidX サポート ライブラリを使用して実装する
Appcompat 1.6.0 以降の場合は、setApplicationLocales()
メソッドと getApplicationLocales()
メソッドを使用します。Android 12(API レベル 32)以前の場合、下位互換性のある API は、アプリ コンテキストではなく AppCompatActivity コンテキストで動作します。
たとえば、ユーザーの使用言語を設定するには、言語選択ツールでロケールを選択するようユーザーにリクエストし、その値をシステムに設定します。
Kotlin
val appLocale: LocaleListCompat = LocaleListCompat.forLanguageTags("xx-YY") // Call this on the main thread as it may require Activity.restart() AppCompatDelegate.setApplicationLocales(appLocale)
Java
LocaleListCompat appLocale = LocaleListCompat.forLanguageTags("xx-YY"); // Call this on the main thread as it may require Activity.restart() AppCompatDelegate.setApplicationLocales(appLocale);
setApplicationLocales()
を呼び出すと、Activity
が再作成されます。ただし、アプリ自体がロケール設定の変更を処理する場合を除きます。
AppCompatDelegate.getApplicationLocales()
を使用して、ユーザーの希望する言語 / 地域を取得します。ユーザーはシステム設定またはアプリ内言語選択ツールでアプリの言語 / 地域を選択している場合もあります。
Android 12 以下をサポートする
Android 12(API レベル 32)以下を搭載するデバイスをサポートするには、autoStoreLocales
の値を true
に設定し、android:enabled
を false
に設定してロケールの保存を処理するよう AndroidX に指示します。これは次のコード スニペットに示すように、アプリの AppLocalesMetadataHolderService
サービスのマニフェスト エントリ内で行います。
<application
...
<service
android:name="androidx.appcompat.app.AppLocalesMetadataHolderService"
android:enabled="false"
android:exported="false">
<meta-data
android:name="autoStoreLocales"
android:value="true" />
</service>
...
</application>
autoStoreLocales
の値を true
に設定すると、メインスレッドでのブロック読み取りの原因になります。スレッド違反をログに記録している場合は、StrictMode
diskRead
および diskWrite
違反になる可能性があります。詳しくは、AppCompatDelegate.setApplicationLocales()
をご覧ください。
カスタム ストレージの取り扱い
マニフェスト エントリを省略するか、autoStoreLocales
を false
に設定すると、独自のストレージを扱っていると示すことになります。その場合、Android 12(API レベル 32)以下では、アクティビティのライフサイクルで onCreate
の前に保存済みのロケールを指定し、AppCompatDelegate.setApplicationLocales()
への呼び出しを制御します。
アプリにカスタムのロケールの保存場所がある場合は、カスタム ロケール ストレージ ソリューションと autoStoreLocales
間で 1 回限りのハンドオフを使用し、ユーザーが任意の言語で引き続きアプリを使用できるようにすることをおすすめします。これは特に、デバイスが Android 13 にアップグレードされた後に初めてアプリを実行する場合に当てはまります。その場合は、カスタム ストレージからロケールを取得して AppCompatDelegate.setApplicationLocales()
に渡すことで、ユーザーがリクエストした既存のロケールを指定できます。
Android フレームワーク API を使用して実装する
AndroidX サポート ライブラリを使用してアプリ内言語選択ツールを実装することを強くおすすめしますが、Android 13 を搭載したデバイスでは、Android フレームワーク内で setApplicationLocales()
メソッドと getApplicationLocales()
メソッドを使用することもできます。
たとえば、ユーザーの使用言語を設定するには、言語選択ツールでロケールを選択するようユーザーにリクエストし、その値をシステムに設定します。
// 1. Inside an activity, in-app language picker gets an input locale "xx-YY"
// 2. App calls the API to set its locale
mContext.getSystemService(LocaleManager.class
).setApplicationLocales(new LocaleList(Locale.forLanguageTag("xx-YY")));
// 3. The system updates the locale and restarts the app, including any configuration updates
// 4. The app is now displayed in "xx-YY" language
ユーザー指定の言語を取得して言語選択ツールで表示する場合、システムからその値を取得します。
// 1. App calls the API to get the preferred locale
LocaleList currentAppLocales =
mContext.getSystemService(LocaleManager.class).getApplicationLocales();
// 2. App uses the returned LocaleList to display languages to the user
その他のおすすめの方法
次のおすすめの方法を考慮してください。
別のアプリからインテントを呼び出す場合は言語を指定する
言語中心のインテントでは、呼び出すアプリの言語を指定できる場合があります。一例として、Speech Recognizer API の EXTRA_LANGUAGE
機能があります。
Chrome カスタムタブで Accept-Language ヘッダーを使用する
Chrome カスタムタブを呼び出すときに、Browser.EXTRA_HEADERS
で Accept-Language ヘッダーを追加して、アプリで設定した言語でウェブページを開くことを検討してください。
システム設定でアプリ別の言語設定を削除する場合にはアプリの言語 / 地域をシステム ロケールにリセットする
システム設定からアプリの言語設定を削除する場合(アプリの AndroidManifest.xml
から android:localeConfig
を削除する場合)、ユーザーがアプリの言語をシステムのデフォルトにリセットするのは簡単ではありません。
このような理由から、android:localeConfig
を削除する場合は、LocaleListCompat.getEmptyLocaleList()
または LocaleList.getEmptyLocaleList()
を使用して、アプリの言語 / 地域をシステム ロケールにリセットすることを検討してください。次のコード スニペットに例を示します。
Kotlin
// Use the AndroidX APIs to reset to the system locale for backward and forward compatibility AppCompatDelegate.setApplicationLocales( LocaleListCompat.getEmptyLocaleList() ) // Or use the Framework APIs for Android 13 and above to reset to the system locale val context = LocalContext.current context.getSystemService(LocaleManager::class.java) .applicationLocales = LocaleList.getEmptyLocaleList()
Java
// Use the AndroidX APIs to reset to the system locale for backward and forward compatibility AppCompatDelegate.setApplicationLocales( LocaleListCompat.getEmptyLocaleList() ); // Or use the Framework APIs for Android 13 and above to reset to the system locale mContext.getSystemService(LocaleManager.class) .setApplicationLocales(LocaleList.getEmptyLocaleList());
参考情報
詳しくは、コードサンプル、ブログ記事、動画をご覧ください。
- アプリ別の言語設定パート 1 のブログ
- アプリ別の言語設定パート 2 のブログ
- サンプルアプリ
- 多言語対応の構築の動画
サンプル locale_config.xml ファイル
Android には、よく使用されるロケールの標準セットに対して、デフォルトで Android オープンソース プロジェクト(AOSP)のシステムレベルの翻訳が用意されています。このセクションに含まれるサンプル locale_config.xml
ファイルでは、各ロケールで推奨される形式が示されています。このサンプル ファイルを参照すれば、アプリがサポートする言語セット用に独自の locale_config.xml
ファイルを作成できます。
<?xml version="1.0" encoding="utf-8"?>
<locale-config xmlns:android="http://schemas.android.com/apk/res/android">
<locale android:name="af"/> <!-- Afrikaans -->
<locale android:name="am"/> <!-- Amharic -->
<locale android:name="ar"/> <!-- Arabic -->
<locale android:name="as"/> <!-- Assamese -->
<locale android:name="az"/> <!-- Azerbaijani -->
<locale android:name="be"/> <!-- Belarusian -->
<locale android:name="bg"/> <!-- Bulgarian -->
<locale android:name="bn"/> <!-- Bengali -->
<locale android:name="bs"/> <!-- Bosnian -->
<locale android:name="ca"/> <!-- Catalan -->
<locale android:name="cs"/> <!-- Czech -->
<locale android:name="da"/> <!-- Danish -->
<locale android:name="de"/> <!-- German -->
<locale android:name="el"/> <!-- Greek -->
<locale android:name="en-AU"/> <!-- English (Australia) -->
<locale android:name="en-CA"/> <!-- English (Canada) -->
<locale android:name="en-GB"/> <!-- English (United Kingdom) -->
<locale android:name="en-IN"/> <!-- English (India) -->
<locale android:name="en-US"/> <!-- English (United States) -->
<locale android:name="es"/> <!-- Spanish (Spain) -->
<locale android:name="es-US"/> <!-- Spanish (United States) -->
<locale android:name="et"/> <!-- Estonian -->
<locale android:name="eu"/> <!-- Basque -->
<locale android:name="fa"/> <!-- Farsi -->
<locale android:name="fi"/> <!-- Finnish -->
<locale android:name="fil"/> <!-- Filipino -->
<locale android:name="fr"/> <!-- French (France) -->
<locale android:name="fr-CA"/> <!-- French (Canada) -->
<locale android:name="gl"/> <!-- Galician -->
<locale android:name="gu"/> <!-- Gujarati -->
<locale android:name="hi"/> <!-- Hindi -->
<locale android:name="hr"/> <!-- Croatian -->
<locale android:name="hu"/> <!-- Hungarian -->
<locale android:name="hy"/> <!-- Armenian -->
<locale android:name="in"/> <!-- Indonesian -->
<locale android:name="is"/> <!-- Icelandic -->
<locale android:name="it"/> <!-- Italian -->
<locale android:name="iw"/> <!-- Hebrew -->
<locale android:name="ja"/> <!-- Japanese -->
<locale android:name="ka"/> <!-- Georgian -->
<locale android:name="kk"/> <!-- Kazakh -->
<locale android:name="km"/> <!-- Khmer -->
<locale android:name="kn"/> <!-- Kannada -->
<locale android:name="ko"/> <!-- Korean -->
<locale android:name="ky"/> <!-- Kyrgyz -->
<locale android:name="lo"/> <!-- Lao -->
<locale android:name="lt"/> <!-- Lithuanian -->
<locale android:name="lv"/> <!-- Latvian -->
<locale android:name="mk"/> <!-- Macedonian -->
<locale android:name="ml"/> <!-- Malayalam -->
<locale android:name="mn"/> <!-- Mongolian -->
<locale android:name="mr"/> <!-- Marathi -->
<locale android:name="ms"/> <!-- Malay -->
<locale android:name="my"/> <!-- Burmese -->
<locale android:name="nb"/> <!-- Norwegian -->
<locale android:name="ne"/> <!-- Nepali -->
<locale android:name="nl"/> <!-- Dutch -->
<locale android:name="or"/> <!-- Odia -->
<locale android:name="pa"/> <!-- Punjabi -->
<locale android:name="pl"/> <!-- Polish -->
<locale android:name="pt-BR"/> <!-- Portuguese (Brazil) -->
<locale android:name="pt-PT"/> <!-- Portuguese (Portugal) -->
<locale android:name="ro"/> <!-- Romanian -->
<locale android:name="ru"/> <!-- Russian -->
<locale android:name="si"/> <!-- Sinhala -->
<locale android:name="sk"/> <!-- Slovak -->
<locale android:name="sl"/> <!-- Slovenian -->
<locale android:name="sq"/> <!-- Albanian -->
<locale android:name="sr"/> <!-- Serbian (Cyrillic) -->
<locale android:name="sr-Latn"/> <!-- Serbian (Latin) -->
<locale android:name="sv"/> <!-- Swedish -->
<locale android:name="sw"/> <!-- Swahili -->
<locale android:name="ta"/> <!-- Tamil -->
<locale android:name="te"/> <!-- Telugu -->
<locale android:name="th"/> <!-- Thai -->
<locale android:name="tr"/> <!-- Turkish -->
<locale android:name="uk"/> <!-- Ukrainian -->
<locale android:name="ur"/> <!-- Urdu -->
<locale android:name="uz"/> <!-- Uzbek -->
<locale android:name="vi"/> <!-- Vietnamese -->
<locale android:name="zh-Hans"/> <!-- Chinese (Simplified) -->
<locale android:name="zh-Hant"/> <!-- Chinese (Traditional) -->
<locale android:name="zu"/> <!-- Zulu -->
</locale-config>