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

Android 10及以上版本如何创建根目录,现有代码创建失败如何解决

Android 10及以上创建共享目录存储图片失败解决方案

失败原因

Android 10(API 级别29)开始系统引入分区存储机制,默认禁止应用直接访问共享存储根目录,原有代码中使用的Environment.getExternalStorageDirectory()已被官方废弃,普通应用无权限直接在根目录创建自定义文件夹,因此调用dir.mkdir()会返回false,创建失败。
另外你提到的“使用Cursor创建根文件夹”存在认知偏差:Cursor是Android系统中用于查询数据的工具类,本身无法直接创建文件夹,你需要的是适配分区存储规则,使用MediaStore API向公共媒体目录写入文件,该方案兼容Android 10及以上所有版本,无需申请特殊权限。

前置配置

先在AndroidManifest.xml中补充必要配置:

<!-- Android 12及以下版本存储权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
<!-- Android 13及以上版本无需存储权限即可写入公共相册 -->

如果你的targetSdkVersion <=29,可以在application节点临时添加android:requestLegacyExternalStorage="true"作为过渡方案,但该配置在Android 11及以上系统无效,建议直接使用下方适配方案

代码修改方案

你可以直接替换AsyncTask中doInBackground的原有逻辑,使用MediaStore写入图片:

@Override
protected Void doInBackground(Bitmap... bitmaps) {
    ContentResolver resolver = getContentResolver();
    ContentValues contentValues = new ContentValues();
    // 设置文件显示名称
    contentValues.put(MediaStore.Images.Media.DISPLAY_NAME, String.format("%d.jpg", System.currentTimeMillis()));
    // 设置文件类型
    contentValues.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
    // 指定存储到公共Pictures目录下的SaveImage文件夹,系统会自动创建该文件夹
    contentValues.put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_PICTURES + "/SaveImage");
    // 设置文件状态为待处理,写入完成前其他应用无法访问
    contentValues.put(MediaStore.Images.Media.IS_PENDING, 1);

    // 插入到媒体库,得到文件Uri
    Uri imageUri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
    if (imageUri == null) {
        return null;
    }

    try {
        OutputStream outputStream = resolver.openOutputStream(imageUri);
        if (outputStream != null) {
            bitmapVar.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
            outputStream.close();
        }
        // 写入完成后更新状态,允许其他应用访问该图片
        contentValues.clear();
        contentValues.put(MediaStore.Images.Media.IS_PENDING, 0);
        resolver.update(imageUri, contentValues, null, null);
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}

该方案不需要你手动创建文件夹,系统会自动在公共Pictures目录下生成SaveImage文件夹,图片保存后可以在系统相册中直接查看,兼容所有Android 10及以上版本。

补充说明:AsyncTask已在Android API 30中被废弃,后续迭代建议替换为Coroutines或者WorkManager实现异步任务

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 19:39:03