使用FileProvider保存高清图片遇onActivityResult数据为空及路径错误
问题1:FileProvider路径配置错误导致
IllegalArgumentException 你的报错源于provider_path.xml的路径配置未覆盖图片文件所在目录。你通过ContextWrapper.getDir(IMAGE_DIRECTORY, Context.MODE_PRIVATE)创建的目录路径为/data/data/com.bkoubik.longlesstime/app_long_less/,当前配置的<root-path name="root" path="." />在部分Android版本中无法正确映射该私有目录,或存在权限限制。
修正方案:
推荐改用外部私有存储目录(兼容性更强),同时调整路径配置:
- 修改
createImageFile函数:
private fun createImageFile(): File { val photoRoot = requireContext().getExternalFilesDir(Environment.DIRECTORY_PICTURES) ?: throw IOException("无法获取外部存储目录") val targetDir = File(photoRoot, IMAGE_DIRECTORY) if (!targetDir.exists()) targetDir.mkdirs() return File(targetDir, "${UUID.randomUUID()}.jpg") }
- 更新
provider_path.xml:
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-files-path name="long_less_images" path="Pictures/long_less" /> </paths>
若坚持使用内部私有目录,可修改provider_path.xml为:
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <files-path name="long_less" path="../app_long_less/" /> </paths>
问题2:
onActivityResult中data为null的问题 这是正常行为:当通过MediaStore.EXTRA_OUTPUT指定图片保存路径后,相机应用不会将图片数据放入返回的Intent(即data为null),而是直接将照片写入你预先指定的文件。
修正方案:
在Fragment中添加成员变量保存创建的文件对象,直接通过该对象访问图片:
private var currentPhotoFile: File? = null // 成员变量存储文件 fun capturePhoto(){ val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE) currentPhotoFile = createImageFile() // 保存文件引用 val photoURI = FileProvider.getUriForFile( requireActivity(), "com.bkoubik.longlesstime.fileprovider", currentPhotoFile!! ) intent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI) startActivityForResult(intent, IMAGE_REQUEST) } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) if(requestCode == IMAGE_REQUEST && resultCode == Activity.RESULT_OK) { currentPhotoFile?.let { file -> // 此处处理图片,例如加载到ImageView // val bitmap = BitmapFactory.decodeFile(file.absolutePath) // imageView.setImageBitmap(bitmap) } } }
额外优化建议
若使用AndroidX库,建议将AndroidManifest中provider的meta-data名称统一为AndroidX规范:
<meta-data android:name="androidx.core.content.FileProvider.PATH" android:resource="@xml/provider_path"/>
内容的提问来源于stack exchange,提问作者Captai-N
相关产品推荐
相关产品推荐

