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

Android 13+公共文档目录文本文件读写失败问题求助

问题原因分析
  • Android 13+作用域存储的媒体类型限制:WRITE_EXTERNAL_STORAGE权限在Android 13及以上版本中,仅授予对图片、音频、视频这类媒体文件的写入权限,文本文件不属于媒体范畴,因此无法通过旧的File API写入公共Documents目录。这就是PNG截图能正常写入,而文本文件失败的核心原因。
  • 模拟器与真机的规则差异:Android模拟器默认可能开启调试兼容模式,放宽了作用域存储的限制,而真机严格执行官方的存储规则,导致功能表现不一致。
  • 权限申请的异步问题:askForWritePermission()是异步请求权限的方法,调用后立刻执行文件读写操作,此时权限可能还未完成授予,直接导致操作失败。
解决方案

根据需求提供三种可行方案:

方案一:使用存储访问框架(SAF)操作公共Documents目录

适合需要让用户在系统文件管理器中看到文本文件的场景,无需依赖WRITE_EXTERNAL_STORAGE权限:

保存文本文件到Documents/TEST目录

private static final int REQUEST_SAVE_TEXT = 1001;

// 启动SAF选择保存路径
private void saveTextFile(String content, String month) {
    Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    intent.setType("text/plain");
    intent.putExtra(Intent.EXTRA_TITLE, month + ".txt");
    
    // 指定初始目录为Documents/TEST
    Uri testDirUri = DocumentsContract.buildDocumentUriUsingTree(
        MediaStore.Downloads.EXTERNAL_CONTENT_URI,
        DocumentsContract.getTreeDocumentId(MediaStore.Downloads.EXTERNAL_CONTENT_URI) + "/TEST"
    );
    intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, testDirUri);
    startActivityForResult(intent, REQUEST_SAVE_TEXT);
}

// 在回调中处理写入逻辑
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQUEST_SAVE_TEXT && resultCode == RESULT_OK) {
        Uri uri = data.getData();
        try (OutputStream outputStream = getContentResolver().openOutputStream(uri)) {
            outputStream.write(content.getBytes(StandardCharsets.UTF_8));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

读取文本文件

private static final int REQUEST_LOAD_TEXT = 1002;

// 启动SAF选择要读取的文件
private void loadTextFile() {
    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    intent.setType("text/plain");
    startActivityForResult(intent, REQUEST_LOAD_TEXT);
}

// 在回调中处理读取逻辑
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQUEST_LOAD_TEXT && resultCode == RESULT_OK) {
        Uri uri = data.getData();
        try (InputStream inputStream = getContentResolver().openInputStream(uri)) {
            String content = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
            writeDataFromFileToTable(content);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

方案二:使用应用专属存储

适合仅应用自身需要访问的文件,无需申请任何存储权限,安全性更高:

修改文件路径获取代码

public File getSavedFile(String month) {
    // 获取应用专属外部存储的Documents目录
    File appTestDir = new File(getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS), "TEST");
    appTestDir.mkdirs();
    return new File(appTestDir, month + ".txt");
}

public File getSavedImage(String month) {
    // 获取应用专属外部存储的Pictures目录
    File appTestDir = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), "TEST");
    appTestDir.mkdirs();
    return new File(appTestDir, month + ".png");
}

清理Manifest权限

删除READ_EXTERNAL_STORAGE和WRITE_EXTERNAL_STORAGE权限,应用专属存储不需要这些权限。

方案三:申请MANAGE_EXTERNAL_STORAGE权限(仅特殊场景使用)

如果你的应用是文件管理器类应用,需要完全访问外部存储,可以申请这个权限,但该权限需要Google Play审核,不推荐普通应用使用:

权限配置

<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />

申请权限代码

public void askForManageStoragePermission() {
    if (!Environment.isExternalStorageManager()) {
        Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
        Uri uri = Uri.fromParts("package", getPackageName(), null);
        intent.setData(uri);
        startActivity(intent);
    }
}
额外注意事项
  • 移除tools:ignore="ScopedStorage"标记,遵循Android官方存储规范,避免后续版本兼容性问题。
  • 权限申请后,必须通过onRequestPermissionsResult回调确认权限授予完成,再执行文件操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 06:06:16