Android中如何在ActivityResultLauncher<String>设置EXTRA_INITIAL_URI
问题解答:如何在文件选择时设置初始目录(EXTRA_INITIAL_URI)
你提到的GetContent这个ActivityResultContract是官方封装的简化版文件选择器,它不支持直接设置EXTRA_INITIAL_URI——因为它的内部逻辑固定了Intent的构建,没有暴露添加额外参数的入口。
要实现设置初始目录的需求,可以用以下两种方法:
方法一:使用通用的StartActivityForResult Contract,自行构建Intent
这种方式最直接,完全自主控制Intent的所有参数,包括添加EXTRA_INITIAL_URI:
1. 注册ActivityResultLauncher
ActivityResultLauncher<Intent> mDocumentPickerLauncher = registerForActivityResult( new ActivityResultContracts.StartActivityForResult(), result -> { if (result.getResultCode() == Activity.RESULT_OK && result.getData() != null) { Uri selectedUri = result.getData().getData(); // 在这里处理获取到的文件Uri } } );
2. 构建带初始目录的Intent并启动
// 构建打开文档的Intent,和GetContent功能一致 Intent pickerIntent = new Intent(Intent.ACTION_OPEN_DOCUMENT); pickerIntent.setType("image/*"); // 设置你需要的MIME类型,和之前的"image/*"保持一致 // 设置初始目录Uri,示例为系统下载目录,可替换为你需要的目录Uri Uri initialDirUri = MediaStore.Downloads.EXTERNAL_CONTENT_URI; pickerIntent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, initialDirUri); // 启动文件选择器 mDocumentPickerLauncher.launch(pickerIntent);
方法二:自定义ActivityResultContract,封装复用逻辑
如果需要在多个地方使用带初始目录的文件选择器,可以自定义一个Contract,把逻辑封装起来:
1. 自定义Contract类
public class OpenDocumentWithInitialDir extends ActivityResultContract<OpenDocumentWithInitialDir.PickerParams, Uri> { // 封装需要的参数:MIME类型和初始目录Uri public static class PickerParams { public String mimeType; public Uri initialDirUri; public PickerParams(String mimeType, Uri initialDirUri) { this.mimeType = mimeType; this.initialDirUri = initialDirUri; } } @NonNull @Override public Intent createIntent(@NonNull Context context, PickerParams params) { Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); intent.setType(params.mimeType); // 添加初始目录参数 if (params.initialDirUri != null) { intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, params.initialDirUri); } return intent; } @Override public Uri parseResult(int resultCode, @Nullable Intent intent) { if (resultCode == Activity.RESULT_OK && intent != null) { return intent.getData(); } return null; } }
2. 注册并使用自定义Contract
ActivityResultLauncher<OpenDocumentWithInitialDir.PickerParams> mCustomPickerLauncher = registerForActivityResult( new OpenDocumentWithInitialDir(), selectedUri -> { if (selectedUri != null) { // 处理获取到的文件Uri } } ); // 启动选择器,传入MIME类型和初始目录Uri mCustomPickerLauncher.launch( new OpenDocumentWithInitialDir.PickerParams("image/*", MediaStore.Downloads.EXTERNAL_CONTENT_URI) );
补充说明
为什么GetContent不能设置初始目录?看它的源码就能明白,它的createIntent方法是固定构建的,没有预留添加额外参数的接口:
@Override public Intent createIntent(Context context, String input) { return new Intent(Intent.ACTION_GET_CONTENT) .addCategory(Intent.CATEGORY_OPENABLE) .setType(input); }
所以无法通过GetContent直接添加EXTRA_INITIAL_URI,只能用上述两种替代方案。
内容的提问来源于stack exchange,提问作者Coilhac
相关产品推荐
相关产品推荐

