言語と地域の解決の概要

Android 7.0(API レベル 24)以降、Android では多言語ユーザー向けのサポートが強化され、ユーザーは設定で複数の言語 / 地域を選択できるようになっています。Android は、サポートするロケール数を大幅に増やし、システムがリソースを解決する方法を変更することで、この機能を実現しています。

このドキュメントでは、まず Android 7.0(API レベル 24)より前のバージョンにおけるリソース解決戦略について説明します。次に、Android 7.0 で改善されたリソース解決戦略について説明します。最後に、拡大されたロケール数を活用して、より多くの多言語ユーザーをサポートする方法について説明します。

言語リソースを解決するうえでの課題

Android 7.0 より前のバージョンでは、アプリとシステムのロケールを必ずしも一致させることができませんでした。

たとえば、次のような状況にあるとします。

  • アプリのデフォルト言語は en_US(アメリカ英語)で、スペイン語にローカライズされた文字列が es_ES のリソース ファイルにあります。
  • デバイスは es_MX に設定されています。

Java コードが文字列を参照するとき、スペイン語にローカライズされたリソースがアプリの es_ES にある場合でも、デフォルト(en_US)のリソース ファイルから文字列が読み込まれます。これは、システムで完全一致が見つからない場合、ロケールから国コードを切り離して引き続きリソースを探すためです。最終的に一致が見つからない場合、システムはデフォルトの en_US にフォールバックします。

また、ユーザーがアプリでまったくサポートされていない言語(フランス語など)を選択した場合にも、デフォルトの en_US になります。次に例を示します。

表 1. ロケールが完全に一致しない場合のリソースの解決

ユーザー設定 アプリのリソース リソースの解決
fr_CH デフォルト(en)
de_DE
es_ES
fr_FR
it_IT
fr_CH を試す => 失敗
fr を試す => 失敗
デフォルト(en)を使用

この例では、ユーザーが英語を理解するかどうかにかかわらず、英語の文字列が表示されます。現在ではこの動作が一般的です。

リソース解決戦略の改善

Android 7.0(API レベル 24)は、より堅牢なリソース解決を可能にするとともに、適切なフォールバックを自動的に検出します。ただし、解決を高速化し、保守性を向上させるには、最も一般的な親言語でリソースを保存する必要があります。たとえば、以前にスペイン語のリソースを values-es-rUS ディレクトリに保存していた場合は、中南米スペイン語を保存する values-b+es+419 ディレクトリにスペイン語のリソースを移動します。同様に、values-en-rGB というディレクトリにリソース文字列を保存していた場合は、en-GB 文字列の最も一般的な親言語が en-001 であるため、ディレクトリ名を values-b+en+001(国際英語)に変更します。以下の例は、こうした処理によってリソース解決のパフォーマンスと信頼性が向上する理由を示しています。

リソース解決の例

Android 7.0 以降のバージョンでは、表 1 に示すケースの解決方法が異なります。

表 2. ロケールが完全に一致しない場合の解決戦略の改善

ユーザー設定 アプリのリソース リソースの解決
  1. fr_CH
デフォルト(en)
de_DE
es_ES
fr_FR
it_IT
fr_CH を試す => 失敗
fr を試す => 失敗
fr の子を試す => fr_FR
fr_FR を使用

これで、ユーザーが英語ではなくフランス語のリソースを取得できるようになります。またこの例は、Android 7.0 以降で、フランス語の文字列を fr_FR ではなく fr に保存すべき理由も示しています。このような動作は、最も近い親言語を一致させることで、解決を高速化し、予測しやすくすることを目的としています。

Android では、解決ロジックが改善されただけでなく、より多くのユーザー言語から選択できるようにもなっています。上記の例を、今度は追加のユーザー言語として指定されているイタリア語で試してみましょう。フランス語はアプリのサポート対象外とします。

表 3: ユーザーが 2 番目に優先するロケール設定だけがアプリで一致する場合のリソース解決

ユーザー設定 アプリのリソース リソースの解決
  1. fr_CH
  2. it_CH
デフォルト(en)
de_DE
es_ES
it_IT
fr_CH を試す => 失敗
fr を試す => 失敗
fr の子を試す => 失敗
it_CH を試す => 失敗
it を試す => 失敗
it の子を試す => it_IT
it_IT を使用

アプリがフランス語をサポートしていない場合でも、ユーザーは理解できる言語を使用できます。

追加のロケールをサポートするようにアプリを設計する

Android には、アプリ コンテンツを簡単にローカライズし、ユーザーによる言語の選択を容易にするツールが用意されています。さまざまな言語や表記慣例にスケーラブルに対応できるように、以下の手法を使用してアプリを構成することをおすすめします。

アプリがサポートする言語の指定

言語が正しく解決されるようにするには、モジュール レベルの build.gradle ファイルの resConfigs プロパティを使用して、アプリがサポートする言語を指定します。

次のコードサンプルは、サポートする言語を resConfigs を使用して指定する方法を示しています。この例では、アプリは英語とスペイン語の両方をサポートしています。

Groovy

android {
    defaultConfig {
        ...
        resConfigs "en", "es"
    }
}

Kotlin

android {
    defaultConfig {
        ...
        resConfigs("en", "es")
    }
}
ユーザーの言語設定が正しく認識されるように、ビルドシステムでアプリのリソースとその依存関係を統合する方法に沿って、サポートする言語を指定する必要があります。

LocaleList API

Android 7.0(API レベル 24)以降では LocaleList.getDefault() API が公開されており、ユーザーが指定した言語のリストをアプリが直接クエリできるようになっています。この API を使用すると、より高度なアプリの動作を作成し、コンテンツをより適切に表示できるようになります。たとえば、ユーザーの設定に基づいて、複数の言語で検索結果を表示できます。ブラウザアプリでは、ユーザーが理解する言語ですでに表示されているページの翻訳を提案しないようにし、キーボード アプリでは適切なレイアウトをすべて自動で有効にできます。

フォーマッタ

Android 6.0(API レベル 23)以前では、多くの一般的な言語(en、es、ar、fr、ru)について、1 つまたは 2 つのロケールしかサポートされていませんでした。各言語のバリエーションがわずかしかなかったため、アプリである種の数値や日付をハードコードされた文字列としてリソース ファイルに保存しても、大きな問題にはなりませんでした。しかし現在、Android がサポートするロケールが増えたため、日付、時刻、通貨などの情報の形式が、1 つのロケール内でも大きく異なる場合があります。形式をハードコードすると、エンドユーザーを混乱させる可能性があります。そのため、Android 7.0 以降向けの開発では、数値や日付の文字列をハードコードするのではなく、必ずフォーマッタを使用するようにしてください。

たとえば、Android 7.0 以降では 27 のアラビア語ロケールがサポートされています。これらのロケール間ではほとんどのリソースを共有できますが、ASCII 数字が好まれる地域もあれば、現地の数字が好まれる地域もあります。たとえば「4 桁の PIN を選択」など、数字の変数を含む文を作成する場合は、次のようにフォーマッタを使用します。

 format(locale, "Choose a %d-digit PIN", 4)