android - 在 Android 11 上编写许多文件

标签 android storage-access-framework

设想
我正在尝试创建许多文件,作为用户的一项功能。例如,我可能会编写一个应用程序,为他们过去几周听的每首歌曲创建一个文件(例如,带有歌词的文本文件)。我不能让用户为我生成的每个文件选择目录和文件名,这需要几个小时。用户应该可以从其他应用程序访问这些文档。
解决方案(不是真的)
在 Android 11 中,Storage Access Framework 似乎不再有用。我注意到最初有 2 个有趣的选项:

  • 创建一个新文件(创建用户交互的启动 Activity 以仅保存一个文件),描述 here
  • 授予对目录内容的访问权限(允许读取访问权限,但不允许写入任何文档),描述 here .
  • 注:如果您以 Android 10 为目标并请求 WRITE_EXTERNAL_STORAGE,则已存在解决方案.不幸的是,此权限在 Android 11 上被拒绝。因此,我无法使用发布的解决方案 here .
  • 使用存储访问框架(特别是 ACTION_OPEN_DOCUMENT_TREE )访问目录以访问目录,但我无法将文件写入此目录。 (我得到 FileNotFoundException ,因为这不是普通路径,而是树路径。)

  • 判决
    我想在我的情况下,我需要走“管理存储设备上的所有文件”的路线,如 here 所述。这涉及使用 ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION 启动一个额外的 Activity .我宁愿不请求读取整个驱动器的权限或让用户进入设置应用程序以授予权限。写入文件不需要任何权限...
    您将如何处理为用户保存许多(非媒体)文件?

    最佳答案

    有 2 种方法,但首先,我将定义文件和目录名称,稍后将其保存在外部 (sdcard) 下载文件夹中

    val outputFilename = "my_file"
    val outputDirectory = "my_sub_directory" // The folder within the Downloads folder, because we use `DIRECTORY_DOWNLOADS`
    
    有效但已弃用的方法:
    虽然 Environment.getExternalStoragePublicDirectory已被弃用,它仍然适用于以 Android 11 为目标和运行的应用程序。
    file = File(Environment.getExternalStoragePublicDirectory(
        Environment.DIRECTORY_DOCUMENTS),
        "$outputDirectory/$outputFilename"
    )
    val outputStream = FileOutputStream(file)
    
    MediaStore 方式:
    或者,您可以使用 MediaStore 的 Files collection , 建议 Gaurav Mall here .我不知道 MediaStore files收藏...
    我在 kotlin 中重写了它并修改了它以在此处写入文件:
    val resolver = context.contentResolver
    val values = ContentValues()
    // save to a folder
    values.put(MediaStore.MediaColumns.DISPLAY_NAME, outputFilename)
    values.put(MediaStore.MediaColumns.MIME_TYPE, "application/my-custom-type")
    values.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS + "/" + outputDirectory)
    val uri = resolver.insert(MediaStore.Files.getContentUri("external"), values)
    // You can use this outputStream to write whatever file you want:
    val outputStream = resolver.openOutputStream(uri!!)
    // Or alternatively call other methods of ContentResolver, e.g. .openFile
    

    在以下两种情况下,您都不需要 WRITE_EXTERNAL_STORAGE适用于 Android 29 及更高版本。

    关于android - 在 Android 11 上编写许多文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64720379/

    相关文章:

    android - WrongViewCast 错误 : Unexpected implicit cast to TabLayout: layout tag was Linear Layout

    android - 从后台返回视频时出现空白屏幕

    android - SAF - ACTION_CREATE_DOCUMENT - 将文件保存到云端硬盘后,文件为空

    android - 正确删除DocumentFile(尊重MediaStore)

    android - 如何在 Android 11 中实现 New Storage API?

    java - 在Android中将语音录制为mp3

    android - 使用 JTwitter 转发和回复

    java - Android 开发和新的 Oracle JDK 许可证

    android - 使用 Android 存储访问框架重命名 Google Drive 文档导致权限错误

    java - Android 无法对 SD 卡进行写入和删除操作