为何getExternalStoragePublicDirectory在Android 14及以下全版本无需权限即可工作?
问题
我开发了一款仅需将txt或xlsx文件写入Downloads目录的简单应用,无需访问其他共享文件夹。此前我尝试通过ActivityResultLauncher机制申请WRITE_EXTERNAL_STORAGE运行时权限,但该方式在Android 13之后失效(需更细分权限)。然而,我发现以下这段简单代码无需任何权限,即可在所有Android版本(模拟器)中成功将文件写入Downloads目录。即使移除Manifest中的<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />声明,文件仍能正常保存。我曾了解到getExternalStoragePublicDirectory()已被废弃,但IDE未标记其为废弃状态。请问这是为何?
public void saveFile(String fileName, byte[] fileBytes) { final File downloadsFolder = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); if (Objects.isNull(downloadsFolder)) { Log.e(LOG_PREFIX, "The downloads folder was null"); toaster.show(R.string.collections_fragment_lack_permission_to_write_file); return; } if (!downloadsFolder.exists()) { if (!downloadsFolder.mkdirs()) { Log.e(LOG_PREFIX, "The downloads folder does not exist, and an attempt to create it failed"); toaster.show(R.string.collections_fragment_lack_permission_to_write_file); return; } } final File file = new File(downloadsFolder, fileName); try { final var fos = new FileOutputStream(file); fos.write(fileBytes); fos.close(); } catch (IOException e) { Log.e(LOG_PREFIX, "Something went wrong while attempting to write to the downloads folder"); toaster.show(R.string.collections_fragment_lack_permission_to_write_file); } sendFileExportedNotification(fileName); }
回答
一、为何无需权限就能写入Downloads目录
从Android 10(API 29)开始,系统引入分区存储机制,对公共目录访问规则做了调整:
DIRECTORY_DOWNLOADS属于系统开放的公共文档目录,应用无需申请WRITE_EXTERNAL_STORAGE权限即可写入,这是分区存储允许的合法场景。- Android 13(API 33)虽然拆分了原存储权限为媒体细分权限,但写入Downloads目录的规则延续了Android 10的设计,依然不需要额外权限。
- 对于Android 10以下的版本,系统对公共Downloads目录的写入限制本就较低,若应用targetSdkVersion偏低,系统会默认授予存储权限(这是兼容行为,不建议长期依赖)。
二、为何getExternalStoragePublicDirectory()未被IDE标记为废弃
这个方法确实在API 29时被官方标记为废弃,IDE没提示的原因通常有两个:
- 项目
compileSdkVersion低于API 29:废弃标记是在API 29中添加的,编译版本没升到29或更高时,IDE无法识别废弃提示。 - IDE缓存异常:Android Studio的缓存偶尔会导致标记不显示,可尝试清理缓存(File → Invalidate Caches...)后重启IDE。
注意:虽然当前代码能正常运行,但官方不推荐再使用该方法,建议改用MediaStore或ACTION_CREATE_DOCUMENT方式写入公共目录,更适配高版本系统的分区存储规则。
内容的提问来源于stack exchange,提问作者ismarlowe
相关产品推荐
相关产品推荐

