アプリのリソースの概要

リソースとは、コードが使用する追加のファイルと静的コンテンツであり、ビットマップ、ユーザー インターフェース文字列、アニメーション命令などがあります。

画像や文字列などのアプリリソースは必ずコードとは別にします。それにより、コードとは独立して管理できるようになります。また、代替リソースは、異なる名前を付けたリソース ディレクトリに分類してデバイス構成ごとに指定します。実行時に、Android は現在の構成に基づいて適切なリソースを使用します。たとえば、言語設定ごとに異なる文字列を指定できます。

アプリリソースをコードとは別にした場合、そのリソースにアクセスするには、プロジェクトの R クラスで生成されたリソース ID を使用します。このドキュメントでは、Android プロジェクトでのリソースの分類方法と、デバイス構成ごとの代替リソースの指定方法、またそれらのリソースにアプリコードやその他の XML ファイルからアクセスする方法について説明します。

グループ リソースのタイプ

リソースはタイプごとにプロジェクトの res/ ディレクトリの対応するサブディレクトリに保存します。たとえば、単純なプロジェクトのファイル階層の例を次に示します。

MyProject/
    src/
        MyActivity.kt
    res/
        drawable/
            graphic.png
        mipmap/
            icon.png
        values/
            strings.xml

res/ ディレクトリのサブディレクトリにすべてのリソース(画像リソース、ランチャー アイコン用の mipmap/ ディレクトリ、文字列リソース ファイル)が保存されています。リソース ディレクトリ名は重要です。これについては表 1 で説明しています。

注: mipmap フォルダの使用方法については、アプリアイコンを mipmap ディレクトリに配置するをご覧ください。

表 1. プロジェクトの res/ ディレクトリ内でサポートされるリソース ディレクトリ

ディレクトリ リソースの種類
drawable/

次のドローアブル リソースのサブタイプにコンパイルされるビットマップ ファイル(PNG、.9.png、JPG、GIF)または XML ファイル。

  • ビットマップ ファイル
  • 9-patch(サイズ変更できるビットマップ)
  • 状態リスト
  • シェイプ
  • アニメーション ドローアブル
  • その他のドローアブル

詳しくは、ドローアブル リソースをご覧ください。

mipmap/ ランチャー アイコンの密度に応じたドローアブル ファイル。mipmap/ フォルダを使用してランチャー アイコンを管理する方法については、アプリアイコンを mipmap ディレクトリに配置するをご覧ください。
raw/

未加工の形式で保存する任意のファイル。このリソースを未加工の InputStream で開くには、リソース ID(R.raw.filename)を指定して Resources.openRawResource を呼び出します。

ただし、元のファイル名とファイル階層にアクセスする必要がある場合は、リソースの一部を res/raw/ ではなく assets/ ディレクトリに保存することを検討してください。assets/ に保存されたファイルにはリソース ID が付けられません。そのため、このファイルは AssetManager を使用する場合にだけ読み取ることができます。

values/

単純な値(文字列、整数、色など)を保存する XML ファイル。

他の res/ サブディレクトリにある XML リソース ファイルは XML ファイル名に基づいて 1 つのリソースを定義するものですが、values/ ディレクトリにあるファイルは複数のリソースを表します。このディレクトリにあるファイルについては、<resources> 要素の子要素ごとにリソースが 1 つずつ定義されます。たとえば、<string> 要素は R.string リソースを作成し、<color> 要素は R.color リソースを作成します。

リソースはそれぞれ独自の XML 要素で定義されるので、ファイルに自由に名前を付けてさまざまなリソースタイプを 1 つのファイルに保存できます。ただし、わかりやすくするために、保存するリソースのタイプをファイルごとに 1 つだけにすることもできます。このディレクトリに作成できるリソースのファイル名規則の例を次に示します。

詳しくは、文字列リソーススタイル リソースその他のリソースタイプをご覧ください。

xml/ 実行時に Resources.getXML を呼び出して読み取ることができる任意の XML ファイル。各種の XML 構成ファイルはここに保存する必要があります。
font/ TTF、OTF、TTC などの拡張子を持つフォント ファイル、または <font-family> 要素を含む XML ファイル。リソースとしてのフォントについて詳しくは、フォントを XML リソースとして追加するをご覧ください。

注意: リソース ファイルを res/ ディレクトリの中に直接保存しないでください。コンパイラ エラーが発生します。

表 1 で定義したサブディレクトリに保存するリソースは、デフォルトのリソースです。つまり、このリソースではアプリのデフォルトのデザインとコンテンツを定義します。しかし、Android 搭載デバイスの種類が異なれば、要求されるリソースタイプも異なる可能性があります。

たとえば、デバイスの言語設定に基づいて、ユーザー インターフェースのテキストを翻訳するさまざまな文字列リソースを使用できます。

注: Compose では、UI、アニメーション、状態駆動型の色が Kotlin で宣言されるため、layout/menu/anim/animator/color/ ディレクトリは最新のアプリでは廃止されています。詳細については、Compose のアニメーションCompose のテーマの構造をご覧ください。

代替リソースの指定

ほとんどのアプリで、デバイスの構成ごとに代替リソースを用意する必要があります。たとえば、各種の画面密度に対応した代替のドローアブル リソースや、各種の言語に対応した代替の文字列リソースを追加します。実行時に、Android によって現在のデバイス構成が自動的に検出され、アプリに適したリソースが読み込まれます。

リソースセットに対応した構成固有の代替リソースを指定する手順は次のとおりです。

  1. res/ の中に、<resources_name>-<qualifier> という形式の名前で新しいディレクトリを作成します。
    • <resources_name> は、対応するデフォルトのリソースのディレクトリ名です(表 1 で定義)。
    • <qualifier> は、そのリソースが使用される個々の構成を指定する名前です(表 2 で定義)。

    <qualifier> は複数追加できます。それらはダッシュ記号でつなぎます。

    注意: 複数の修飾子を追加する場合は、それらを表 2 の記載と同じ順序で配置する必要があります。修飾子の順序が間違っている場合、そのリソースは無視されます。

  2. この新しいディレクトリに適切な代替リソースを保存します。リソース ファイルにはデフォルトのリソース ファイルと同じ名前を付ける必要があります。

デフォルトのリソースと代替リソースの例を次に示します。

res/
    drawable/
        icon.png
        background.png
    drawable-hdpi/
        icon.png
        background.png

hdpi 修飾子は、そのディレクトリにあるリソースが高密度画面を備えたデバイス用であることを示します。これらの drawable ディレクトリにある画像のサイズは画面密度ごとに調整されていますが、ファイル名は同じです。このように、icon.pngbackground.png の画像を参照する際に使用するリソース ID は常に同じです。Android では、デバイス構成情報をリソース ディレクトリ名の修飾子と比較することで、現在のデバイスに最も適したバージョンのリソースをそれぞれ選択します。

注意: 代替リソースを定義する場合は、必ずデフォルト構成でもリソースを定義してください。そうしないと、デバイスで構成が変更された場合にアプリでランタイム例外が発生する可能性があります。たとえば、文字列を values-en だけに追加して values には追加しないと、ユーザーがデフォルトのシステム言語を変更したときに、アプリで Resource Not Found 例外が発生することがあります。

表 2 では、構成修飾子の一覧を優先度の高い順に示します。複数の修飾子をダッシュ記号でつなぐことで 1 つのディレクトリ名に追加できます。リソース ディレクトリで複数の修飾子を使用する場合は、それらを表に記載されている順序でディレクトリ名に追加する必要があります。

表 2. 構成修飾子の名前。

構成 修飾子の値 説明
MCC と MNC 例:
mcc310
mcc310-mnc004
mcc208-mnc00

デバイスの SIM カードに登録されているモバイル カントリー コード(MCC)。必要に応じて直後にモバイル ネットワーク コード(MNC)が付きます。たとえば、mcc310 は米国の任意の携帯通信会社、mcc310-mnc004 は米国 Verizon 社、mcc208-mnc00 はフランス Orange 社を表します。

無線接続を使用しているデバイス(GSM フォン)の場合、MCC と MNC の値は SIM カードから取得されます。

MCC のみを使用することもできます(たとえば、アプリに国別の法的リソースを含める場合など)。言語だけに基づいて指定する必要がある場合は、代わりに言語、文字(省略可)、地域(省略可)の修飾子を使用してください。MCC および MNC 修飾子の使用には注意が必要です。想定どおりに動作することをテストしてください。

また、現在のモバイル カントリー コードを示す構成フィールド mcc と、モバイル ネットワーク コードを示す構成フィールド mnc もご覧ください。

言語、文字(省略可)、地域(省略可) 例:
en
fr
en-rUS
fr-rFR
fr-rCA
b+en
b+en+US
b+es+419
b+zh+Hant
b+sr+Latn+RS

言語は 2 文字の ISO 639-1 言語コードによって定義され、必要に応じて 2 文字の ISO 3166-1-alpha-2 地域コード(先頭は小文字の r)が付きます。

コードの大文字と小文字は区別されません。 r 接頭辞は地域部分の区別に使用します。地域だけを指定することはできません。

Android 7.0(API レベル 24)では、BCP 47 言語タグのサポートが導入され、言語と地域に固有のリソースを修飾できるようになりました。言語タグは 1 つ以上のサブタグで構成されます。各サブタグは、タグ全体で識別される言語の範囲を絞り込むために使用されます。言語タグについて詳しくは、Tags for Identifying Languages をご覧ください。

BCP 47 言語タグを使用するには、b+ と 2 文字の ISO 639-1 言語コードを連結し、必要に応じて + で区切られたサブタグを追加します。

ユーザーがシステム設定で言語を変更すると、アプリの実行中に言語タグが変わる可能性があります。このことが実行時にアプリに与える影響について詳しくは、設定の変更に対処するをご覧ください。

他の言語向けにアプリをローカライズする方法については、アプリをローカライズするをご覧ください。

定義されたロケールのリストを提供する getLocales メソッドも確認してください。このリストには主要なロケールが含まれています。

文法性 masculine
feminine
neuter

ユーザーの文法上の性別。文法上の性別がある言語で使用されます。

たとえば、フランス語を話すユーザー向けに異なるリソースを提供する必要がある場合は、次のようなディレクトリを使用できます。

res/
  values-fr/
    strings.xml(性別が指定されていないデフォルトの文字列)
  values-fr-masculine/
    strings.xml(男性の性別が指定されている文字列)
  values-fr-feminine/
    strings.xml(女性の性別が指定されている文字列)
  values-fr-neuter/
    strings.xml(中性の性別が指定されている文字列)

文法上の性別でアプリの UI をパーソナライズするをご覧ください。

文法上の性別を示す getGrammaticalGender 構成メソッドもご覧ください。

API レベル 34 で追加されました。

広色域 widecg
nowidecg
  • widecg: 色域が広いディスプレイ(Display P3 や AdobeRGB など)
  • nowidecg: 色域が狭いディスプレイ(sRGB など)

API レベル 26 で追加されました。

画面の色域が広いかどうかを示す isScreenWideColorGamut 構成メソッドもご覧ください。

ハイ ダイナミック レンジ(HDR) highdr
lowdr
  • highdr: ハイ ダイナミック レンジのディスプレイ
  • lowdr: ダイナミック レンジが低いか標準であるディスプレイ

API レベル 26 で追加されました。

画面が HDR 対応かどうかを示す isScreenHdr 構成メソッドもご覧ください。

UI モード car
desk
television
appliance
watch
vrheadset
  • car: デバイスはカーホルダーに装着され、画面を表示しています
  • desk: デバイスは卓上ホルダーに装着され、画面を表示しています
  • television: デバイスの画面はテレビに表示されており、「10 フィート エクスペリエンス」用になっています。ユーザー インターフェースは大型画面に表示されており、ユーザーはそこから離れた場所にいます。また、主に D-pad などの非ポインタ操作が中心となります
  • appliance: デバイスは装置として、画面なしで稼働しています
  • watch: デバイスは画面の表示があり、腕に装着されます
  • vrheadset: デバイスの画面はバーチャル リアリティ ヘッドセットで表示されています

API レベル 8 で追加されました。television は API 13、appliance は API 16、watch は API 20、vrheadset は API 26 で追加されました。

デバイスをホルダーに装着した場合と取り外した場合のアプリの反応について詳しくは、装着状態とタイプを特定して監視するをご覧ください。

ユーザーがデバイスをホルダーに置いた場合、この設定はアプリの実行中に変更される可能性があります。このモードの一部を有効または無効にするには UiModeManager を使用します。 このことが実行時にアプリに与える影響について詳しくは、実行時の変更の処理をご覧ください。

夜間モード night
notnight
  • night: 夜間
  • notnight: 日中

API レベル 8 で追加されました。

夜間モードが自動モードのままにされている場合(デフォルト)、アプリの実行中に変更される可能性があります。自動モードでは、時間帯に応じてモードが変更されます。このモードを有効または無効にするには UiModeManager を使用します。 このことが実行時にアプリに与える影響について詳しくは、実行時の変更の処理をご覧ください。

画面のピクセル密度(dpi) ldpi
mdpi
hdpi
xhdpi
xxhdpi
xxxhdpi
nodpi
tvdpi
anydpi
nnndpi
  • ldpi: 低密度画面(およそ 120 dpi)。
  • mdpi: 中密度画面(従来の HVGA、およそ 160 dpi)。
  • hdpi: 高密度画面(およそ 240 dpi)。
  • xhdpi: 超高密度画面(およそ 320 dpi)。API レベル 8 で追加されました
  • xxhdpi: 超超高密度画面(およそ 480 dpi)。API レベル 16 で追加されました
  • xxxhdpi: 超超超高密度(ランチャー アイコンのみ。各種のピクセル密度をサポートするを参照)(およそ 640 dpi)。API レベル 18 で追加されました。
  • nodpi: ビットマップ リソースをデバイスの密度に合わせて拡大縮小したくない場合に使用します。
  • tvdpi: mdpi から hdpi の範囲の画面(およそ 213 dpi)。 これは「メイン」の密度グループとしては認識されません。主に 720p のテレビが念頭に置かれており、ほとんどのアプリでは必要ありません。1080p のテレビの場合は xhdpi、4K のテレビの場合は xxxhdpi を使用します。API レベル 13 で追加されました。
  • anydpi: すべての画面密度に一致し、他の修飾子よりも優先されます。これはベクター型ドローアブルで役立ちます。API レベル 21 で追加されました
  • nnndpi: 標準以外の密度を表すために使用します。nnn は正の整数の画面密度です。ほとんどの場合、使用されません。標準密度のバケットを使用すると、市販のさまざまなデバイスの画面密度をサポートする際のオーバーヘッドを大幅に削減できます。

6 つの主要な密度の間には 3:4:6:8:12:16 というスケーリング比があります(tvdpi 密度は無視してください)。そのため、ldpi の 9x9 ビットマップは、mdpi では 12x12、hdpi では 18x18、xhdpi では 24x24 になります。

注: 密度修飾子を使用した場合でも、リソースはその密度の画面のみで使用されるわけではありません。現在のデバイス構成により適した修飾子付きの代替リソースが用意されていない場合、システムは最も適しているいずれかのリソースを使用できます。

さまざまな画面密度の処理方法や、現在の密度に合わせてビットマップが拡大縮小される仕組みについて詳しくは、画面の互換性の概要をご覧ください。

タッチスクリーンのタイプ notouch
finger
  • notouch: デバイスにタッチスクリーンがありません。
  • finger: デバイスは、ユーザーが指を使って操作できるタッチスクリーンを備えていません。

デバイスのタッチスクリーンのタイプを示す touchscreen 構成フィールドもご覧ください。

キーボードを使用できるかどうか keysexposed
keyshidden
keyssoft
  • keysexposed: デバイスはキーボードを備えています。デバイスでソフトウェア キーボードが有効になっている場合は(多くの場合そのようになっています)、デバイスがハードウェア キーボードを備えていなくても、またはユーザーがハードウェア キーボードを表に出していないときでも、この修飾子が使用されます。ソフトウェア キーボードを備えていない場合やソフトウェア キーボードが無効になっている場合には、ユーザーがハードウェア キーボードを表に出しているときだけ、この修飾子が使用されます。
  • keyshidden: デバイスには使用可能なハードウェア キーボードがあるものの、それが表に出ておらず、またデバイスでソフトウェア キーボードが有効になっていません。
  • keyssoft: デバイスでソフトウェア キーボードが有効になっています。表示されているかどうかは関係ありません。

keyssoft リソースではなく keysexposed リソースを指定すると、システムでソフトウェア キーボードが有効になっている限り、キーボードが表示されているかどうかにかかわらず、keysexposed リソースが使用されます。

ユーザーがハードウェア キーボードを表に出した場合、アプリの実行中に変更される可能性があります。このことが実行時にアプリに与える影響について詳しくは、実行時の変更の処理をご覧ください。

また、構成フィールド hardKeyboardHiddenkeyboardHidden もご覧ください。これらは、それぞれハードウェア キーボードの可視性と、あらゆる種類のキーボード(ソフトウェアを含む)の可視性を示します。

メインのテキスト入力方法 nokeys
qwerty
12key
  • nokeys: デバイスはテキスト入力用のハードウェア キーを備えていません。
  • qwerty: デバイスは QWERTY 配列のハードウェア キーボードを備えています。表に出ているかどうかは関係ありません。
  • 12key: デバイスは 12 キーのハードウェア キーボードを備えています。表に出ているかどうかは関係ありません。

使用できるメインのテキスト入力方法を示す keyboard 構成フィールドもご覧ください。

プラットフォームのバージョン(API レベル) 例:
v3
v4
v7

デバイスでサポートされている API レベル。たとえば、API レベル 1(Android 1.0 以降のデバイス)では v1、API レベル 4(Android 1.6 以降のデバイス)では v4 です。これらの値について詳しくは、Android API レベルのドキュメントをご覧ください。

注: Android のすべてのバージョンですべての修飾子がサポートされているわけではありません。新しい修飾子を使用すると、プラットフォーム バージョンの修飾子が暗黙的に追加され、古いバージョンのデバイスで無視できるようになっています。問題を避けるため、必ず、デフォルトのリソースセット(修飾子を付けないリソースのセット)を用意してください。詳しくは、リソースに関するデバイスの互換性を最適に保つをご覧ください。

Compose アプリでは、レイアウトとディメンションに関連する構成修飾子は必要ありません。これらのデバイスは、引き続き存在しますが、表 2 から除外されます。これらの修飾子には、レイアウトの方向、最小幅、利用可能な幅、利用可能な高さ、画面サイズ、画面のアスペクト比、丸い画面、画面の向きなどがあります。優先順位順に並べた構成修飾子の完全な表については、アプリリソースの概要(ビュー)をご覧ください。

修飾子の命名規則

構成修飾子の名前を使用する場合の規則は次のとおりです。

  • 複数の修飾子をダッシュ記号でつないで 1 つのリソースセットとして指定できます。たとえば drawable-en-rUS-night は、言語が英語(米国)で夜間モードのデバイスに適用されます。
  • 修飾子は表 2 に記載されている順序で指定する必要があります。
    • 不適切: drawable-hdpi-night/
    • 適切: drawable-night-hdpi/
  • 代替リソース ディレクトリはネストできません。たとえば、res/drawable/drawable-en/ のようにはできません。
  • 値は大文字と小文字が区別されません。大文字と小文字が区別されないファイル システムで問題が生じるのを避けるため、リソース コンパイラでは処理の前にディレクトリ名が小文字に変換されます。大文字を使用するのは単に名前を読みやすくする場合だけです。
  • 修飾子の種類ごとに 1 つの値だけを指定できます。たとえば、スペインとフランスで同じドローアブル ファイルを使用する場合、drawable-es-fr/ というディレクトリは作成できません。その場合は、drawable-es/drawable-fr/ というように、それぞれのファイルを保存する 2 つのリソース ディレクトリが必要になります。

この修飾子で名前を付けたディレクトリに代替リソースを保存すると、現在のデバイス構成に基づいてアプリのリソースが自動的に適用されます。リソースが必要になるたびに、必要なリソース ファイルが保存されている代替リソース ディレクトリが調べられ、最適なリソースが見つけられます

デバイス構成に一致する代替リソースがない場合は、対応するデフォルトのリソースが使用されます。デフォルトのリソースとは、特別なリソースタイプに用意された、構成修飾子が付かないリソースセットです。

エイリアス リソースの作成

あるリソースを複数のデバイス構成で使用したいが、デフォルトのリソースにはしたくない場合、その同じリソースを複数の代替リソース ディレクトリに保存する必要はありません。代わりに、デフォルトのリソース ディレクトリに保存したリソースのエイリアスとして機能する代替リソースを作成できます。

ドローアブル

たとえば、icon.png というアプリアイコンがあり、ロケールごとに固有のバージョンが必要だとします。しかし、English-Canadian と French-Canadian の 2 つのロケールについては同じバージョンを使用する必要があるとします。この場合、English-Canadian 用と French-Canadian 用の両方のリソース ディレクトリに同じ画像をコピーする必要はありません。代わりに、両方に使用する画像を icon.png 以外の任意の名前(icon_ca.png など)で保存し、デフォルトの res/drawable/ ディレクトリに置くことができます。次に、res/drawable-en-rCA/res/drawable-fr-rCA/ に、<bitmap> 要素を使用して icon_ca.png リソースを参照する icon.xml ファイルを作成します。

<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android" android:src="@drawable/icon_ca" />

こうすることで、PNG ファイルの 1 つのバージョンと、それを参照する 2 つの小さな XML ファイルを保存するだけで済みます。その後、painterResource(R.drawable.icon) を使用すると、言語 / 地域が検出されたときに適切なファイルが選択されます。

文字列やその他の単純な値

既存の文字列のエイリアスを作成するには、必要な文字列のリソース ID を新しい文字列の値として使用します。

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="hello">Hello</string>
    <string name="hi">@string/hello</string>
</resources>

これで、R.string.hi リソースは R.string.hello のエイリアスになります。

色など、他の単純な値についても同様です。

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="red">#f00</color>
    <color name="highlight">@color/red</color>
</resources>

アプリのリソースにアクセスする

アプリでリソースを指定したら、そのリソース ID を参照して適用できます。すべてのリソース ID は、aapt ツールによって自動的に生成される、プロジェクトの R クラスで定義されます。

アプリがコンパイルされると、aaptR クラスを生成します。このクラスには、res/ ディレクトリ内のすべてのリソースのリソース ID が含まれています。リソースのタイプごとに R サブクラスがあります。たとえば、R.drawable はすべてのドローアブル リソースに対応します。また、そのタイプのリソースごとに静的整数があります(たとえば R.drawable.icon)。この整数は、リソースの取得に使用できるリソース ID です。

R クラスはリソース ID を指定するために使用されますが、リソース ID を検出するためにこれを確認する必要はありません。リソース ID は常に次の要素で構成されます。

  • リソースタイプ: 各リソースは stringdrawable などの「タイプ」に分類されます。
  • リソース名。拡張子を除いたファイル名です。

Compose でリソースにアクセスする

Jetpack Compose には、リソースに安全にアクセスするためのコンポーザブル対応の組み込み関数が用意されています。

  • 文字列:
    stringResource(id = R.string.hello)
  • Drawables:
    painterResource(id = R.drawable.my_icon)

UI 以外のコードでリソースにアクセスする

ViewModelRepository、システム Service など、UI 階層外のリソースにアクセスする必要がある場合は、Context を使用して解決できます。

// Retrieve a localized string resource
val greeting = context.getString(R.string.hello_world)

Resources のメソッドを使用して個々のリソースを取得することもできます。このインスタンスは getResources メソッドで取得できます。

構文

コード内でリソースを参照する構文は次のとおりです。

[<package_name>.]R.<resource_type>.<resource_name>
  • <package_name> は、リソースがあるパッケージの名前です(独自のパッケージからリソースを参照する場合は必要ありません)。
  • <resource_type> はリソースタイプの R サブクラスです。
  • <resource_name> は、拡張子のないリソース ファイル名、または XML 要素の android:name 属性値(単純な値の場合)です。

各リソースタイプの詳細と参照方法については、Compose のリソースをご覧ください。

元のファイルにアクセスする

場合によっては、元のファイルとディレクトリへのアクセスが必要になることがあります。その場合、res/ からリソースを読み取るにはリソース ID を使用するしかないため、res/ にファイルを保存するのは適切ではありません。代わりに、assets/ ディレクトリにリソースを保存します。

assets/ ディレクトリに保存されているファイルにはリソース ID が割り当てられないため、R クラスや XML リソースから参照することはできません。代わりに、通常のファイル システムと同様に assets/ ディレクトリ内のファイルをクエリし、AssetManager を使用して元データを読み取ることができます。

ただし、元データ(動画や音声ファイルなど)を読み取るだけでよい場合は、res/raw/ ディレクトリにファイルを保存し、openRawResource を使用してバイト ストリームとして読み取ります。

プラットフォーム リソースにアクセスする

Android には、システム スタイルやテーマなど、さまざまな標準リソースが含まれています。これらにアクセスするには、リソース参照を android パッケージ クラスで修飾します。(例: painterResource(android.R.drawable.ic_menu_info_details))。

リソースに関するデバイスの互換性を最適に保つ

アプリで複数のデバイス構成をサポートするには、アプリが使用するリソースのタイプごとにデフォルトのリソースを準備しておくことが重要です。

たとえば、アプリで複数の言語をサポートする場合は、必ず、言語と地域の修飾子を付けない values/ ディレクトリを用意しておきます(このディレクトリに文字列を保存します)。このようにせず、言語と地域の修飾子を付けたディレクトリにすべての文字列ファイルを保存した場合、文字列が対応していない言語に設定されたデバイス上でアプリが実行されたとき、アプリはクラッシュします。

デフォルトの values/ リソースを用意しておけば、ユーザーがその言語を理解しないとしても、アプリは適切に実行されます。クラッシュするよりはるかによいでしょう。

デフォルトのリソースを準備しておくことが重要なのは、アプリが予期しない構成で実行される場合があるだけでなく、Android の新しいバージョンには、古いバージョンでサポートしていない構成修飾子が追加されることがあるためです。新しいリソース修飾子を使用し、古いバージョンの Android とのコード互換性も保つ場合、デフォルトのリソースを用意しておかないと、古いバージョンの Android でアプリが実行されたとき、アプリは新しい修飾子が名前に付いたリソースを使用できないため、クラッシュします。

たとえば、minSdkVersion を 4 に設定し、夜間モード(API レベル 8 で追加された night または notnight)を使用してすべてのドローアブル リソースを修飾するとします。その場合、API レベル 4 のデバイスはドローアブル リソースにアクセスできず、クラッシュします。これに対処するには、notnight をデフォルトのリソースにして、問題の修飾子は使用せず、ドローアブル リソースを drawable/drawable-night/ に用意します。

簡単に言えば、デバイスの互換性を適切に保つには、アプリを正しく実行するために必要なリソースについて、必ずデフォルトのリソースを用意しておきます。そのうえで、構成修飾子を使って個々のデバイス構成用に代替リソースを作成します。

このルールには 1 つだけ例外があります。アプリの minSdkVersion が 4 以上で、画面密度の修飾子を付けた代替ドローアブル リソースを用意した場合は、デフォルトのドローアブル リソースは必要ありません。デフォルトのドローアブル リソースがなくても、Android は代替の画面密度から最適な密度を見つけて、必要に応じてビットマップを拡大縮小できます。ただし、すべての種類のデバイスで最良のエクスペリエンスを提供するには、3 種類の密度のすべてについて代替のドローアブル リソースを用意してください。

Android が最適なリソースを見つける仕組み

Android では、代替リソースが提供されているリソースがシステムで必要になると、現在のデバイス構成に応じて、どの代替リソースを使用するのかが実行時に選択されます。Android による代替リソースの選択の仕組みを理解するため、次の各ドローアブル ディレクトリに、同じ画像の異なるバージョンが保存されている場合を考えてみましょう。

drawable/
drawable-en/
drawable-fr-rCA/
drawable-en-night/
drawable-en-notouch-12key/
drawable-night-ldpi/
drawable-night-notouch-12key/

デバイス構成は次のようになっているとします。

ロケール = en-GB
夜間モード = night
画面のピクセル密度 = hdpi
タッチスクリーンのタイプ = notouch
メインのテキスト入力方法 = 12key

Android によってデバイス構成と使用可能な代替リソースとが比較され、drawable-en-night のドローアブルが選択されます。

システムは次のようなロジックで、使用するリソースを決定します。

図 2. Android が最適なリソースをどのように見つけるかを示すフローチャート

  1. デバイス構成と一致しないリソース ファイルが除外されます。

    drawable-fr-rCA/ ディレクトリは、en-GB ロケールと矛盾するため除外されます。

    drawable/
    drawable-en/
    drawable-fr-rCA/
    drawable-en-night/
    drawable-en-notouch-12key/
    drawable-night-ldpi/
    drawable-night-notouch-12key/
    

    例外: 画面のピクセル密度を表す修飾子は、不一致が原因で除外されることはありません。デバイスの画面密度は hdpi ですが、この時点ではすべての画面密度が一致しているものと見なされるので、drawable-night-ldpi/ は除外されません。詳しくは、画面の互換性の概要をご覧ください。

  2. 一覧(表 2)で、次に優先度の高い修飾子を見つけます。(MCC から始めます)
  3. この修飾子が含まれているリソース ディレクトリがあるかどうかが調べられます。
    • ない場合は、ステップ 2 に戻って次の修飾子を調べます。(この例では、言語修飾子に達するまで答えは「ない」です)。
    • ある場合は、ステップ 4 に進みます。
  4. この修飾子が含まれていないリソース ディレクトリが除外されます。この例では、次に、言語修飾子が含まれていないディレクトリがすべて除外されます。
    drawable/
    drawable-en/
    drawable-en-night/
    drawable-en-notouch-12key/
    drawable-night-ldpi/
    drawable-night-notouch-12key/
    

    例外: 対象の修飾子が画面のピクセル密度の場合、Android はデバイスの画面密度に最も近い設定を選択します。通常は、小さい方の元画像を拡大するよりも、大きい方の元画像を縮小する方が優先されます。詳しくは、画面の互換性の概要をご覧ください。

  5. ただ 1 つのディレクトリが残るまでステップ 2、3、4 を繰り返します。この例では、比較の対象となる次の修飾子はナイトモードです。そのため、夜間モードが指定されていないリソースは除外されます。
    drawable-en/
    drawable-en-night/
    drawable-en-notouch-12key/
    

    残りのディレクトリは drawable-en-night です。

上記の手順は必要なリソースごとに実行されますが、一部の処理はシステムによって最適化されます。たとえば、デバイス構成が判明した時点で、まったく一致しない代替リソースが除外される場合があります。たとえば、構成の言語が英語の場合には、英語以外に設定された言語修飾子を持つリソース ディレクトリはすべて、チェック対象のリソースプールから除外されます(ただし、言語修飾子を「持たない」リソース ディレクトリはまだ残されます)。

画面サイズの修飾子に基づいてリソースを選択する場合、最適なリソースがない場合は、現在の画面よりも小さい画面向けに設計されたリソースが使用されます。たとえば、「large」サイズの画面では、必要に応じて「normal」サイズの画面のリソースを使用します。

ただし、使用できるリソースがそのときの画面よりも大きい画面のものしかない場合、システムはその大きい画面向けのリソースを使用せず、他にデバイスの構成に一致するリソースがなければアプリはクラッシュしてしまいます。このような状況は、たとえば、レイアウト リソースすべてに修飾子 xlarge が付いているが、デバイスの画面サイズは「normal」である場合に起こります。

注: デバイスと正確に一致する修飾子がいくつあるのかよりも、表 2 に示す修飾子の優先度の方が重要視されます。上記の例のステップ 4 で、一覧の最後の選択肢にはデバイスと正確に一致する修飾子が 3 つ含まれていますが(ナイトモード、タッチスクリーンのタイプ、入力方法)、drawable-en には一致する 1 つのパラメータ(言語)しかありません。しかし、言語の方が他の修飾子よりも優先度が高いので、drawable-night-notouch-12key は除外されます。

参考情報

アプリ リソースの詳細については、以下のリソースをご覧ください。

ドキュメント

コンテンツの閲覧