Storage Access Framework:その概要、動作方法、Androidでのファイルアクセス

著者: IT Sectr 公開日: 2026-07-10 読了時間: 6 分

Storage Access Frameworkは、システム選択ダイアログを通じてファイルやドキュメントに安全にアクセスするためのAndroidフレームワークです。ストレージ読み取りの広範な権限を要求する代わりに、アプリはユーザーが選択したファイルへのURIリンクを受け取ります。Android Developers(2026)によると、SAFはDocumentProviderを介してローカルストレージ、クラウドサービスのGoogle Drive、Dropboxをサポートしています。このフレームワークはAndroid 4.4で導入され、Android 10以降ドキュメントを扱う標準となりました。

主要ポイント

  • SAFは、広範な権限なしでシステムダイアログを通じてファイルを選択するためのAndroidフレームワークです。
  • URIリンクが直接のファイルパスを置き換えます:アプリはcontent URIを介してファイルを操作します。
  • Persistent permissionsにより、アプリ再起動後もファイルへのアクセスを維持できます。
  • DocumentProviderは、クラウドおよびカスタムストレージへのアクセスをSAFに拡張します。
  • Android 10は、アプリのサンドボックス外のファイルにアクセスするためにSAFを必須としました。

Storage Access Frameworkとは?

Storage Access Frameworkは、システムダイアログを通じてドキュメントを選択および作成するための統一インターフェースを提供するAndroid SDKの一部です。SAFはファイルの物理的な場所を抽象化します:アプリはファイルがローカルディスク、Google Drive、Dropboxのどこから読み取られているかを認識しません。

SAFアーキテクチャには3つのコンポーネントがあります:リクエストを開始するクライアントアプリ、標準的なファイル選択ダイアログであるシステムピッカー、特定のストレージのファイルへのアクセスを実装するコンテンツプロバイダであるDocumentProviderです。ユーザーはデータソースに関係なく統一されたインターフェースを表示します。

SAFはAndroid 4.4(API 19)から利用可能です。当初はドキュメントのみをサポートしていましたが、Android 5.0でACTION_OPEN_DOCUMENT_TREEによるディレクトリのサポートが追加されました。Android 10以降、SAFはアプリ固有ストレージ外のファイルにアクセスする推奨方法となりました。

SAFの仕組み:システムピッカーとURI

SAFは、ACTION_OPEN_DOCUMENTアクションを持つIntentを介してシステムファイル選択ダイアログを起動します。ユーザーは利用可能なソース(内部ストレージ、Google Drive、Dropbox、その他登録されたプロバイダ)のリストを表示します。ファイル選択後、システムは一時的なアクセス権を持つcontent URIを返します

content URIの形式はcontent://com.android.externalstorage.documents/document/primary/Download/file.pdfです。file:// URIとは異なり、content URIは実際のファイルパスを公開せず、DocumentProviderを介して動作します。アプリは取得したURIを使用してContentResolver.openInputStreamを介してファイルを読み取ります。

システムピッカーは自動的にMIMEタイプによるファイルの検索、並べ替え、フィルタリングをサポートします。開発者はIntent.putExtra(Intent.EXTRA_MIME_TYPES, arrayOf("application/pdf", "image/*"))を介して必要なタイプを指定し、ピッカーは関連するファイルのみを表示します。

URIアクセスのライフサイクル

デフォルトでは、URIはアプリの再起動またはデバイスの再起動まで有効です。長期アクセスのために、アプリはtakePersistableUriPermissionを要求します。これにより、ダイアログで再選択することなく、後続の起動でファイルを読み取ることができます。

ACTION_OPEN_DOCUMENTとACTION_CREATE_DOCUMENT

SAFは、ファイルを操作するための3つの主要なアクション(開く、作成する、フォルダツリーを選択する)を提供します。ACTION_OPEN_DOCUMENTは既存のファイルを選択するためにシステムピッカーを開きます。ACTION_CREATE_DOCUMENTは新しいファイルを作成します。ユーザーはダイアログに名前を入力し、アプリは書き込み用のURIを受け取ります。

ACTION_OPEN_DOCUMENT_TREEは、ディレクトリ全体を選択し、その中のすべてのファイルへのアクセスを取得できます。これはファイルマネージャー、バックアップアプリ、同期ツールで使用されます。アプリはディレクトリURIを受け取り、DocumentFileを介してコンテンツを再帰的に列挙できます。

アクション目的フラグ
ACTION_OPEN_DOCUMENT既存のファイルを選択READ_FLAG
ACTION_CREATE_DOCUMENT新しいファイルを作成WRITE_FLAG
ACTION_OPEN_DOCUMENT_TREEディレクトリを選択READ + WRITE

各アクションに対して、MIMEタイプはEXTRA_MIME_TYPESを介して指定されます。複数のタイプ("application/pdf"、"image/*"、"text/plain")を指定できます。タイプが指定されていない場合、ピッカーはすべてのファイルを表示します。

Persistent URI permissions

Persistent URI permissionsは、現在のセッション終了後もファイルへのアクセスを維持できるSAFのメカニズムです。このフラグがない場合、URIはアプリの再起動までのみ有効です。アプリはREADフラグとWRITEフラグとともにFLAG_GRANT_PERSISTABLE_URI_PERMISSIONフラグを要求します。

権限を保存するには、ContentResolver.takePersistableUriPermissionメソッドを使用します。システムはURIを特別なレジストリに保存し、次回のアプリ起動時にアクセスを復元します。アプリがURIへの永続的アクセスを持っているかどうかを確認するには、ContentResolver.persistedUriPermissionsを使用します。

ユーザーは設定→アプリ→権限から保存された権限を取り消すことができます。アプリはファイルへのアクセスが予期せず失われたシナリオを処理する必要があります。作業を開始する前にContentResolver.openInputStreamを介してアクセスを確認し、SecurityExceptionを適切に処理することをお勧めします。

コード例:SAFによるファイル選択

SAFは標準のIntentを介して起動されます。コードは最小限です:ACTION_OPEN_DOCUMENTでIntentを作成し、MIMEタイプを指定し、ActivityResultContracts.StartActivityForResultを介して起動します。ファイル選択後、callbackはdata.dataでURIを受け取り、それを読み取りに使用します。

kotlin
val pickFile = registerForActivityResult(
    ActivityResultContracts.StartActivityForResult()
) { result ->
    result.data?.data?.let { uri ->
        val inputStream = contentResolver?.openInputStream(uri)
        // read from inputStream
    }
}

val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
    addCategory(Intent.CATEGORY_OPENABLE)
    setType("application/pdf")
    putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
}
pickFile.launch(intent)

ACTION_CREATE_DOCUMENTによるファイル作成

新しいファイルに書き込むには、ACTION_CREATE_DOCUMENTを使用します。IntentはMIMEタイプとEXTRA_TITLEを介したファイル名を受け入れます。フォルダを選択して確認した後、ユーザーはURIを返し、アプリはContentResolver.openOutputStreamを介してデータを書き込みます。システムは自動的に選択された場所にファイルを作成します。

SAF vs READ_EXTERNAL_STORAGE

SAFは、従来のREAD_EXTERNAL_STORAGEとはセキュリティに対する根本的に異なるアプローチで異なります。一度にストレージ全体へのアクセスを要求する代わりに、SAFは特定のファイルへのアクセスのみを要求します。これにより攻撃対象領域が最小限に抑えられ、ユーザーの信頼が高まります。

READ_EXTERNAL_STORAGEは、他のアプリの写真やドキュメントを含む、デバイス上のすべてのファイルへのアクセスを許可します。Android 10+では、このアプローチは制限されています。対照的に、SAFはユーザーが選択したファイルへのアクセスのみを提供し、ファイルごとに明示的な確認を必要とします。バッチメディア操作にはMediaStoreを、個別のドキュメントにはSAFを使用してください。

SAFの主な欠点は、各ファイルを個別に選択する必要があることです。一括操作(バックアップ、フォルダ同期)には、ACTION_OPEN_DOCUMENT_TREEを使用します。これにより、選択したディレクトリ内のすべてのファイルへのアクセスが許可されます。解決策はシナリオによって異なります:SAFはユーザー選択に最適で、MediaStoreはプログラムによるメディアアクセスに最適です。

よくある質問

AndroidのStorage Access Frameworkとは?

Storage Access Frameworkは、システム選択ダイアログを通じて安全なファイルアクセスを提供するAndroidフレームワークです。アプリはストレージ読み取りの広範な権限を要求せずに、選択されたファイルのcontent URIを受け取ります。

SAFでファイルを開くには?

ACTION_OPEN_DOCUMENTでIntentを作成し、setTypeでMIMEタイプを指定し、ActivityResultContractsを介して起動します。コールバックでdata.dataからURIを取得し、ContentResolver.openInputStreamを介して読み取ります。

Persistent URI permissionsとは?

Persistent URI permissionsは、アプリ再起動後もURIへのアクセスを維持するメカニズムです。FLAG_GRANT_PERSISTABLE_URI_PERMISSIONフラグとtakePersistableUriPermissionメソッドを介して要求されます。

SAFはどのMIMEタイプをサポートしていますか?

SAFは任意のMIMEタイプ(application/pdfimage/*text/plainapplication/zipなど)をサポートしています。タイプはEXTRA_MIME_TYPES配列を使用してIntent.putExtraを介して指定されます。

SAFとMediaStoreの違いは?

SAFは、ユーザーがシステムダイアログを通じて個別のファイルを選択するために設計されています。MediaStoreは、ユーザーの操作なしでメディアデータベースを介してデバイス上のすべてのメディアファイルへのプログラムによるアクセスを提供します。

まとめ

  • Storage Access Frameworkは、広範な権限なしでシステムピッカーを介して安全なファイルアクセスを提供するAndroidフレームワークです。
  • Content URIがファイルパスを置き換えます:アプリは直接のfile://リンクではなく、DocumentProviderを介してファイルを操作します。
  • ACTION_OPEN_DOCUMENTは既存のファイルを開き、ACTION_CREATE_DOCUMENTは新しいファイルを作成し、ACTION_OPEN_DOCUMENT_TREEはフォルダを選択します。
  • Persistent permissionsは、takePersistableUriPermissionを介してアプリ再起動後もURIへのアクセスを維持します。
  • Android 10は、アプリ固有ストレージ外のファイルアクセスにSAFを必須とし、READ_EXTERNAL_STORAGEを制限しました。
  • DocumentProviderは、クラウドおよびカスタムストレージとの統合のためにSAFを拡張します。
  • 選択はシナリオによって異なります:SAFはユーザー選択用、MediaStoreはプログラムによるメディアアクセス用です。

ターンキー方式のモバイルアプリケーションを開発します

IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

プロジェクトについて相談

こちらもお読みください