如何使用 File API 将文件保存到 Android 11 中用户选择的位置?

Posted

技术标签:

【中文标题】如何使用 File API 将文件保存到 Android 11 中用户选择的位置?【英文标题】:How to save files with File API to a user-selected location in Android 11? 【发布时间】:2021-03-26 23:15:13 【问题描述】:

我对@9​​87654322@ 和Storage Access Framework (SAF) 以及所有限制感到非常困惑。我需要使用File API,而不是Uri,所以: android API 级别 /storage/emulated/0 有效(使用 requestLegacyExternalStorage)。 Android API 级别 = 30 (Android 11) 保存到 /storage/emulated/0 不起作用 (IOException: Operation not permitted)。

Environment.getExternalStorageDirectory() 已弃用。好的,所以getExternalFilesDirs() 在 Android 11 中:

ctx.getExternalFilesDirs(): /storage/emulated/0/Android/data/<package name>/files //External storage in internal memory
ctx.getExternalFilesDirs(): /storage/16F4-3A1C/Android/data/<package name>/files //SDcard

有效,因为它是应用程序的存储空间。但是用户希望在外部存储/storage/emulated/0/MySpecificFolder 或sdcard /storage/16F4-3A1C/MySpecificFolder 的根目录中拥有应用程序的文件夹。我正在使用File API,它应该可以再次使用(与 Android10 不同)。

如何写入用户特定目录,例如/storage/emulated/0/MySpecificFolder

我尝试使用:

Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
startActivityForResult(intent, PICK_FOLDER);

打开文件管理器。用户创建新目录(因为 root 不能使用):/storage/emulated/0/MySpecificFolder。接下来我尝试通过以下方式创建一个新文件:

File nomedia = new File("/storage/emulated/0/MySpecificFolder", ".nomedia");
if (!nomedia.exists()) 
    nomedia.createNewFile();

但它不起作用IOException: Operation not permitted。可能是写权限有问题。

这条线有效:

DocumentFile newFile = pickedDir.createFile("text/plain", "My Novel");

适用于Uri为什么不能使用File API 当我调用使用UricreateFile() 时,它可以工作,但是当我调用使用File APIcreateNewFile() 时,它不起作用。所以用户可以选择自己的目录,但只有当应用程序使用Uri

如何从 SAF 获取 path(供以后与 File API 一起使用),而不仅仅是 Uri

// Get Uri from Storage Access Framework.
Uri treeUri = data.getData();
DocumentFile pickedDir = DocumentFile.fromTreeUri(this, treeUri);
Log.i(TAG, "Tree uri: "+treeUri.getPath());  //returns /tree/primary:My
Log.i(TAG, "Picked dir: "+pickedDir.getUri().getPath()); //returns /tree/primary:My/document/primary:My

我需要使用 File API,因为 app.创建需要在一起的视频+照片+数据文件。

问题:用户是否可以选择自己的路径+创建文件夹(可能通过SAF)并将用户新创建的文件夹的File(文件描述符)返回给应用程序?

【问题讨论】:

"我需要使用 File API,因为 app. 创建需要放在一起的视频+照片+数据文件" -- 在 getFilesDir() 中创建这些文件,然后将它们复制到用户选择的文档树.或者,选择让您使用流而不是文件的 SDK。 “用户是否可以选择自己的路径 + 创建文件夹(可能通过 SAF)并将用户新创建的文件夹的文件(文件描述符)返回给应用程序?” -- 不是File。您可以通过ContentResolver 获取Uri 的文件描述符。 也许这就是你需要的:github.com/anggrayudi/SimpleStorage 【参考方案1】:

在 Android 11 上,每个应用都可以使用旧的 File 类写入外部存储上的公共目录。

不要让用户选择位置,因为您需要使用 SAF 进行进一步操作。

如果您想让用户在文档、下载、警报、DCIM、图片等之间进行选择,请使用带有警报生成器的小列表。

【讨论】:

以上是关于如何使用 File API 将文件保存到 Android 11 中用户选择的位置?的主要内容,如果未能解决你的问题,请参考以下文章

Laravel:如何将图像或文件发送到 API

将音频流保存到 mp3 文件 (iOS)

如何将 fastify swagger api 描述保存到本地文件

如何将字典列表保存到文件中?

用相机意图拍摄照片并将其保存到文件中

如何将multer保存在内存中的文件上传到另一个API