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

Android使用Intent操作文件后无法写入数据问题

问题原因

你的代码核心问题在于:通过Intent.ACTION_CREATE_DOCUMENT或ACTION_OPEN_DOCUMENT获取的是文件的Content URI,但你的writeToFile方法却直接用文件名在Environment.DIRECTORY_DOCUMENTS目录下创建/查找文件——这和用户实际选择的文件根本不是同一个(比如用户可能在Downloads目录创建文件,你却去Documents目录找同名文件),自然无法写入数据。

另外,Android 10及以上的Scoped Storage限制了直接访问文件路径,必须通过ContentResolver操作Content URI来读写文件。

修复方案

1. 保留Uri引用,不要只存文件名

把currentProject的作用改为记录文件名(仅用于显示),实际读写依赖uriFile变量,因为Uri是唯一指向文件的标识。

2. 重写writeToFile方法,通过ContentResolver写入

替换原来的writeToFile方法,用ContentResolver打开输出流来写入数据:

private void writeToFile(String data, Context context) {
    if (uriFile == null) {
        // 如果没有选中文件,使用默认文件逻辑
        File dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS);
        File file = new File(dir, "amirLight.txt");
        try (FileWriter fileWriter = new FileWriter(file, true)) {
            fileWriter.append(data);
            fileWriter.write(System.lineSeparator());
        } catch (IOException e) {
            Log.e("FileWrite", "默认文件写入失败", e);
        }
        return;
    }

    // 通过Content URI写入文件
    try (OutputStreamWriter writer = new OutputStreamWriter(
            context.getContentResolver().openOutputStream(uriFile, "wa"))) {
        writer.append(data);
        writer.write(System.lineSeparator());
        Log.e("FileWrite", "数据写入成功");
    } catch (IOException e) {
        Log.e("FileWrite", "写入失败", e);
        Toast.makeText(context, "文件写入失败", Toast.LENGTH_SHORT).show();
    }
}

3. 获取持久化文件访问权限(可选但推荐)

当用户通过ACTION_OPEN_DOCUMENT打开文件后,获取持久化权限,这样App重启后仍能访问该文件:
在onActivityResult的requestCode==3分支里添加:

// 获取持久化权限
final int takeFlags = data.getFlags()
        & (Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
getContentResolver().takePersistableUriPermission(uriFile, takeFlags);

4. 调用修改后的writeToFile方法

在getLocation方法里,把调用改为:

writeToFile("Lux "+currentLux+" Y "+wayLatitude+" X "+wayLongitude, getApplicationContext());

5. 处理默认文件的情况

如果用户没有选择任何文件,仍使用原来的默认文件逻辑,这样兼容原来的功能。

关键说明
  • openOutputStream的第二个参数"wa"表示追加写入,和原来的FileWriter(file, true)效果一致。
  • Content URI是Android系统文件访问的标准方式,尤其是Scoped Storage下,必须用这种方式操作非App私有目录的文件。
  • 持久化权限确保App重启后不需要重新选择文件,提升用户体验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 19:35:16