Android は、不変の POSIX アクセス許可クラスとモードを備えた大文字と小文字を区別しないファイル システムとして定義されている従来のストレージを備えたデバイスをサポートします。従来のストレージの概念には、エミュレートされたポータブル ストレージが含まれます。ポータブル ストレージは、システムに採用されていないため、フォーマットおよび暗号化されていない、または特定のデバイスに関連付けられていない外部ストレージとして定義されます。従来の外部ストレージは保存されたデータに対して最小限の保護を提供するため、システム コードは機密データを外部ストレージに保存すべきではありません。具体的には、構成ファイルとログ ファイルは、効果的に保護できる内部ストレージにのみ保存する必要があります。
マルチユーザー外部ストレージ
Android 4.2 以降、デバイスは複数のユーザーをサポートできるようになり、外部ストレージは次の制約を満たす必要があります。
- 各ユーザーは独自の分離されたプライマリ外部ストレージを持っている必要があり、他のユーザーのプライマリ外部ストレージにアクセスすることはできません。
-
/sdcard
パスは、プロセスを実行しているユーザーに基づいて、正しいユーザー固有のプライマリ外部ストレージに解決される必要があります。 -
Android/obb
ディレクトリ内の大きな OBB ファイルのストレージは、最適化として複数のユーザー間で共有される場合があります。 - セカンダリ外部ストレージは、合成されたアクセス許可で許可されているパッケージ固有のディレクトリを除き、アプリから書き込み可能であってはなりません。
この機能のデフォルトのプラットフォーム実装では、Linux カーネル名前空間を利用して、Zygote フォークされたプロセスごとに分離されたマウント テーブルを作成し、バインド マウントを使用して、そのプライベート名前空間に適切なユーザー固有のプライマリ外部ストレージを提供します。
起動時に、システムは単一のエミュレートされた外部ストレージ FUSE デーモンをEMULATED_STORAGE_SOURCE
にマウントします。これはアプリからは隠されています。 Zygote がフォークした後、アプリの外部ストレージ パスが正しく解決されるように、FUSE デーモンの下から適切なユーザー固有のサブディレクトリをEMULATED_STORAGE_TARGET
にバインド マウントします。アプリには他のユーザーのストレージにアクセスできるマウント ポイントがないため、アプリを起動したユーザーのストレージにのみアクセスできます。
この実装では、共有サブツリー カーネル機能も使用して、マウント イベントをデフォルトのルート名前空間からアプリ名前空間に伝達します。これにより、ASEC コンテナーや OBB マウントなどの機能が引き続き正しく動作します。これは、rootfs を共有としてマウントし、各 Zygote 名前空間が作成された後にスレーブとして再マウントすることによって行われます。
複数の外部ストレージデバイス
Android 4.4 以降、複数の外部ストレージ デバイスがContext.getExternalFilesDirs()
、 Context.getExternalCacheDirs()
、およびContext.getObbDirs()
を通じて開発者に表示されます。
WRITE_EXTERNAL_STORAGE
権限は、デバイス上のプライマリ外部ストレージへの書き込みアクセスのみを許可する必要があります。アプリには、合成されたアクセス許可で許可されているパッケージ固有のディレクトリを除き、セカンダリ外部ストレージ デバイスへの書き込みを許可してはなりません。この方法で書き込みを制限すると、アプリケーションのアンインストール時にシステムがファイルをクリーンアップできるようになります。
USBメディアのサポート
Android 6.0 は、USB フラッシュ ドライブなど、短時間しかデバイスに接続されないポータブル ストレージ デバイスをサポートしています。ユーザーが新しいポータブル デバイスを挿入すると、プラットフォームはそのデバイスのコンテンツをコピーまたは管理できるようにする通知を表示します。
Android 6.0 では、採用されていないデバイスはポータブルであるとみなされます。ポータブル ストレージは短時間しか接続されないため、プラットフォームはメディア スキャンなどの負荷の高い操作を回避します。サードパーティ アプリは、ポータブル ストレージ上のファイルを操作するためにストレージ アクセス フレームワークを経由する必要があります。直接アクセスは、プライバシーとセキュリティ上の理由から明示的にブロックされます。