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

How to read or write file as getExternalStorageDirectory is deprecated in API 29?

我正在学习 android 开发,我在阅读 java 中的 getExternalStorageDirectory 时遇到了一些问题,我已经阅读了 https://developer.android.com/reference/android/os/Environment 但无法理解,谁能帮我举个例子java.

中的代码

docs可以看出:

getExternalStoragePublicDirectory(String type)

This method was deprecated in API level 29. To improve user privacy, direct access to shared/external storage devices is deprecated. When an app targets Build.VERSION_CODES.Q, the path returned from this method is no longer directly accessible to apps. Apps can continue to access content stored on shared/external storage by migrating to alternatives such as Context#getExternalFilesDir(String), MediaStore, or Intent#ACTION_OPEN_DOCUMENT.

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

context.getExternalFilesDir();

这里"Context"是通过this.getContext();

得到的对象

this是Activity的当前对象。使用时请仔细检查瞄准镜。

重要

要访问内部存储,文件 AndroidManifest.xml.

中需要 Manifest.permission.WRITE_EXTERNAL_STORAGE and/or Manifest.permission.READ_EXTERNAL_STORAGE

可选信息:

  1. 通常内部存储有路径 /sdcard/ 在 Android 台设备上。这不是真正的路径,而是 symlink.

  2. 令人困惑,但 Android 中的 "external sdcard" 实际上是指内部设备存储,而不是外部可弹出 out-of-the-device 存储卡存储。 另请注意,real external sdcard无法完全访问

  3. Activity class extends the Context class 所以我们可以从中获取上下文

已更新

From Android 11, it won't allow creating folder/file in the root directory but, we can still manage folder separation with help of the public directory (It will show a deprecated warning but it will work)

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

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

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

年长

Use this static method. Currently I don't find any legal way to do this. So, I was made this static method to get root or getAbsolutePath file path.

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

使用 getExternalFilesDir()getExternalCacheDir()getExternalMediaDirs() (上下文中的方法)而不是 Environment.getExternalStorageDirectory()

String root = mContext.getExternalFilesDir(null).getAbsolutePath();
File myDir = new File(root + "/" + mContext.getResources().getString(R.string.app_name) + "_share");
    myDir.mkdirs();