Android 7.0(API レベル 24)以降では、複数言語のユーザーのサポートが強化されており、設定で複数のロケールを選択できます。Android ではこの機能を提供するために、サポート対象のロケール数を大幅に拡大し、システムがリソースを解決する方法を変更しました。
このドキュメントでは、Android 7.0(API レベル 24)より前のバージョンにおけるリソース解決戦略を最初に説明します。次に、Android 7.0 で改善されたリソース解決戦略について、そして最後に、増大したロケールを活用し、より多くの複数言語ユーザーをサポートする方法について説明します。
言語リソースの解決における課題
Android 7.0 より前のバージョンの Android では、アプリとシステムのロケールを一致させることができない場合がありました。
例として、以下の状況を想定してください。
- アプリのデフォルトの言語が
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
という名前のディレクトリにリソースを保存している場合、そのディレクトリの名前を values-b+en+001
(国際英語)に変更します。en-GB
文字列の最も一般的な親言語は en-001
であるためです。以下の例では、このような対応によってリソース解決のパフォーマンスと信頼性が向上する根拠について説明します。
リソース解決の例
Android 7.0 より後のバージョンを使う場合、表 1 で説明されたケースとは解決法が異なります。
表 2. 完全一致するロケールが存在しない場合の改善後の解決方針
ユーザー設定 | アプリのリソース | リソース解決 |
---|---|---|
|
デフォルト(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 番目に優先するロケール設定のみと一致する場合のリソース解決
ユーザー設定 | アプリのリソース | リソース解決 |
---|---|---|
|
デフォルト(en) de_DE es_ES it_IT |
fr_CH を試行 => 失敗 fr を試行 => 失敗 fr の子を試行 => 失敗 it_CH を試行 => 失敗 it を試行 => 失敗 it の子言語を試行 => it_IT it_IT を使用 |
アプリでフランス語をサポートしていなくても、ユーザーが理解できる言語が使用されます。
追加のロケールをサポートするためのアプリ設計
LocaleList API
Android 7.0(API level 24)以降は、Android が LocaleList.getDefault()
API を公開することで、ユーザーが指定した言語リストをアプリが直接クエリできるようになっています。この API を使用すると、アプリの動作がさらに洗練され、コンテンツの表示がより最適化されます。たとえば検索で、ユーザーの設定に基づいて複数の言語で結果を表示できます。ブラウザ アプリは、ユーザーが理解できる言語の翻訳ページを表示することがなくなり、キーボード アプリは、自動的に最適なレイアウトを有効にすることができます。
フォーマッタ
Android 6.0(API レベル 23)までは、Android は多くの一般的な言語(en、es、ar、fr、ru)に対して 1 つか 2 つのロケールしかサポートしていませんでした。各言語にはわずかなバリエーションしかなかったため、アプリはリソース ファイルでハードコーディングされた文字列として数字や日付を保存し、処理することができました。しかし Android でさまざまなローケルがサポートされるようになったため、日付、時刻、通貨などの情報は、一つのロケール内でも形式が大幅に異なる場合があります。形式をハードコーディングすると、エンドユーザーが混乱するおそれがあります。したがって、Android 7.0 以降のバージョン向けに開発するときは、数字や日付の文字列をハードコーディングせず、必ずフォーマッタを使用してください。
たとえば、Android 7.0 以降では、27 のアラビア語ロケールがサポートされています。これらのロケールは、ほとんどのリソースを共有できますが、数字は ASCII 表記とネイティブ表記で好みが分かれています。たとえば、「4 桁の PIN を入力してください」など、数字の変数を含む文を作成する場合、以下のようにフォーマッタを使用します。
format(locale, "Choose a %d-digit PIN", 4)