如何在 API 29 中弃用 getExternalStorageDirectory 时读取或写入文件?
Posted
技术标签:
【中文标题】如何在 API 29 中弃用 getExternalStorageDirectory 时读取或写入文件?【英文标题】:How to read or write file as getExternalStorageDirectory is deprecated in API 29? 【发布时间】:2019-11-11 03:49:14 【问题描述】:我正在学习 android 开发,我在阅读 java 中的 getExternalStorageDirectory 时遇到了一些问题,我已阅读 https://developer.android.com/reference/android/os/Environment 但无法理解,有人可以帮助我使用 java 中的示例代码。
【问题讨论】:
【参考方案1】:从docs可以看到:
getExternalStoragePublicDirectory(String type)
此方法在 API 级别 29 中已弃用。为了提高用户隐私,不建议直接访问共享/外部存储设备。什么时候 一个应用程序以 Build.VERSION_CODES.Q 为目标,从这里返回的路径 应用程序不再可以直接访问方法。应用程序可以继续 通过迁移到访问存储在共享/外部存储上的内容 Context#getExternalFilesDir(String) 等替代方案, MediaStore,或 Intent#ACTION_OPEN_DOCUMENT。
不向此函数传递任何参数,以将您的目录作为File
对象:
context.getExternalFilesDir();
这里的“上下文”是this.getContext();
获取的对象
this
是Activity的当前对象。使用时请仔细检查范围。
重要
要访问内部存储空间,AndroidManifest.xml 文件中需要 Manifest.permission.WRITE_EXTERNAL_STORAGE
和/或 Manifest.permission.READ_EXTERNAL_STORAGE
。
可选信息:
通常内部存储有路径 /sdcard/ 在 Android 设备上。这不是真正的路径,而是symlink。
这很令人困惑,但 Android 中的“外部 sdcard”实际上是指内部设备存储,而不是外部可弹出的设备外存储卡存储。 另请注意,真正的外部sdcard无法完全访问
Activity 类扩展了 Context 类这就是我们可以从中获取上下文的原因。
【讨论】:
请注意,此方法返回的路径会在应用卸载时被删除。它不会提供与Environment.getExternalStorageDirectory()
相同的位置。【参考方案2】:
更新
从 Android 11 开始,它不允许在根目录中创建文件夹/文件,但我们仍然可以在公共目录的帮助下管理文件夹分离(它会显示已弃用的警告,但它会起作用)
fun getAbsolutePath(context: Context): File
return File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "YOUR_FOLDER_NAME"))
现在,用公共目录路径创建文件
val file = File(getAbsolutePath(requireContext()), "FILENAME.EXTENSION")
老年人
使用此静态方法。 目前我没有找到任何合法的方式来做到这一点。 所以,我做了这个静态方法来获取 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);
【讨论】:
静态路径总是一个不好的解决方案,因为 Android 太分散了,您的制造商可能有不同的目录路径。不要使用这个 所有设备通用。你可以检查一下。【参考方案3】:使用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();
【讨论】:
以上是关于如何在 API 29 中弃用 getExternalStorageDirectory 时读取或写入文件?的主要内容,如果未能解决你的问题,请参考以下文章
UIAlertView 已弃用:首先在 iOS 9.0 中弃用 - UIAlertView 已弃用。将 UIAlertController 与首选样式一起使用
thumbnailImageAtTime:timeOption 已弃用:首先在 iOS 7 中弃用