アプリ開発において、内部ストレージや外部ストレージのデータ保存領域について改めて調べる必要があったので、今後の開発用の覚書としてまとめることにしました。
特にAndroid 10以降で導入された「Scoped Storage(対象範囲別ストレージ)」によって、ファイルアクセスの仕様が大きく変化しています。
キャッシュとして扱うべきか、ユーザーの永続データとして扱うべきかによって適切なパスやAPIが異なるため、モダンなOS環境に合わせて一覧で参照できるようにしています。
Unityにおけるデータ保存パスと取得領域一覧
Unityの Application クラスを利用して取得できるパスと、各OS(Android / iOS)における実際の保存領域の対応表です。
| パス取得変数 | 環境 | データの領域 | 取得パスの例 |
|---|---|---|---|
| Application.dataPath | Android | – | /data/app/<パッケージ名>-<ハッシュ>/base.apk |
| 同上 | iOS | – | /var/containers/Bundle/Application/<固有ID>/myappname.app/Data |
| Application.persistentDataPath | Android | 外部データ(アプリ専用) | /storage/emulated/0/Android/data/<アプリのID>/files/ |
| 同上 | iOS | 内部データ | /var/mobile/Containers/Data/Application/<固有ID>/Documents |
| Application.temporaryCachePath | Android | 外部キャッシュ | /storage/emulated/0/Android/data/<アプリのID>/cache/ |
| 同上 | iOS | 内部キャッシュ | /var/mobile/Containers/Data/Application/<固有ID>/Library/Caches |
※Android環境において、persistentDataPath や temporaryCachePath は、アンインストール時にデータが削除されるアプリ専用領域(Scoped Storageに準拠)を指すのが現在の基本挙動です。
Androidネイティブにおけるストレージ領域と最新のパス取得
続いて、Androidのネイティブ環境(Java/Kotlin)で取得できる各種ディレクトリのパスと特徴です。APIレベル29(Android 10)以降の仕様変更に注意が必要です。
検証・前提環境
- OS:Android 10 以降 (Scoped Storage適用環境)
- 言語:Java / Kotlin
| パス取得メソッド | 領域 | アプリ専用 | ユーザ許可 | アプリ削除時 | 備考・現在の仕様 |
|---|---|---|---|---|---|
| Context.getFilesDir() | 内部データ | ◯ | 不要 | 消える | アプリ占有の内部領域(/data/user/0/<アプリID>/files) |
| Context.getCacheDir() | 内部キャッシュ | ◯ | 不要 | 消える | OSによって自動消去される可能性がある内部領域 |
| Context.getExternalFilesDir() | 外部データ | ◯ | 不要 | 消える | Android 4.4以降パーミッション不要。現在の外部保存の基本。 |
| Context.getExternalCacheDir() | 外部キャッシュ | ◯ | 不要 | 消える | 外部領域の一時保存用。 |
| Environment.getExternalStorageDirectory() | 外部公開 | × | – | 消えない | 【API 29で非推奨】直接アクセス不可。現在はSAFやMediaStoreを推奨。 |
| Environment.getExternalStoragePublicDirectory() | 外部公開共有 | × | – | 消えない | 【API 29で非推奨】画像や動画の共有はMediaStoreを利用。 |
Scoped Storage時代の保存領域の使い分け
一時的なデータは CacheDir に、ユーザーのセーブデータなど消されては困るアプリ固有のデータは ExternalFilesDir(またはUnityの PersistentDataPath)に保存するのが現在のセオリーです。
他のアプリとファイルを共有したい場合(画像やファイルの端末内へのエクスポートなど)は、パスを直接指定する旧来の手法ではなく、MediaStore API や Storage Access Framework (SAF) を利用してURI経由でアクセスするように設計をアップデートしましょう。

