从URI创建可写DocumentFile [英] Creating a writeable DocumentFile from URI
问题描述
我正在尝试使用DocumentFile
使基于File
的文档系统适应某些环境,以便允许对外部存储进行API> = 29的读/写访问.
I'm trying to adapt a File
-based document system to something using DocumentFile
in order to allow external storage read/write access on API >= 29.
让用户使用Intent.ACTION_OPEN_DOCUMENT_TREE
选择SD卡根目录,然后按预期方式返回Uri
,然后可以使用以下命令进行处理:
I get the user to select the SD card root using Intent.ACTION_OPEN_DOCUMENT_TREE
, and I get back a Uri
as expected, which I can then handle using:
getContentResolver().takePersistableUriPermission(resultData.getData(),
Intent.FLAG_GRANT_READ_URI_PERMISSION
| Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
我可以成功浏览外部存储内容直至所选根目录.一切都很好.
I can browse successfully through the external storage contents up to the selected root. All good.
但是我需要做的是在选定的(子)文件夹中写入一个任意文件,这就是我遇到问题的地方.
But what I need to be able to do is write an arbitrary file in the chosen (sub)folder, and that's where I'm running into problems.
DocumentFile file = DocumentFile.fromSingleUri(mContext, Uri.parse(toPath));
Uri uri = file.getUri();
FileOutputStream output = mContext.getContentResolver().openOutputStream(uri);
除了openOutputStream()
通话,我得到了:
java.io.FileNotFoundException: Failed to open for writing: java.io.FileNotFoundException: open failed: EISDIR (Is a directory)
这让我有些困惑,但是找不到文件"部分建议我可能需要先创建空白的输出文件,所以我尝试这样做,例如:
That's slightly confusing to me, but the "file not found" part suggests I might need to create the blank output file first, so I try that, like:
DocumentFile file = DocumentFile.fromSingleUri(mContext, Uri.parse(toPath));
Uri uri = file.getUri();
if (file == null) {
return false;
}
if (file.exists()) {
file.delete();
}
DocumentFile.fromTreeUri(mContext, Uri.parse(getParentPath(toPath))).createFile("", uri.getLastPathSegment());
FileOutputStream output = mContext.getContentResolver().openOutputStream(uri);
我得到一个java.io.IOException
:
java.lang.IllegalStateException: Failed to touch /mnt/media_rw/0B07-1910/Testing.tmp: java.io.IOException: Read-only file system
at android.os.Parcel.createException(Parcel.java:2079)
at android.os.Parcel.readException(Parcel.java:2039)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:188)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:140)
at android.content.ContentProviderProxy.call(ContentProviderNative.java:658)
at android.content.ContentResolver.call(ContentResolver.java:2042)
at android.provider.DocumentsContract.createDocument(DocumentsContract.java:1327)
at androidx.documentfile.provider.TreeDocumentFile.createFile(TreeDocumentFile.java:53)
at androidx.documentfile.provider.TreeDocumentFile.createFile(TreeDocumentFile.java:45)
这对我没有意义,因为树应该是可写的.
Which doesn't make sense to me, since the tree should be writeable.
对于它的价值,我从Intent.ACTION_OPEN_DOCUMENT_TREE
回来的Uri
看起来像这样:
For what it's worth, the Uri
I get back from Intent.ACTION_OPEN_DOCUMENT_TREE
looks like this:
content://com.android.externalstorage.documents/tree/0B07-1910%3A
有趣的是,当我使用Uri
使用documentFile = DocumentFile.fromTreeUri(context, uri)
创建要浏览的DocumentFile
对象时,documentFile.getURI().toString()
看起来像:
Interestingly, when I use that Uri
to create a DocumentFile
object to browse, using documentFile = DocumentFile.fromTreeUri(context, uri)
, then documentFile.getURI().toString()
looks like:
content://com.android.externalstorage.documents/tree/0B07-1910%3A/document/0B07-1910%3A
即,它的末尾附加了一些内容.
i.e., it's had something appended to the end of it.
然后,我进入应为可写文件夹的位置(例如下载"),然后尝试如上所述创建可写文件. 下载"文件夹获取Uri
:
Then, I descend into what should be a writeable folder (like "Download"), and try creating a writeable file as described above. The "Download" folder gets the Uri
:
content://com.android.externalstorage.documents/tree/0B07-1910%3A/document/0B07-1910%3ADownload
和上面用于toPath
的Uri
是:
content://com.android.externalstorage.documents/tree/0B07-1910%3A/document/0B07-1910%3ADownload/Testing.tmp
这会导致前面描述的尝试创建它的问题.
which leads to the problems described previously trying to create it.
我实际上还没有发现有关在Storage Access Framework限制下写入任意文件的任何体面信息.
I haven't actually found any decent information about writing an arbitrary file under Storage Access Framework restrictions.
我做错了什么?谢谢. :)
What am I doing wrong? Thanks. :)
推荐答案
Uri uri = uri obtained from ACTION_OPEN_DOCUMENT_TREE
String folderName = "questions.59189631";
DocumentFile documentDir = DocumentFile.fromTreeUri(context, uri);
DocumentFile folder = documentDir.createDirectory(folderName);
return folder.getUri();
将createFile()用于可写文件.
Use createFile() for a writable file.
这篇关于从URI创建可写DocumentFile的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!