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

如何修复Android写入内部存储DCIM目录时出现的权限错误问题

Android写入公共DCIM目录权限报错解决方案

修复步骤

1. 补充运行时动态权限申请

Android 6.0(API level 23)及以上系统,仅在AndroidManifest.xml声明存储权限不生效,必须在运行时主动申请权限:

  • 现有代码仅判断权限未授予就打印日志,没有发起权限申请流程,自然无法拿到写入权限,且权限未授予时没有中断后续写入逻辑,直接执行文件操作必然报错
  • 权限申请示例:
// 预先定义权限请求码常量
private static final int REQUEST_WRITE_STORAGE = 112;

// 替换原有权限判断逻辑
if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
    Log.v(TAG, "Permission is not granted!");
    // 发起权限申请
    ActivityCompat.requestPermissions(this,
            new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
            REQUEST_WRITE_STORAGE);
    // 权限未获取直接返回,不执行后续写入逻辑
    return;
}
  • 重写onRequestPermissionsResult回调,确认用户授权通过后再调用写入方法。

2. 适配分区存储规则

Android 10(API level 29)开始引入分区存储机制,WRITE_EXTERNAL_STORAGE权限被废弃,公共目录写入需要做对应适配:

  • 若应用targetSdkVersion介于29~32之间,在AndroidManifest.xml的application节点添加属性做临时兼容:
android:requestLegacyExternalStorage="true"
  • 若应用targetSdkVersion >= 33,不要直接使用FileAPI操作公共目录路径,改为使用MediaStoreAPI写入DCIM目录,无需申请存储权限即可实现写入,示例:
ContentValues values = new ContentValues();
values.put(MediaStore.MediaColumns.DISPLAY_NAME, "testing.txt");
values.put(MediaStore.MediaColumns.MIME_TYPE, "text/plain");
values.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DCIM);

ContentResolver resolver = getContentResolver();
Uri uri = resolver.insert(MediaStore.Files.getContentUri("external"), values);
if (uri != null) {
    try (OutputStream os = resolver.openOutputStream(uri)) {
        os.write(text.getBytes(StandardCharsets.UTF_8));
    } catch (IOException e) {
        Log.e("Exception", "File write failed: " + e.toString());
    }
}

3. 修复原有代码逻辑问题

现有写入代码存在两处逻辑错误会导致写入失败:

  • 执行file.createNewFile()之前就判断文件不存在打印错误日志,判断顺序完全倒置
  • 流关闭顺序错误:先关闭OutputStreamWriter再执行FileOutputStream的flush操作,此时写入内容已经被丢弃,可直接用try-with-resources语法自动管理流的关闭,避免手动操作错误:
try (FileOutputStream fOut = new FileOutputStream(file);
     OutputStreamWriter myOutWriter = new OutputStreamWriter(fOut)) {
    myOutWriter.append(text);
    myOutWriter.flush();
} catch (IOException e) {
    Log.e("Exception", "File write failed: " + e.toString());
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 11:09:04