从URI创建可写DocumentFile [英] Creating a writeable DocumentFile from URI

查看:895
本文介绍了从URI创建可写DocumentFile的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用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

和上面用于toPathUri是:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆