良い質問がたくさんあるので、掘り下げてみましょう。:)
どんなふうに使うの?
次に、KitKatのストレージアクセスフレームワークを操作するための優れたチュートリアルを示します。
https://developer.android.com/guide/topics/providers/document-provider.html#client
Lollipopの新しいAPIの操作は非常に似ています。ユーザーにディレクトリツリーを選択するように促すには、次のようなインテントを起動します。
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
startActivityForResult(intent, 42);
次に、onActivityResult()で、ユーザーが選択したUriを新しいDocumentFileヘルパークラスに渡すことができます。次に、選択したディレクトリ内のファイルを一覧表示し、新しいファイルを作成する簡単な例を示します。
public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
if (resultCode == RESULT_OK) {
Uri treeUri = resultData.getData();
DocumentFile pickedDir = DocumentFile.fromTreeUri(this, treeUri);
// List all existing files inside picked directory
for (DocumentFile file : pickedDir.listFiles()) {
Log.d(TAG, "Found file " + file.getName() + " with size " + file.length());
}
// Create a new file and write into it
DocumentFile newFile = pickedDir.createFile("text/plain", "My Novel");
OutputStream out = getContentResolver().openOutputStream(newFile.getUri());
out.write("A long time ago...".getBytes());
out.close();
}
}
によって返されるUriは、DocumentFile.getUri()
さまざまなプラットフォームAPIで使用できるほど柔軟です。たとえば、を使用Intent.setData()
して共有できますIntent.FLAG_GRANT_READ_URI_PERMISSION
。
ネイティブコードからそのUriにアクセスする場合は、またはをContentResolver.openFileDescriptor()
使用して、従来のPOSIXファイル記述子整数を取得できます。ParcelFileDescriptor.getFd()
detachFd()
ファイル/フォルダにアクセスできるかどうかをどのように確認しますか?
デフォルトでは、Storage Access Frameworksインテントを通じて返されたUrisは、再起動後は保持されません。プラットフォームは、パーミッションを永続化する機能を「提供」しますが、必要な場合はパーミッションを「取得」する必要があります。上記の例では、次のように呼び出します。
getContentResolver().takePersistableUriPermission(treeUri,
Intent.FLAG_GRANT_READ_URI_PERMISSION |
Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
ContentResolver.getPersistedUriPermissions()
API を介してアプリがアクセスできる永続的な付与をいつでも把握できます。永続化されたUriにアクセスする必要がなくなった場合は、を使用して解放できますContentResolver.releasePersistableUriPermission()
。
これはKitKatで利用できますか?
いいえ、古いバージョンのプラットフォームに新しい機能をさかのぼって追加することはできません。
ファイル/フォルダにアクセスできるアプリを確認できますか?
現在、これを示すUIはありませんが、adb shell dumpsys activity providers
出力の「Granted Uri Permissions」セクションで詳細を確認できます。
同じデバイスに複数のユーザー向けにアプリをインストールするとどうなりますか?
Uri権限の付与は、他のすべてのマルチユーザープラットフォーム機能と同様に、ユーザーごとに分離されます。つまり、2人の異なるユーザーのもとで実行されている同じアプリには、重複したり共有されたUriパーミッションはありません。
権限を取り消すことはできますか?
バッキングDocumentProviderは、クラウドベースのドキュメントが削除されたときなど、いつでも権限を取り消すことができます。これらの取り消されたアクセス許可を検出する最も一般的な方法は、ContentResolver.getPersistedUriPermissions()
上記の説明から消えたときです。
権限に関与しているいずれかのアプリのアプリデータがクリアされると、アクセス許可も取り消されます。
選択したフォルダに対して再帰的にアクセス許可を要求しますか?
ACTION_OPEN_DOCUMENT_TREE
はい、このインテントにより、既存のファイルと新しく作成されたファイルとディレクトリの両方に再帰的にアクセスできます。
これは複数選択を許可しますか?
はい、複数選択はKitKatからサポートされておりEXTRA_ALLOW_MULTIPLE
、ACTION_OPEN_DOCUMENT
インテントを開始するときに設定することで許可できます。Intent.setType()
またはEXTRA_MIME_TYPES
を使用して、選択できるファイルのタイプを絞り込むことができます。
http://developer.android.com/reference/android/content/Intent.html#ACTION_OPEN_DOCUMENT
エミュレータで新しいAPIを試す方法はありますか?
はい、プライマリ共有ストレージデバイスは、エミュレータ上でもピッカーに表示されます。アプリが共有ストレージへのアクセスにストレージアクセスフレームワークのみを使用している場合は、アクセスREAD/WRITE_EXTERNAL_STORAGE
許可はまったく必要なく、削除したり、android:maxSdkVersion
機能を使用して古いプラットフォームバージョンでのみ要求したりできます。
ユーザーがSDカードを別のカードに交換するとどうなりますか?
物理メディアが関係する場合、元のメディアのUUID(FATシリアル番号など)は常に返されたUriに書き込まれます。システムはこれを使用して、ユーザーが複数のスロット間でメディアを交換しても、ユーザーが最初に選択したメディアに接続します。
ユーザーが2枚目のカードを入れ替えた場合は、新しいカードにアクセスするように求めるメッセージが表示されます。システムは許可をUUIDごとに記憶するため、ユーザーが後でカードを再挿入した場合でも、以前に許可されていた元のカードへのアクセスが継続されます。
http://en.wikipedia.org/wiki/Volume_serial_number