Android は、他のプラットフォームのディスクベース ファイル システムと同様のファイル システムを使用しています。システムには、アプリデータの保存方法として次のような選択肢が用意されています。
- アプリ固有のストレージ: アプリ専用のファイルを、内部ストレージ ボリューム内の専用ディレクトリ、または外部ストレージ内の別の専用ディレクトリに保存します。他のアプリがアクセスできない機密情報の保存には、内部ストレージ内のディレクトリを使用します。
- 共有ストレージ: メディアやドキュメントなど、アプリが他のアプリと共有するファイルを保存します。
- 設定: 非公開のプリミティブ データを Key-Value ペアで保存します。
- データベース: Room 永続ライブラリを使用して、構造化データを非公開のデータベースに保存します。
これらの選択肢の特徴を次の表にまとめます。
コンテンツの種類 | アクセス手段 | 必要な許可 | 他のアプリがアクセス可能 | アプリのアンインストール時に削除される | |
---|---|---|---|---|---|
アプリ固有のファイル | お客様のアプリのみで使用するファイル | 内部ストレージからは getFilesDir() または getCacheDir() 外部ストレージからは getExternalFilesDir() または getExternalCacheDir() |
内部ストレージには不要 Android 4.4(API レベル 19)以降を搭載するデバイスでアプリを使用する場合、外部ストレージには不要 |
ファイルが内部ストレージ内のディレクトリにある場合、不可能 ファイルが外部ストレージ内のディレクトリにある場合、可能 |
削除される |
メディア | 共有可能なメディア ファイル(画像、音声ファイル、動画) | MediaStore API |
Android 10(API レベル 29)以降で他のアプリのファイルにアクセスする場合、READ_EXTERNAL_STORAGE または WRITE_EXTERNAL_STORAGE Android 9(API レベル 28)以前では、すべてのファイルで許可が必要 |
可能(ただし、他のアプリでは READ_EXTERNAL_STORAGE 権限が必要) |
削除されない |
ドキュメントやファイル | ダウンロードしたファイルを含めた、共有可能なその他の種類のコンテンツ | ストレージ アクセス フレームワーク | なし | 可能(システムのファイル選択ツールを使用) | 削除されない |
アプリ設定 | Key-Value ペア | Jetpack Preferences ライブラリ | なし | 不可能 | 削除される |
データベース | 構造化データ | Room 永続ライブラリ | なし | 不可能 | 削除される |
選択するソリューションは、次のようなニーズによって異なります。
- データに必要な容量
- 内部ストレージのアプリ固有データ用のスペースは限られています。大量のデータを保存する必要がある場合は、他のストレージを使用します。
- データアクセスの信頼性
- アプリの起動時など、アプリの基本機能に特定のデータが必要な場合は、内部ストレージのディレクトリまたはデータベースに保存します。外部ストレージに保存されているアプリ固有のファイルは、外部ストレージの物理デバイスをユーザーが取り外すことができるため、常にアクセスできるわけではありません。
- 保存する必要があるデータの種類
- お客様のアプリにとってだけ意味のあるデータには、アプリ固有のストレージを使用します。共有可能なメディア コンテンツには、他のアプリがコンテンツにアクセスできるように共有ストレージを使用します。構造化データには、設定(Key-Value データの場合)またはデータベース(2 列以上のデータの場合)を使用します。
- データを非公開にする必要性
- 他のアプリからアクセスできてはいけない機密データを保存する場合は、内部ストレージ、設定、またはデータベースを使用します。内部ストレージには、データがユーザーから隠されるというメリットもあります。
保存場所の種類
Android には、内部ストレージと外部ストレージという、2 種類の物理的な保存場所があります。ほとんどのデバイスで、内部ストレージの容量は外部ストレージよりも少なくなっています。ただし、内部ストレージは常にすべてのデバイスで利用できるため、アプリにとって重要なデータを保存する場所としては、より信頼性が高い場所です。
SD カードなどのリムーバブル ボリュームは、外部ストレージの一部としてファイル システムの中に現れます。Android では、こういったデバイスを /sdcard
のようなパスを使用して表します。
アプリ自体はデフォルトで内部ストレージに保存されます。ただし、APK のサイズが非常に大きい場合は、次のようにアプリのマニフェスト ファイルで設定を指定して、アプリを外部ストレージにインストールさせることができます。
<manifest ... android:installLocation="preferExternal"> ... </manifest>
外部ストレージに対する権限とアクセス
Android では、外部ストレージに対する読み取りと書き込みのアクセス権として READ_EXTERNAL_STORAGE
と WRITE_EXTERNAL_STORAGE
が定義されています。
以前のバージョンの Android では、外部ストレージ上のアプリ固有のディレクトリの外にあるファイルにアクセスするために、これらの権限を宣言する必要がありました。これより新しいバージョンの Android では、アプリのファイルへのアクセス権を判断するにあたって、ファイルの場所よりも用途を重視します。このような用途に基づいたストレージ モデルでは、デバイスのファイル システムにある、アプリが実際に使用する領域のみにアクセスできるため、ユーザーのプライバシーが向上します。
対象範囲別ストレージ
ユーザーがファイルを詳細に管理して整理できるように、Android 10(API レベル 29)以降をターゲットとするアプリには、外部ストレージに対する特別アクセス権限がデフォルトで付与されます(対象範囲別ストレージ)。このようなアプリでアクセスできるのは、外部ストレージにあるアプリ固有ディレクトリと、そのアプリが作成したメディアタイプだけに限られます。
アプリ固有のディレクトリの外にあり、MediaStore
API でアクセスできるディレクトリの外にあるファイルへのアクセス権を必要とするのでない限り、対象範囲別ストレージを使用してください。アプリ固有のファイルを外部ストレージに保存する場合は、外部ストレージのアプリ固有のディレクトリに配置することで、対象範囲別ストレージの導入が容易になります。このようにして、対象範囲別ストレージが有効なとき、アプリでアプリ固有のファイルへのアクセス権を管理します。
アプリに対象範囲別ストレージでは対応できないユースケースがある場合は、機能リクエストを申請して、プラットフォームで提供されているアプリ互換性機能を使用してください。
ファイル操作に関するおすすめの方法
このセクションでは、アプリからファイルを開いて共有することに関する一般的なおすすめの方法をいくつか紹介します。
ファイルを繰り返し開いたり閉じたりしない
アプリのパフォーマンスを落とさないために、同じファイルを何度も開いたり閉じたりしないでください。システムがファイルを開き、最初にファイルを読み取るときにコストがかかります。
個々のファイルを共有する
個々のファイルやアプリデータを他のアプリと共有する場合、Android では次の API が用意されています。
- 特定のファイルを他のアプリと共有する場合は、
FileProvider
API を使用します。 - データを他のアプリに公開する場合は、コンテンツ プロバイダを使用できます。コンテンツ プロバイダを使用すると、他のアプリに与える読み書きアクセス権を完全に制御できます。ストレージ メディアでもコンテンツ プロバイダを使用できますが、データベースで使用するのが一般的です。
デバイス上のファイルを表示する
デバイスに保存されているファイルを表示するには、Android Studio の Device File Explorer を使用します。
参考情報
データ ストレージの詳細については、次のリソースをご覧ください。