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

使用OpenDocumentTree将Uri转路径,实现Excel文件保存至用户选择目录

解决OpenDocumentTree Uri无法转换为文件路径的问题

从OpenDocumentTree返回的Uri属于Android存储访问框架(SAF)的文档树Uri,不能直接转换为传统文件路径——Android 10及以上版本限制了对外部存储的直接访问权限,必须通过SAF提供的API完成文件创建与写入操作,具体修改方案如下:

修改后的完整代码实现

final ActivityResultLauncher<Uri> mDirRequest = registerForActivityResult(
        new ActivityResultContracts.OpenDocumentTree(),
        new ActivityResultCallback<Uri>() {
            @Override
            public void onActivityResult(Uri selectedDirUri) {
                if (selectedDirUri == null) {
                    // 用户取消目录选择
                    return;
                }

                // 1. 在选定目录下创建goofy.xlsx文件
                Uri fileUri = null;
                try {
                    fileUri = DocumentsContract.createDocument(
                            getContentResolver(),
                            selectedDirUri,
                            "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
                            "goofy.xlsx"
                    );
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                    return;
                }

                if (fileUri == null) {
                    // 文件创建失败
                    return;
                }

                // 2. 通过ContentResolver获取输出流并写入Excel内容
                try (OutputStream out = getContentResolver().openOutputStream(fileUri)) {
                    workbook.write(out);
                    // 可选:持久化目录访问权限,避免应用重启后需重新选择
                    getContentResolver().takePersistableUriPermission(
                            selectedDirUri,
                            Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
                    );
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });

关键细节说明

  • DocumentsContract.createDocument():依托选定的目录Uri在目标目录下创建新文件,需传入Excel(xlsx)对应的MIME类型application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,返回新文件的Uri。
  • getContentResolver().openOutputStream():直接通过文件Uri获取输出流,无需转换为File对象即可完成写入操作,适配SAF的权限机制。
  • takePersistableUriPermission():若需要应用重启后仍能访问该目录,调用此方法持久化权限,避免重复请求用户授权。

启动目录选择器的修正

你原启动代码存在参数错误,DocumentsContract.EXTRA_INITIAL_URI是Intent的额外参数而非Uri,正确启动方式如下:

// 可选:指定初始目录,例如下载目录
Uri initialDirUri = MediaStore.Downloads.EXTERNAL_CONTENT_URI;
mDirRequest.launch(initialDirUri);

// 无需初始目录时直接传null
// mDirRequest.launch(null);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 09:15:35