API 29中Environment.getExternalStorageDirectory()已废弃,求替代方案
API 29+ 替代Environment.getExternalStorageDirectory()的方案
在API 29及以上,Environment.getExternalStorageDirectory()被废弃是因为Google推行分区存储模型,目的是提升文件安全性和用户隐私保护。以下是不同场景下的替代方案:
1. 存储应用专属文件(卸载后自动删除)
如果是存放应用自己的文件,直接用Context提供的方法,无需额外存储权限(API 29+):
- 获取应用专属外部文件目录:
context.getExternalFilesDir(null)- 示例路径:
/storage/emulated/0/Android/data/[你的应用包名]/files
- 示例路径:
- 获取应用专属外部缓存目录:
context.getExternalCacheDir()- 示例路径:
/storage/emulated/0/Android/data/[你的应用包名]/cache
- 示例路径:
2. 访问公共媒体目录(图片、下载、音乐等)
如果需要操作公共媒体文件,推荐使用MediaStore API,这是官方推荐的标准方式:
- 获取公共目录的Uri(以下载目录为例):
// Kotlin val downloadDirUri = MediaStore.Downloads.EXTERNAL_CONTENT_URI
// Java Uri downloadDirUri = MediaStore.Downloads.EXTERNAL_CONTENT_URI;
如果确实需要获取对应路径(API 29+不建议直接操作路径,优先用ContentResolver读写),可以通过查询MediaStore获取相对路径:
String[] projection = {MediaStore.Downloads.RELATIVE_PATH}; Cursor cursor = getContentResolver().query(downloadDirUri, projection, null, null, null); if (cursor != null) { if (cursor.moveToFirst()) { String relativePath = cursor.getString(0); String fullPath = Environment.getExternalStorageDirectory().getPath() + relativePath; } cursor.close(); }
3. 临时兼容访问根外部存储(不推荐)
如果你的应用是文件管理器类等必须直接访问根目录的场景,可以在AndroidManifest.xml中开启临时兼容:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <application ... android:requestLegacyExternalStorage="true"> ... </application> </manifest>
开启后可以继续使用Environment.getExternalStorageDirectory(),但这是过渡方案,API 30及以上即使开启,也无法访问其他应用的私有文件,未来版本可能彻底移除支持。
关键提醒
- 尽量遵循分区存储设计,减少权限依赖,避免后续版本兼容性问题。
- API 30+ 必须使用MediaStore或**存储访问框架(SAF)**来访问非应用专属的公共文件。
内容的提问来源于stack exchange,提问作者Anirudh Kachroo
相关产品推荐
相关产品推荐

