通过Intent传递数据至onActivityResult遇阻:PDF保存问题求助
问题描述
尝试将PDF文件保存到用户选择的位置,但在通过Intent传递数据时遇到问题。试过用Bundle传递信息,但始终为null,仅在save方法中定义局部变量并赋值时可行,但希望通过Intent传递数据。需要说明的是,并未跳转至其他Activity,仅选择目录后返回。
代码如下:
protected void save(byte[] bytes, String fileName, String mimeType) { Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT); intent.setType(mimeType); intent.addCategory(Intent.CATEGORY_OPENABLE); intent.putExtra(Intent.EXTRA_TITLE, fileName); intent.putExtra("bytes", bytes); activityResultLaunch.launch(intent); } ActivityResultLauncher<Intent> activityResultLaunch = registerForActivityResult( new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() { @Override public void onActivityResult(ActivityResult result) { Intent data = result.getData(); try { Uri uri = data.getData(); OutputStream outputStream = getContext().getContentResolver().openOutputStream(uri); // 此处始终为null //byte[] bytes = data.getByteArrayExtra("bytes"); outputStream.write(bytes); outputStream.close(); Toast.makeText(getContext(), "Successfully saved document to device!", Toast.LENGTH_SHORT).show(); } catch (IOException e) { Toast.makeText(getContext(), "Failed to save document to device.", Toast.LENGTH_SHORT).show(); e.printStackTrace(); } } });
解决建议
- 核心原因:
Intent.ACTION_CREATE_DOCUMENT调用的是系统内置的文件保存选择器,这个组件只会返回用户选择的文件Uri,不会将你传入的extra参数回传。你通过intent.putExtra("bytes", bytes)传入的数据,系统选择器不会保留,自然在回调里拿不到。 - 可行方案1:将byte数组设为类成员变量
在你的类中定义成员变量存储byte数组,在save方法中赋值,回调里直接使用:private byte[] mSaveBytes; // 类成员变量 protected void save(byte[] bytes, String fileName, String mimeType) { mSaveBytes = bytes; // 赋值给成员变量 Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT); intent.setType(mimeType); intent.addCategory(Intent.CATEGORY_OPENABLE); intent.putExtra(Intent.EXTRA_TITLE, fileName); activityResultLaunch.launch(intent); } ActivityResultLauncher<Intent> activityResultLaunch = registerForActivityResult( new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() { @Override public void onActivityResult(ActivityResult result) { Intent data = result.getData(); try { Uri uri = data.getData(); OutputStream outputStream = getContext().getContentResolver().openOutputStream(uri); outputStream.write(mSaveBytes); // 使用成员变量 outputStream.close(); Toast.makeText(getContext(), "Successfully saved document to device!", Toast.LENGTH_SHORT).show(); } catch (IOException e) { Toast.makeText(getContext(), "Failed to save document to device.", Toast.LENGTH_SHORT).show(); e.printStackTrace(); } finally { mSaveBytes = null; // 用完及时释放避免内存泄漏 } } }); - 可行方案2:使用final局部变量(适用于单个保存场景)
如果save方法调用后不会被多次覆盖数据,可以在save方法中用final修饰byte数组,让内部回调类可以访问:protected void save(final byte[] bytes, String fileName, String mimeType) { Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT); intent.setType(mimeType); intent.addCategory(Intent.CATEGORY_OPENABLE); intent.putExtra(Intent.EXTRA_TITLE, fileName); activityResultLaunch.launch(intent); } // 回调中直接使用bytes变量即可,因为它是final修饰的 - 注意事项:如果byte数组体积很大(比如超过几十MB),建议先将数据写入临时文件,再将临时文件复制到用户选择的Uri位置,避免内存占用过高导致OOM。
内容的提问来源于stack exchange,提问作者Dazai
相关产品推荐
相关产品推荐

