6 月 3 日の「#Android11: The Beta Launch Show」にぜひご参加ください。

アプリをローカライズする

Android は多くの地域の多くのデバイス上で稼働しています。そのほとんどのユーザーにアプローチするには、アプリでテキスト、音声ファイル、数値、通貨、グラフィックを扱う際に、アプリが使用される言語 / 地域(ロケール)での適切な形で扱う必要があります。

このドキュメントでは、Android アプリのローカライズに関するおすすめの方法を紹介します。

ここでは、Java プログラミング言語の実践的な知識があり、Android リソースの読み込みユーザー インターフェース要素の XML での宣言アクティビティ ライフサイクルのような開発上の検討事項、および国際化とローカライズの一般原則について熟知している人を対象としています。

Android リソース フレームワークを利用して、アプリのローカライズされる部分を Java ベースのコア機能からできる限り分離することをおすすめします。

  • このドキュメントとリソースの提供に関する記事で説明するように、アプリのユーザー インターフェース(UI)の「コンテンツ」のほとんどまたはすべてを、リソース ファイルに含めることができます。
  • 一方、UI の「動作」は、Java ベースのコードによって駆動されます。たとえば、ユーザーが入力するデータをロケールに応じて書式設定したり、並べ替えたりする必要がある場合は、Java プログラミング言語を使用してプログラムでデータを処理します。このドキュメントでは、Java ベースのコードのローカライズ方法については説明しません。

アプリの文字列をローカライズする簡潔なガイドとしては、トレーニング レッスンの各種言語のサポートに関するページをご覧ください。

概要: Android でのリソースの切り替え

リソースとは、Android アプリが必要とするテキスト文字列、レイアウト、音声、グラフィック、およびその他のすべての静的データのことです。アプリには、異なるデバイス設定用にそれぞれカスタマイズした複数のリソースセットを含めることができます。ユーザーがアプリを実行する際、そのデバイスに最適なリソースが自動的に選択されて読み込まれます。

このドキュメントでは、ローカライズとロケールを中心に説明します。リソースの切り替えと、指定できる設定の種類(画面の向き、タッチスクリーンのタイプなど)についての全詳細は、代替リソースを提供する場合の説明をご覧ください。

アプリを作成する際に、アプリで使用するデフォルト リソースと代替リソースを作成します。ユーザーがアプリを実行する際、デバイスのロケールに応じて、読み込むリソースが Android システムで選択されます。リソースを作成するには、プロジェクトの res/ ディレクトリに含める特別な名前を付けたサブディレクトリ内にファイルを置きます。

デフォルト リソースが重要な理由

あるロケールでアプリが実行される際、そのロケール固有のテキストを提供していない場合、Android は常に res/values/strings.xml からデフォルト文字列を読み込みます。このデフォルト ファイルがない場合、またはアプリが必要とする文字列が欠落している場合、アプリは実行されず、エラーが表示されます。次の例で、デフォルト テキスト ファイルが不完全な場合にどのようになるかを示します。

例:

2 つの文字列 text_atext_b のみ参照するアプリの Java ベースのコードがあるとします。このアプリにはローカライズされたリソース ファイル(res/values-en/strings.xml)があり、text_atext_b が英語で定義されています。このアプリにはデフォルトのリソース ファイル(res/values/strings.xml)もあり、text_a の定義が含まれていますが、text_b の定義は含まれていないとします。

  • ロケールが英語に設定されているデバイスでこのアプリを起動すると、res/values-en/strings.xml には必要なテキスト文字列が両方含まれているので、おそらく問題なくアプリが実行されます。
  • 一方、英語以外の言語に設定されたデバイスでこのアプリを起動すると、ユーザーにはエラー メッセージと強制終了ボタンが表示されます。この場合、アプリは読み込まれません。

このような状況を回避するには、必ず res/values/strings.xml ファイルを用意し、必要な文字列をすべてそこに定義します。このような状況は、文字列だけでなく、リソースのどのタイプでも同様です。デフォルト リソース ファイル セットを作成し、レイアウト、ドローアブル、アニメーションなど、アプリが必要とするすべてのリソースを含める必要があります。テストの詳細については、デフォルト リソースをテストする方法に関する説明をご覧ください。

リソースを使ってローカライズする

デフォルト リソースを作成する方法

アプリのデフォルト テキストを res/values/strings.xml に含めます。

res/values/strings.xml 内のテキスト文字列にはデフォルト言語を使用する必要があります。アプリの最も多くのユーザーが話すと想定される言語をデフォルトにします。

デフォルト リソース セットには、デフォルトのドローアブルやレイアウトも含める必要があります。アニメーションなど、他のタイプのリソースも含めることができます。

  • res/drawable/(Google Play でのアプリのアイコン用に 1 つ以上のグラフィック ファイルを含める必須のディレクトリ)
  • res/layout/(デフォルト レイアウトを定義する XML ファイルを含める必須のディレクトリ)
  • res/anim/res/anim-<qualifiers> フォルダがある場合に必須)
  • res/xml/res/xml-<qualifiers> フォルダがある場合に必須)
  • res/raw/res/raw-<qualifiers> フォルダがある場合に必須)

ヒント: コード内で、Android リソースへの各参照を確認してください。それぞれにデフォルト リソースが定義されていることを確認します。デフォルトの文字列ファイルに漏れがないことも確認してください。「ローカライズ」した文字列ファイルは文字列のサブセットにすることができますが、「デフォルト」の文字列ファイルには、すべて含める必要があります。

代替リソースの作成方法

各種言語の代替テストを提供することが、アプリのローカライズの大部分を占めます。場合によっては、グラフィック、音声、レイアウトなど、ロケールごとに専用の代替リソースも提供する必要があります。

1 つのアプリに、それぞれ異なる修飾子(qualifier)を付けた多数の res/<qualifiers>/ ディレクトリを指定できます。各ロケール用に代替リソースを作成するには、言語または言語と地域の組み合わせを指定する修飾子を使用します(リソース ディレクトリの名前は、代替リソースを提供する方法に記載されている命名規則に準拠する必要があります。準拠していないと、アプリはコンパイルできません)。

例:

アプリのデフォルト言語を英語とします。さらに、アプリ内のすべてのテキストをフランス語にローカライズし、テキストのほとんど(アプリのタイトル以外すべて)を日本語にローカライズするとします。この場合、3 つの代替 strings.xml ファイルを作成し、各ロケール専用のリソース ディレクトリにそれぞれ格納します。

  1. res/values/strings.xml
    title という名前の文字列のテキストをはじめとして、アプリが使用するすべての文字列に対して英語のテキストを含めます。
  2. res/values-fr/strings.xml
    title をはじめとして、すべての文字列に対してフランス語のテキストを含めます。
  3. res/values-ja/strings.xml
    title を除く、すべての文字列に対して日本語のテキストを含めます。

Java ベースのコードが R.string.title を参照する場合、ランタイムには次のようになります。

  • デバイスがフランス語以外の言語に設定されている場合、Android は res/values/strings.xml ファイルから title を読み込みます。
  • デバイスがフランス語に設定されている場合、Android は res/values-fr/strings.xml ファイルから title を読み込みます。

デバイスが日本語に設定されている場合、Android は res/values-ja/strings.xml ファイル内で title を探しますが、このファイルには title の文字列が含まれていないので、Android はデフォルトにフォールバックし、res/values/strings.xml ファイルから英語の title を読み込みます。

優先されるリソース

デバイスの設定に一致するリソース ファイルが複数ある場合、Android は一連のルールに従ってどのファイルを使用するかを決定します。リソース ディレクトリ名に指定できる修飾子のうち、通常はロケールが優先されます

例:

アプリに、デフォルトのグラフィック セットの他に 2 種類のグラフィック セットがあり、それぞれ異なるデバイスの設定に最適化されているとします。

  • res/drawable/
    デフォルト グラフィックが含まれます。
  • res/drawable-small-land-stylus/
    スタイラスからの入力が想定され、横向きの QVGA の低密度画面が搭載されたデバイスで使用するように最適化されたグラフィックが含まれます。
  • res/drawable-ja/
    日本語での使用に最適化されたグラフィックが含まれます。

日本語を使用するように設定されたデバイスでアプリが実行される場合、Android は res/drawable-ja/ のグラフィックを読み込みます。そのデバイスでスタイラスからの入力が想定され横向きの QVGA の低密度画面が搭載されていても同様です。

例外: この選択プロセスでロケールよりも優先される修飾子は、MCC(モバイル国コード)と MNC(モバイル ネットワーク コード)だけです。

例:

次のような状況を想定します。

  • アプリコードが R.string.text_a を必要としています。
  • 次の 2 つの関連リソース ファイルがあります。
    • res/values-mcc404/strings.xml: アプリのデフォルト言語、この例では英語の text_a が含まれます。
    • res/values-hi/strings.xml: ヒンディー語の text_a が含まれます。
  • 以下の設定のデバイスでアプリが実行されます。
    • SIM カードはインドのモバイル ネットワーク(MCC 404)に接続されます。
    • 言語はヒンディー語に設定されています(hi)。

デバイスがヒンディー語に設定されていても、Android は res/values-mcc404/strings.xml(英語)から text_a を読み込みます。これは、リソースの選択プロセスで、Android が MCC の一致を言語の一致よりも優先するためです。

選択プロセスは必ずしも、上記の例のように単純明快ではありません。プロセスの詳細な説明については、Android が最適なリソースを見つける仕組みに関する説明をご覧ください。すべての修飾子についての説明が、代替リソースを提供する方法に関する表 2 に優先度順に記載されています。

コード内でリソースを参照する

アプリの Java ベースのコード内でリソースを参照するには、構文 R.resource_type.resource_name または android.R.resource_type.resource_name を使用します。詳しくは、リソースへのアクセスに関するページをご覧ください。

ローカライズする文字列を管理する

すべての文字列を strings.xml に移動する

アプリを作成する際に、どの文字列もハードコードしないようにしてください。代わりに、すべての文字列をリソースとして、デフォルトの strings.xml ファイルに宣言します。これにより、文字列の更新とローカライズがしやすくなります。strings.xml ファイル内の文字列を抽出、翻訳し、アプリ内に統合し直すことが簡単にできます(該当する修飾子を指定します)。コンパイルしたコードを変更する必要はありません。

テキストが含まれる画像を作成する場合、その文字列も同様に strings.xml で宣言し、翻訳後に画像を再度作成します。

UI 文字列について Android のガイドラインに沿う

UI を設計し、開発する際は、ユーザーにどのように話しかけるかに十分に注意を払います。一般的には簡潔なスタイル(シンプルで親しみやすい表現)を使用し、UI 全体でスタイルを統一します。

マテリアル デザインでの文章のスタイルと言葉の選択に関する推奨事項を参照して、それに沿うようにします。それによって、アプリからのユーザーへの表示や働きかけが洗練され、ユーザーにとって UI がわかりやすくなります。

また、該当する場所では常に Android の標準的用語を使用します。たとえば UI 要素では、アクションバー、オプション メニュー、システムバー、通知といった用語を使用します。Android の用語を適切に、一貫して使用することで、翻訳しやすくなり、ユーザー向け最終製品の改善につながります。

宣言する文字列に十分なコンテキストを提供する

文字列を strings.xml ファイルで宣言する際、その文字列が使用される状況について必ず説明を加えます。この情報は翻訳者にとって重要な意味を持つため、翻訳品質の向上につながります。また、文字列を効率よく管理できるようになります。

次に例を示します。

<!-- The action for submitting a form. This text is on a button that can fit 30 chars -->
    <string name="login_submit_button">Sign in</string>
    

次のような内容をコンテキスト情報として提供することを検討してください。

  • この文字列は何のためか。いつ、どこでユーザーに表示されるか。
  • レイアウトのどこに配置されるか。たとえば、ボタンに表示する文字列の翻訳は、テキストボックス内の文字列の翻訳よりも制約があります。

メッセージ内の翻訳対象外の部分に印を付ける

他の言語に翻訳してはならないテキストが文字列に含まれることはよくあります。一般的な例は、コードの一部、何かの値のプレースホルダ、特殊記号、名称などです。文字列を翻訳する準備の際に、翻訳せずにそのまま残す必要があるテキストを探して印を付け、翻訳者が変更しないようにします。

翻訳対象外のテキストに印を付けるには、<xliff:g> プレースホルダ タグを使用します。次の例では、テキスト「%1$s」が翻訳中に変更されないよう指定するタグを示します(タグを指定しないと、メッセージが壊れるおそれがあります)。

    <string name="countdown">
      <xliff:g id="time" example="5 days">%1$s</xliff:g> until holiday
    </string>
    

プレースホルダ タグを宣言する際は、何のためのプレースホルダかを説明する id 属性を必ず追加します。アプリが後でプレースホルダの値を置き換える場合は、どのような使用例が想定されるかを明示する example 属性を必ず指定します。

プレースホルダ タグの例をさらにいくつか示します。

    <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <!-- Example placeholder for a special unicode symbol -->
    <string name="star_rating">Check out our 5
        <xliff:g id="star">\u2605</xliff:g>
    </string>
    <!-- Example placeholder for a for a URL -->
    <string name="app_homeurl">
        Visit us at <xliff:g
        id="application_homepage">http://my/app/home.html</xliff:g>
    </string>
    <!-- Example placeholder for a name -->
    <string name="prod_name">
        Learn more at <xliff:g id="prod_gamegroup">Game Group</xliff:g>
    </string>
    <!-- Example placeholder for a literal -->
    <string name="promo_message">
        Please use the "<xliff:g id="promotion_code">ABCDEFG</xliff:g>" to get a discount.
    </string>
    ...
    </resources>
    

ローカライズに関するチェックリスト

Android アプリをローカライズし、配布するプロセスの概要については、ローカライズ チェックリストのドキュメントをご覧ください。

ローカライズのヒント

どのロケールでもアプリが機能するように設計する

ユーザーがアプリを実行するデバイスについて、デベロッパーは何も想定できません。デバイスに想定外のハードウェアが搭載されている場合や、予定していないロケール、またはテストできないロケールに設定されている場合もあります。どのようなデバイス上で起動されても、正常に機能するか、エラーとして適切に処理するようにアプリを設計してください。

重要: アプリにデフォルト リソース セットを完備しておきます。

アプリに必要な画像とテキストをすべて含めた res/drawable/ フォルダと res/values/ フォルダを必ず用意します(フォルダ名に修飾子は追加しません)。

デフォルト リソースが 1 つでも欠落しているアプリは、サポートされていないロケールに設定されたデバイスで実行されません。たとえば、res/values/strings.xml デフォルト ファイルに、アプリが必要とする文字列の 1 つが欠落しているとします。サポートされていないロケールでアプリが起動し、res/values/strings.xml を読み込もうとすると、エラー メッセージと強制終了ボタンがユーザーに表示されます。

詳細については、デフォルト リソースをテストする方法の説明をご覧ください。

柔軟性のあるレイアウトを設計する

特定の言語(たとえば、ドイツ語の長い単語)に合わせてレイアウトを変更する必要がある場合、その言語用に代替レイアウト(たとえば res/layout-de/main.xml)を作成できます。ただし、これを行うと、アプリの管理が難しくなることがあります。それより、柔軟性を高めたレイアウトを 1 つ作成することをおすすめします。

別の典型的な状況としては、言語によってレイアウトの一部を変える必要がある場合です。たとえば、連絡先フォームがある場合、日本語でアプリが実行される際は、名前の欄を 2 つ表示しますが、アプリが実行される言語によっては、欄を 3 つ表示する必要があります。これに対処する方法は 2 つあります。

  • 言語に応じてプログラムで有効または無効にできるフィールドを持つレイアウトを 1 つ作成します。
  • メインのレイアウトに、変更可能なフィールドがある別のレイアウトを含めます。2 つ目のレイアウトでは言語ごとに異なる設定を用意できます。

リソース ファイルやテキスト文字列を必要以上に作成しないようにする

ロケールごとの代替リソースをアプリ内のすべてのリソースに作成する必要があるとは限りません。たとえば、res/layout/main.xml ファイルがどのロケールでも動作する場合、代替レイアウト ファイルを作成する必要はありません。

同様に、すべての文字列に対して代替テキストの作成が必要とは限りません。たとえば、次のような状況を考えます。

  • アプリのデフォルト言語がアメリカ英語だとします。アプリで使用されるすべての文字列について、アメリカ英語のスペルで res/values/strings.xml に定義します。
  • いくつかの重要なフレーズについては、イギリス英語のスペルを提供するとします。こうした代替文字列を、英国内のデバイスでアプリが実行されるときに使用するようにします。

これを行うには、res/values-en-rGB/strings.xml という小さなファイルを作成し、英国でアプリが実行されるときに変える必要がある文字列のみを含めます。残りの文字列については、アプリはデフォルトにフォールバックし、res/values/strings.xml に定義されている文字列を使用します。

Android Context オブジェクトを使ってロケールを手動で検索する

ロケールを検索するには、Android で提供されている Context オブジェクトを使用します。

Kotlin

    val primaryLocale: Locale = context.resources.configuration.locales[0]
    val locale: String = primaryLocale.displayName
    

Java

    Locale primaryLocale = context.getResources().getConfiguration().getLocales().get(0);
    String locale = primaryLocale.getDisplayName();
    

アプリ翻訳サービスを使用する

アプリ翻訳サービスPlay Console に統合されており、Android Studio からもアクセスできます。翻訳会社に迅速な見積もりを依頼し、発注できる簡便な方法です。アプリの UI 文字列、Play ストアの掲載情報のテキスト、IAP 名、広告キャンペーン テキストの翻訳を 1 つ以上の言語に翻訳するよう依頼できます。

ローカライズしたアプリをテストする

デバイスでテストする

テストするデバイスは、他の地域でエンドユーザーが使用するデバイスと大幅に異なることがあります。お使いのデバイスで使用できるロケールは、他のデバイスで使用できるロケールとは異なることがあります。また、デバイスの画面の解像度や密度が異なる場合があり、UI の文字列やドローアブルの表示に影響する可能性があります。

デバイスのロケールや言語を変更するには、設定アプリを使用します。

エミュレータでテストする

エミュレータの使い方について詳しくは、Android エミュレータに関する記事をご覧ください。

カスタム ロケールを作成して使用する

「カスタム」ロケールは、Android システム イメージが明示的にサポートしていない言語と地域の組み合わせです。エミュレータでカスタム ロケールを作成すると、カスタム ロケールでのアプリの動作をテストできます。これには、次の 2 つの方法があります。

  • アプリのタブからアクセスできる Custom Locale アプリを使用します(カスタム ロケールを作成したら、ロケール名を長押しして切り替えます)。
  • 下記のように、adb シェルからカスタム ロケールに変更します。

Android システム イメージで使用できないロケールにエミュレータを設定する場合、システムそのものはシステムのデフォルト言語で表示されます。ただし、アプリは適切にローカライズされている必要があります。

エミュレータのロケールを adb シェルから変更する

adb シェルを使用してエミュレータのロケールを変更するには:

  1. テストするロケールを選択し、BCP-47 言語タグを指定します。たとえば、カナダのフランス語は fr-CA です。
  2. エミュレータを起動します。
  3. ホスト コンピュータのコマンドライン シェルから、次のコマンドを実行します。
    adb shellまたはデバイスが接続されている場合は、エミュレータに指示していることを示すため、-e オプションを指定します。adb -e shell
  4. adb シェル プロンプト(#)で、次のコマンドを実行します。
    setprop persist.sys.locale [BCP-47 language tag];stop;sleep 5;start
    ステップ 1 の括弧付きのセクションを適切なコードに置き換えます。

たとえば、カナダのフランス語でテストするには、次のコマンドを実行します。

setprop persist.sys.locale fr-CA;stop;sleep 5;start

これにより、エミュレータが再起動します(完全な再起動のようですが、そうではありません)。ホーム画面が再び表示されたら、アプリを再起動すると、アプリは新しいロケールで起動します。

デフォルト リソースをテストする

アプリに必要なすべての文字列リソースが含まれているかどうかをテストする方法は次のとおりです。

  1. アプリでサポートされていない言語にエミュレータまたはデバイスを設定します。たとえば、res/values-fr/ にフランス語の文字列があり、res/values-es/ にスペイン語の文字列がまったくない場合に、エミュレータのロケールをスペイン語に設定してみます(Custom Locale アプリを使用して、サポートされていないロケールにエミュレータを設定できます)。
  2. アプリを実行します。
  3. エラー メッセージと強制終了ボタンが表示される場合、使用できない文字列が検索されている可能性があります。res/values/strings.xml ファイルに、アプリが使用するすべての文字列の定義を含めるようにしてください。

テストが成功した場合は、他のタイプの設定についても同じ手順を繰り返します。たとえば、res/layout-land/main.xml というレイアウト ファイルがあり、res/layout-port/main.xml というファイルがない場合は、エミュレータまたはデバイスを縦向きにしてアプリが実行されるかどうかを確認します。