ストレージ アクセス フレームワークを使用してファイルを開く

Android 4.4(API レベル 19)は、ストレージ アクセス フレームワーク(SAF)を採用しています。SAF を使用すると、ユーザーは任意のドキュメント ストレージ プロバイダからドキュメントや画像などのファイルを参照して開くことができます。標準の使いやすい UI により、ユーザーはアプリとプロバイダの間で一貫した方法でファイルを閲覧し、最近使用したファイルにアクセスできます。

サービスをカプセル化する DocumentsProvider を実装することで、クラウドやローカル ストレージ サービスをエコシステムに参加させることができます。プロバイダのドキュメントにアクセスする必要があるクライアント アプリは、数行のコードで SAF と統合できます。

SAF には次の項目が含まれます。

  • ドキュメント プロバイダ: Google ドライブなどのストレージ サービスが、管理対象のファイルを公開できるようにするコンテンツ プロバイダ。ドキュメント プロバイダは DocumentsProvider クラスのサブクラスとして実装されます。document-provider スキーマは従来のファイル階層に基づくものですが、ドキュメント プロバイダが物理的にどのようにデータを格納するかはその設定次第です。Android プラットフォームには、ダウンロード、画像、動画などの組み込みのドキュメント プロバイダがいくつか用意されています。
  • クライアント アプリ: ACTION_CREATE_DOCUMENTACTION_OPEN_DOCUMENTACTION_OPEN_DOCUMENT_TREE のインテントのアクションを呼び出し、ドキュメント プロバイダから返されたファイルを受け取るカスタムアプリ。
  • 選択ツール: ユーザーがクライアント アプリの検索条件を満たすすべてのドキュメント プロバイダのドキュメントにアクセスできるようにするシステム UI。

SAF には次の機能があります。

  • ユーザーは 1 つのアプリだけでなく、すべてのドキュメント プロバイダのコンテンツを参照できます。
  • アプリは、ドキュメント プロバイダが所有するドキュメントに長期間永続的にアクセスできるようにします。このアクセス権により、ユーザーはプロバイダでファイルを追加、編集、保存、削除できます。
  • 複数のユーザー アカウントと USB ストレージ プロバイダなどの一時的なルートをサポートします。一時的なルートはドライブを接続した場合にのみ表示されます。

概要

SAF は、DocumentsProvider クラスのサブクラスであるコンテンツ プロバイダを中心に展開します。ドキュメント プロバイダ内では、データは従来のファイル階層として構造化されています。

データモデル

図 1. ドキュメント プロバイダのデータモデル。ルートが単一ドキュメントを指し、そこからツリーのファンアウトが開始されます。

次の点にご注意ください。

  • 各ドキュメント プロバイダは 1 つ以上のルートを報告します。ルートは、ドキュメントのツリーを調査する際の出発点です。各ルートは一意の COLUMN_ROOT_ID を持ち、そのルートの下のコンテンツを表すドキュメント(ディレクトリ)を参照します。ルートは、複数のアカウント、一時的な USB ストレージ デバイス、ユーザーのログインとログアウトなどのユースケースをサポートするために、動的設計となっています。
  • 各ルートの下にはドキュメントが 1 つだけあります。そのドキュメントは 1~N 個のドキュメントを指し、さらにそれぞれのドキュメントも 1~N 個のドキュメントを指すことができます。
  • 各ストレージ バックエンドは、一意の COLUMN_DOCUMENT_ID を使って参照することにより、個々のファイルやディレクトリを表示します。ドキュメント ID は一意であり、デバイスの再起動後も永続的な URI を付与するために使用されるため、一度発行すると変更されることはありません。
  • ドキュメントは、開くことができるファイル、特定の MIME タイプのファイル、または追加のドキュメントを含むディレクトリ(MIME_TYPE_DIR MIME タイプのドキュメント)のいずれかです。
  • 各ドキュメントはさまざまな機能を持つことができ、COLUMN_FLAGS を使って記述します。たとえば、FLAG_SUPPORTS_WRITEFLAG_SUPPORTS_DELETEFLAG_SUPPORTS_THUMBNAIL といった機能です。同じ COLUMN_DOCUMENT_ID を複数のディレクトリに含めることができます。

制御フロー

ドキュメント プロバイダのデータモデルは、従来のファイル階層に基づいています。ただし、DocumentsProvider API を使用してアクセスできる限り、任意の方法でデータを物理的に保存できます。たとえば、データにタグベースのクラウド ストレージを使用できます。

図 2 は、写真アプリが格納されたデータに SAF を使ってアクセスする方法を表しています。

アプリ

図 2. ストレージ アクセス フレームワークのフローです。

次の点にご注意ください。

  • SAF では、プロバイダとクライアントは直接やり取りできません。クライアントが、ファイルを操作する権限(ファイルの読み取り、編集、作成、削除)をリクエストします。
  • アプリ(この例では写真アプリ)がインテント ACTION_OPEN_DOCUMENT または ACTION_CREATE_DOCUMENT を起動すると、インタラクションが開始されます。インテントには、「画像」MIME タイプの開くことができるすべてのファイルを取得するなど、条件をさらに絞り込むためのフィルタを含めることができます。
  • インテントが起動すると、システムの選択ツールが登録済みの各プロバイダに移動し、一致するコンテンツのルートをユーザーに表示します。
  • 選択ツールは、基盤となるドキュメント プロバイダが大きく異なる場合でも、ドキュメントにアクセスするための標準インターフェースを提供します。たとえば、図 2 には、Google ドライブ プロバイダ、USB プロバイダ、クラウド プロバイダが示されています。

図 3 では、ユーザーがイメージの検索時に開いた選択ツールから [ダウンロード] フォルダを選択しています。選択ツールには、クライアント アプリで使用できるすべてのルートも表示されます。

システムの選択ツールでのフォルダ選択のスクリーンショット

図 3. 検索場所として [ダウンロード] フォルダが選択されている選択ツール。

ユーザーがダウンロード フォルダを選択すると、画像が表示されます。図 4 は、このプロセスの結果を表しています。これで、ユーザーはプロバイダとクライアント アプリがサポートする方法で画像を操作できるようになります。

ダウンロード フォルダのスクリーンショット

図 4. システムの選択ツールに表示される [ダウンロード] フォルダに保存されている画像。

クライアント アプリを作成する

Android 4.3 以前では、別のアプリからファイルを取得する場合、アプリは ACTION_PICKACTION_GET_CONTENT などのインテントを呼び出す必要があります。次に、ユーザーはファイルを選択するアプリを 1 つ選択します。選択されたアプリは、ユーザーが使用可能なファイルを参照して選択できるユーザー インターフェースを提供する必要があります。

Android 4.4(API レベル 19)以降では、ACTION_OPEN_DOCUMENT インテントを使用することもできます。このインテントは、システム制御の選択ツール UI を表示し、ユーザーは他のアプリで利用できるすべてのファイルを参照できます。ユーザーは、この 1 つの UI から、サポートされるすべてのアプリのファイルを選択できます。

Android 5.0(API レベル 21)以降では、ACTION_OPEN_DOCUMENT_TREE インテントを使用して、アクセスするクライアント アプリのディレクトリをユーザーが選択することもできます。

注: ACTION_OPEN_DOCUMENTACTION_GET_CONTENT に代わるものではありません。どちらを使用するかは、アプリのニーズによって異なります。

  • アプリでデータの読み取りまたはインポートを行う場合は、ACTION_GET_CONTENT を使用します。この方法を使用すると、アプリは、画像ファイルなどのデータのコピーをインポートします。
  • ACTION_OPEN_DOCUMENT は、ドキュメント プロバイダが所有するドキュメントにアプリが長期的にアクセスできる場合に使用します。たとえば、ドキュメント プロバイダに保存されている画像を編集できる写真編集アプリがあります。

システムの選択ツール UI を使用したファイルやディレクトリのブラウジングをサポートする方法の詳細については、ドキュメントやその他のファイルへのアクセスに関するガイドをご覧ください。

参考情報

ドキュメント プロバイダについて詳しくは、以下のリソースをご利用ください。

サンプル

動画