许多好的问题,让我们深入探讨。:)
你如何使用它?
这是与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()
,然后使用ParcelFileDescriptor.getFd()
或detachFd()
获取传统的POSIX文件描述符整数。
您如何检查是否可以访问文件/文件夹?
默认情况下,通过Storage Access Framework意图返回的Uris 在重新启动后不会保留。该平台“提供”了保留权限的能力,但是如果需要,您仍然需要“获取”该权限。在上面的示例中,您将调用:
getContentResolver().takePersistableUriPermission(treeUri,
Intent.FLAG_GRANT_READ_URI_PERMISSION |
Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
您始终可以确定哪些持久授权可以使您的应用通过ContentResolver.getPersistedUriPermissions()
API进行访问。如果您不再需要访问保留的Uri,则可以使用释放它ContentResolver.releasePersistableUriPermission()
。
可以在KitKat上使用吗?
不,我们不能向该平台的旧版本追溯添加新功能。
我可以查看哪些应用有权访问文件/文件夹吗?
当前没有显示此内容的UI,但是您可以在输出的“授予的Uri权限”部分中找到详细信息adb shell dumpsys activity providers
。
如果在同一设备上为多个用户安装了一个应用程序,会发生什么?
就像所有其他多用户平台功能一样,Uri权限授予是按用户隔离的。也就是说,在两个不同用户下运行的同一应用程序没有重叠或共享的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?
是的,主要的共享存储设备应该出现在选择器中,即使在模拟器上也是如此。如果您的应用仅使用Storage Access Framework来访问共享存储,则根本不再需要这些READ/WRITE_EXTERNAL_STORAGE
权限,可以删除它们或使用该android:maxSdkVersion
功能仅在较旧的平台版本上请求它们。
当用户用另一张SD卡替换时,会发生什么?
当涉及到物理介质时,基础介质的UUID(例如FAT序列号)总是被刻录到返回的Uri中。即使用户在多个插槽之间交换媒体,系统也会使用它将您连接到用户最初选择的媒体。
如果用户交换第二张卡,则需要提示您获得对新卡的访问权限。由于系统会根据每个UUID记住授权,因此如果用户稍后重新插入原始卡,您将继续拥有以前授予原始卡的访问权限。
http://en.wikipedia.org/wiki/Volume_serial_number