365連休

にわかのandroidとかの開発メモ。

Localize your appの意訳

developer.android.com

 

Androidは多くの地域の多くのデバイスで実行される。

多くのユーザに手に取ってもらうには、テキスト、オーディオ、数字、通貨、そして画像をアプリが使用されるロケールに適合させる。

このドキュメントでは、Androidアプリをローカライズするためのベストプラクティスについて述べる。

 

このドキュメントの対象

 

Androidリソースフレームワークを使用して、アプリのローカライズに関する部分をJavaベースのコア機能から可能な限り分離することを勧める。

 

アプリで文字列をローカライズする簡単なガイドについては「Supporting Different Languages 異なる言語をサポート」を参照すること。

 

Android内のリソース切り替え

リソースとは、テキスト、レイアウト、サウンド、グラフィックス、およびアプリに必要なその他の静的データ。

アプリには複数のリソースセットを含めることができ、異なるデバイス構成用にカスタマイズされている。

ユーザーがアプリを実行すると、Android は自動的にデバイスに最も適したリソースを選択して読み込む。

(このドキュメントでは、ローカリゼーションロケールに焦点を当てている。リソース切り替えと指定できる全ての構成-画面の向き、タッチスクリーンの種類など-「Providing Alternative Resources 代替リソースの提供」を参照すること。

アプリを作成するときは、アプリで使用する既定のリソースと代替リソースを作成する。ユーザがアプリを実行すると、Android システムはデバイスロケールに基づいて読み込むリソースを選択する。

リソースを作成するには、プロジェクトの"res/特別な名前/"にファイルを配置する。

 

既定のリソースが重要な理由

ロケール固有のテキストを指定していないロケールでアプリが実行されるたびに、Androidはres/values/strings.xmlからデフォルトの文字列を読み込む。

この既定のファイルがない場合、または使用する文字列が定義されていない場合、アプリは実行されずエラーが表示される。

次の例は、既定のテキストファイルが不完全な場合に何が起こるかを示している。

 

例:

アプリはtext_aとtext_bの2つの文字列だけを参照する。
このアプリには2つの文字列が英語でローカライズされたres/values-en/strings.xmlが含まれている。
このアプリには既定のres/values/strings.xmlが含まれているが、text_aしか定義されていない。text_bは定義されていない。

  • 英語のロケールのデバイスで起動すると、必要な文字列がres/values-en/strings.xmlに定義されているため、問題なく実行される可能性がある。
  • 英語以外の言語に設定された状態で起動すると、エラーメッセージと強制終了ボタンが表示される。アプリは起動しない。

この状況を防ぐために、res/values/strings.xmlファイルが存在し、必要なすべての文字列が定義されていることを確認する。これは、文字列だけでなく、全ての種類のリソースも同様である。テストの詳細については、「Testing for Default Resources既定のリソースのテスト」を参照すること。

 

ローカリゼーションにリソースを使用する

既定のリソースの作成方法

アプリの既定のテキストをres/values/strngs.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 リソースへの各参照を調べる。
既定のリソースがそれぞれに定義されていることを確認する。
また、既定の文字列ファイルが完全であることを確認する。 ローカライズされた文字列ファイルには文字列のサブセットを含めることができるが、既定の文字列ファイルには必ず全ての文字列ファイルが含まれている必要がある。

 

代替リソースの作成方法

アプリのローカライズの大部分は、異なる言語に代わるテキストを提供することであり、場合によっては、グラフィックス、サウンド、レイアウト、およびその他のロケール固有リソースも提供する。

アプリは、異なる修飾子を持つ多くのres//を指定できる。

別のロケールの代替リソースを作成するには、言語または言語-リージョンの組み合わせを指定する修飾子を使用する。

(リソース ディレクトリの名前は、「Providing Alternavive Resources 代替リソースの提供」で説明されている命名スキームに準拠している必要がある。)

例:

  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"を探す。しかし、そのような文字列がそのファイルに含まれていないため、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"を読み込む。リソース選択プロセスで言語よりもMCCの一致を優先するため。

選択プロセスは例が示すように必ずしも簡単ではない。

より詳細な説明については「How Android Finds the Best-matching Resource システムが最適なリソースを見つける仕組み」を参照する事。全ての修飾子は「Table 2 of Providing Alternative Resources 代替リソースの提供の表2」に記載されている。

 

コード内のリソースの参照

アプリのJavaベースのコードでは、"R.resource_type.resource_name"構文、または"android.R.resource_type.resource_name"構文を使用してリソースを参照する。

詳細については、「Accessing Resources リソースへのアクセス」を参照すること。

 

ローカリゼーションの文字列の管理

全ての文字列をstrings.xmlへ移動する

アプリをビルドする場合は、文字列をハードコーディングしないこと。代わりに、全ての文字列を既定のstrings.xmlでリソースとして宣言し、修正とローカライズを簡単に行える。

strings.xmlファイル内の文字列は、コンパイルされたコードを変更することなく、簡単に抽出、変換、および適切な修飾子を使用してアプリに統合できる。

テキストを含む画像を生成する場合は、これらの文字列をstrings.xmlに入れ、翻訳後にイメージを再生成する。

 

UI文字列のAndroid ガイドライン

UIを設計および開発する際は対話方法に細心の注意を払うこと。

通常、「succinct and compressed style 簡潔で無駄を省いたスタイル」で、簡単であるものの必要充分であり、UI全体で一貫したスタイルを使用する。

writing style and word choice スタイルと単語の選択」のためにマテリアルデザインの推奨事項を読み、それに従っていることを確認する。

これにより、アプリがユーザーに対してより洗練された表示になり、ユーザーがUIをより迅速に理解できるようになる。

また、アクションバー、オプションメニュー、システムバー、通知などのUI要素は可能な限りAndroid標準の用語を常に使用すること。

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 アプリのローカライズと配布のプロセスの完全な概要については、「Localization Checklist GooglePlyガイド ローカライズチェックリスト」のドキュメントを参照すること。

 

ローカライズTips

任意のロケールで動作するよう設計する

どのようなデバイスでアプリを実行される分からない。

バイスには予想していなかったハードウェアが含まれる場合や、予想していないロケールに設定されている場合があり、想定できなかったりテスト出来ない場合がある。

バイスの機能が想定通りであってもそうでなくても、問題無く動作するようアプリを設計する必要がある。訳注:ここ原文難解。

重要:アプリに既定リソースの完全なセットが含まれているか確認する

アプリの全てリソースを含む既定のres/drawable/とres/values/を含める必要がある。(フォルダ名に修飾子無しのもの)

もし、既定リソースが1つでも不足している場合、サポートされないロケールに設定されているデバイスではアプリは動作しない。

例えば、res/values/strings.xmlにアプリが必要とする文字列が1つ足りない場合。

詳細は「Testing for Default Resources 既定リソースのテスト」を参照する。

 

柔軟なレイアウトの設計

もし、特定の言語(例えばドイツ語は長い単語を含む)に合わせてレイアウトを再配置する場合、その言語の代替レイアウトを作成できる。(例えばres/layout-de/main.xml)

ただし、アプリの保守は困難になるため、柔軟な単一のレイアウトを使用したほうが良い。

もう一つの典型的な状況は、そのレイアウトに他の項目を必要とする言語の場合。

例えば、日本語では2つの名前フィールドを持つ連絡先フォームがあり、他の言語で実行される場合は3つの名前フィールドを持つ。

これには2つの対応策がある。

  • 単一のレイアウトを用い、言語によってプログラムでフィールドの有効/無効を切り替える
  • メインレイアウトが他の変更可能フィールドを持つ他のレイアウトを読み込む。2つめのレイアウトは異なる言語のために異なる構成を持つことができる。訳注:<include>タグを使うってことだと思う。

 

必要以上のリソースファイルと文字列を作らない

全てのリソースをローカライズする必要はない。

例えば、res/layout/main.xmlで定義されたレイアウトは任意のロケールで動作するよう設計した場合、ローカライズされた代替レイアウトを作成する必要はない。

また、文字列をローカライズする必要がない場合もある。

  • アプリの既定の言語はアメリカ英語で、全ての文字列をres/values/strings.xmlで定義
  • 一部の重要なフレーズについてはイギリス英語の代替文字列を定義する。アプリがイギリスで実行される場合、代替文字列が使用される。

これを行うには、res/values-en-rGB/strings.xmlという小さなファイルを作るだけでよい。

残りの文字列は既定リソースであるres/values/strings.xmlから使用される。

 

Contextオブジェクトを使い手動でロケールを調べる方法

Contextオブジェクトを使用して、ロケールを調べることができる。

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

 

翻訳サービスを利用する

翻訳サービスはPlay Consoleに統合され、Android Studioからアクセス可能である。

簡単で迅速に翻訳企業からインスタント見積もりを取得し発注できる。 1つもしくは多数の言語へ、UI文字列、Play Storeリスティングテキスト、IAP名、広告キャンペーンテキストを翻訳できる。

訳注:だーかーらー翻訳サービスを翻訳しとけとあれほど、言ってることとやってることが真逆

 

既定のリソースのテスト

バイスでのテスト

地域によって利用できるデバイスが異なる場合があることに注意する。

テストに使用されたデバイスで利用可能なロケールは、他のデバイスで利用可能なロケールとは異なる場合がある。

また、デバイスの画面解像度と密度も異なる場合があり、文字や画像のUIに影響を与える可能性がある。

設定アプリを使用し、ロケールや言語を変更する。

 

エミュレータでのテスト

使い方の詳細は「Android Emulator」を参照する。

カスタムロケールの作り方

カスタムロケールAndroidシステムがサポートしていない言語と地域の組み合わせであり、テストを行うためエミュレータでカスタムロケールを作成する。

次の2つの方法がある。

  • アプリタブからアクセス可能なCustom Localeアプリを使用する。(ロケールを作成した後、長押ししてロケール名を変更する)
  • adbシェルからカスタムロケールに変更する。後述。

エミュレータAndroidシステムで使用できないロケールを設定すると、システムは既定の言語で表示される。ただし、アプリは適切にローカライズする必要がある。

adbシェルからカスタムロケールに変更する方法

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

カダナ/フランス語でテストするには次のコマンドを実行する。
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がない場合、エミュレータまたは実機を縦向きに設定し、アプリが実行できるか確認する。

 

 

マテリアルデザインをググる。

※上記はhttps://developer.android.com/guide/topics/resources/localizationの意訳である。

Android開発者向けドキュメントを意訳してみる。 - 365連休

意訳元https://developer.android.com/ライセンス解釈
ソースコードから抽出されたドキュメントやコードはAndroid Open Source Projectの優先ライセンスであるApache 2.0 licenseが適用され、それ以外のコンテンツはCC BY 2.5が適用されている。
よって、ページ全体の意訳についてはCC BY 2.5における翻案行為、ページ内のコード転載についてはApache 2.0 licenseにおける頒布行為にあたると解釈している。