使用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
相关产品推荐
相关产品推荐

