如何在API 29中弃用getExternalStorageDirectory来读写文件?

Muj*_*han 7 java android android-10.0

我是android开发的新手,我在阅读java中的getExternalStorageDirectory时遇到了一些问题,我已经阅读了https://developer.android.com/reference/android/os/Environment,但无法理解,有人可以帮我举例吗Java代码

小智 10

文档中您可以看到:

getExternalStoragePublicDirectory(String type)

在API级别29中不赞成使用此方法。为了提高用户隐私,不建议直接访问共享/外部存储设备。当应用程序定位到Build.VERSION_CODES.Q时,此方法返回的路径不再可供应用程序直接访问。通过迁移到Context#getExternalFilesDir(String),MediaStore或Intent#ACTION_OPEN_DOCUMENT之类的替代方案,应用程序可以继续访问共享/外部存储中存储的内容

不传递任何参数作为此函数的参数,以将目录作为File对象:

context.getExternalFilesDir();

这里的“上下文”是一个对象,它是通过 this.getContext();

this是活动的当前对象。使用时请仔细检查示波器。

重要

要访问内部存储,Manifest.permission.WRITE_EXTERNAL_STORAGE和/或Manifest.permission.READ_EXTERNAL_STORAGE需要访问文件AndroidManifest.xml

可选信息:

  1. 通常,内部存储在Android设备上的路径为/ sdcard /。这不是真正的路径,而是符号链接

  2. 这很令人困惑,但Android中的“外部sdcard”实际上是指内部设备存储,而不是外部可弹出设备外存储卡存储。另请注意,真正的外部sdcard无法完全访问

  3. Activity类扩展了Context类,这就是为什么我们可以从中获取上下文的原因。

  • 请注意,卸载应用程序时,此方法返回的路径将被删除。它不会提供与“Environment.getExternalStorageDirectory()”相同的位置。 (8认同)

Nir*_*iya 6

更新

从 Android 11 开始,它不允许在根目录中创建文件夹/文件,但是,我们仍然可以借助公共目录来管理文件夹分离(它会显示已弃用的警告,但它会起作用)

fun getAbsolutePath(context: Context): File {
    return File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "{YOUR_FOLDER_NAME}"))
}
Run Code Online (Sandbox Code Playgroud)

现在,使用公共目录路径创建文件

val file = File(getAbsolutePath(requireContext()), "FILENAME.EXTENSION")
Run Code Online (Sandbox Code Playgroud)

年长的

使用这个静态方法。目前我找不到任何合法的方法来做到这一点。因此,我使用了这个静态方法来获取 root 或 getAbsolutePath 文件路径。

public static File getAbsoluteDir(Context ctx, String optionalPath) {
        String rootPath;
        if (optionalPath != null && !optionalPath.equals("")) {
            rootPath = ctx.getExternalFilesDir(optionalPath).getAbsolutePath();
        } else {
            rootPath = ctx.getExternalFilesDir(null).getAbsolutePath();
        }
        // extraPortion is extra part of file path
        String extraPortion = "Android/data/" + BuildConfig.APPLICATION_ID
                + File.separator + "files" + File.separator;
        // Remove extraPortion
        rootPath = rootPath.replace(extraPortion, "");
        return new File(rootPath);
    }
Run Code Online (Sandbox Code Playgroud)