可以通过 Android 11

问题描述

我正在尝试使用 Android 11 中的 Environment.getExternalStoragePublicDirectory 进行一些测试。

问题 1:为什么我不能创建新文件,但可以创建新目录?
问题 2canRead() + canWrite() 返回 true,但 createNewFile() 不起作用,为什么?

(如果为空,如果存在,...本例省略检查)

获取公共电影目录:

fun getExternalPublicMoviesDir(): File? {
    val movies = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES)
    try {
        movies.mkdirs()
        if (Environment.getExternalStorageState(movies) == Environment.MEDIA_MOUNTED) {
            return movies
        }
    } catch (e: Exception) {
        e.printstacktrace()
    }
    return null
}

创建文件/文件夹:

val externalMoviesPath = getExternalPublicMoviesDir()
externalMoviesPath.canRead() //return true
externalMoviesPath.canWrite() //return true

val newDir = File(externalMoviesPath,"newDirTest")
newDir.mkdirs() //works

val newFile = File(externalMoviesPath,"newFileTest")
newFile.createNewFile() // <- java.io.IOException: No such file or directory

异常:

java.io.IOException: No such file or directory
    at java.io.UnixFileSystem.createFileExclusively0(Native Method)
    at java.io.UnixFileSystem.createFileExclusively(UnixFileSystem.java:317)
    at java.io.File.createNewFile(File.java:1008)

只是为了完整性:在 Android 10 中,当 WRITE_EXTERNAL_STORAGE 被授予时,代码有效。

更新 当我使用 Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS) 而不是 Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES) 时,createNewFile 方法有效。

在三星、Pixel 等真实设备和 Android 模拟器上进行了测试。

解决方法

您可以使用 FileProviderContext.getExternalFilesDir(type) 其中类型可以是目录等... DIRECTORY_MOVIES 从现在开始并设置路径作为 xml 目录中的 <external-files-path name="" path="/" />。欲知详情https://developer.android.com/reference/androidx/core/content/FileProvider