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

Android TargetSdk33下SD卡目录创建失败,权限问题求助

Android 13(TargetSdk33)存储权限变更导致目录创建失败的解决方案

问题根源

Android 13(API 33)彻底调整了外部存储权限规则:

  • 旧的WRITE_EXTERNAL_STORAGE和READ_EXTERNAL_STORAGE权限已被废弃,不再生效。
  • 应用无法直接在Environment.getExternalStorageDirectory()指向的公共存储根目录创建自定义文件夹(比如你代码里的/Temp),系统会直接拒绝这类操作。

分场景解决方法

场景1:存储应用私有文件(推荐)

如果这些文件不需要被其他应用访问,直接用应用专属外部存储目录,完全不需要申请权限:

// 路径示例:/storage/emulated/0/Android/data/com.export.exportcontacts/files/Temp
File directory = new File(getExternalFilesDir(null), "Temp");
if (!directory.exists()) {
    boolean isCreated = directory.mkdirs();
    // 可打印isCreated值确认是否创建成功
}

这个目录的文件会随应用卸载自动删除,符合Android的存储最佳实践。

场景2:必须写入公共存储目录(非媒体文件)

如果一定要在公共区域创建目录,只能用**存储访问框架(SAF)**让用户手动选择目录授权:

  1. 启动目录选择界面:
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
startActivityForResult(intent, 1001);
  1. 处理用户选择结果并创建目录:
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == 1001 && resultCode == RESULT_OK && data != null) {
        Uri treeUri = data.getData();
        // 申请持久化权限,下次启动不用再选目录
        getContentResolver().takePersistableUriPermission(treeUri,
                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
        
        // 在选中的目录下创建Temp文件夹
        DocumentFile rootDir = DocumentFile.fromTreeUri(this, treeUri);
        DocumentFile tempDir = rootDir.createDirectory("Temp");
        // tempDir就是创建好的目录对象
    }
}

场景3:存储媒体文件(图片/音频/视频)

如果是存媒体类文件,先替换Manifest里的权限:

<!-- 图片权限 -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.WRITE_MEDIA_IMAGES" />
<!-- 音频权限 -->
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<uses-permission android:name="android.permission.WRITE_MEDIA_AUDIO" />
<!-- 视频权限 -->
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.WRITE_MEDIA_VIDEO" />

然后用MediaStore API写入文件,不要直接操作File对象。

兼容低版本设备的注意事项

如果要兼容API 32及以下设备,Manifest里可以保留旧权限但加上版本限制:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />

同时,低版本设备需要动态申请WRITE_EXTERNAL_STORAGE权限,API 33及以上则只需动态申请对应的媒体权限,SAF方式无需权限申请但需要用户手动选目录。

内容的提问来源于stack exchange,提问作者Anatoli

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 04:02:44