如何在API 29中读写文件,因为getExternalStorageDirectory已被弃用?

15
4个回答

12

文档中可以看到:

getExternalStoragePublicDirectory(String type)

该方法在API级别29中已被弃用。为了提高用户隐私,不再直接访问共享/外部存储设备。当应用程序针对Build.VERSION_CODES.Q时,从此方法返回的路径不再直接可供应用程序访问。应用程序可以继续通过迁移到替代方案,例如Context#getExternalFilesDir(String)、MediaStore或Intent#ACTION_OPEN_DOCUMENT来访问存储在共享/外部存储上的内容。

不传递参数即可将您的目录作为File对象获取:

context.getExternalFilesDir();

这里的"Context"是通过this.getContext();获取的对象。

this是Activity的当前对象。在使用时请仔细检查范围。

重要提示

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

可选信息:

  1. 通常,内部存储在Android设备上的路径为/sdcard/。它不是一个真实的路径,而是一个symlink

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

  3. Activity类扩展自Context类,因此我们可以从中获取上下文。


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

6

更新

从Android 11开始,不允许在根目录下创建文件夹/文件,但我们仍然可以通过公共目录来管理文件夹分离(它会显示一个过时的警告,但它仍然有效)

fun getAbsolutePath(context: Context): File {
    return File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "{YOUR_FOLDER_NAME}"))
}

现在,创建具有常见目录路径的文件。

val file = File(getAbsolutePath(requireContext()), "FILENAME.EXTENSION")

旧版

使用这个静态方法。 目前我没有找到任何合法的方法来做到这一点。 因此,我编写了这个静态方法来获取根目录或绝对路径文件路径。

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);
    }

静态路径总是一个不好的解决方案,因为Android太过分散,你的制造商可能有不同的目录路径。不要使用这个。 - Undefined function
这对所有设备都是普遍的。你可以检查一下。 - Niral Dhameliya
getExternalStoragePublicDirectory()回答了其他100个线程中的问题,即“如何访问公共DCIM目录(例如)以保存文件”。其余答案是为了获取应用程序的内部目录(例如DCIM),这些目录无法通过图库查看。 - IOviSpot

1
使用Context中的getExternalFilesDir()getExternalCacheDir()getExternalMediaDirs()方法,而不是Environment.getExternalStorageDirectory()。请注意保留HTML标签。
String root = mContext.getExternalFilesDir(null).getAbsolutePath();
File myDir = new File(root + "/" + mContext.getResources().getString(R.string.app_name) + "_share");
    myDir.mkdirs();

    
    

0
在2022年,Environment.getExternalStorageDirectoryEnvironment.getExternalStoragePublicDirectory已经取消弃用(undeprecated)
它们从API 29~31被标记为已弃用(deprecated),但不包括以上版本。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接