You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 06:43:37