使用FileProvider存图后,调用ThumbnailUtils生成缩略图报文件找不到异常
问题分析
你遇到的java.io.FileNotFoundException异常,核心原因是传递给ThumbnailUtils.createImageThumbnail的路径并非真实的文件系统路径:
- 你在拍照结果中传递的是
imageURI.toString(),这是一个content://开头的Content Uri,而非本地文件的绝对路径; - 当你把这个Uri字符串传入
File(imagePath)时,系统会把它当作文件路径去查找,自然找不到对应的文件,抛出异常。
而ImageView.setImageURI(imageURI)能正常显示,是因为ImageView支持直接通过Content Uri加载内容,不需要访问真实文件路径。
解决方案
以下两种方案都可以解决问题,根据你的需求选择:
方案一:传递真实文件路径(兼容所有Android版本)
在启动拍照时,先保存创建的临时文件的绝对路径,结果回调时直接用该路径生成缩略图:
步骤1:保存文件路径
在启动拍照的代码中,添加变量存储文件路径:
// 定义成员变量或ViewModel变量存储路径 private var photoAbsolutePath: String? = null // 启动拍照的代码 val photoFile = File.createTempFile( "IMG_", ".jpg", requireContext().getExternalFilesDir(Environment.DIRECTORY_PICTURES) ) photoAbsolutePath = photoFile.absolutePath // 保存真实路径 val uri = FileProvider.getUriForFile( requireContext(), "${requireContext().packageName}.fileprovider", photoFile ) sampleActivityRes.launch(uri)
步骤2:使用真实路径生成缩略图
在结果回调中,用保存的路径调用生成方法:
val sampleActivityRes = registerForActivityResult(TakePictureWithUriReturnContract()) { (isSuccess, imageURI) -> if (isSuccess) { binding.sampleImage.setImageURI(imageURI) photoAbsolutePath?.let { path -> val thumbnail = generateImageThumbnail(path) // 使用缩略图 } } }
你的generateImageThumbnail方法无需修改,此时传入的是真实文件路径,能正常找到文件。
方案二:直接使用Content Uri生成缩略图(Android 10+)
Android 10及以上版本的ThumbnailUtils提供了直接接收Content Uri的重载方法,无需转换为文件路径:
修改缩略图生成方法
private fun generateImageThumbnail(context: Context, imageUri: Uri): Bitmap? { val THUMB_SIZE = 64 val cancellationToken = CancellationSignal() return ThumbnailUtils.createImageThumbnail( imageUri, Size(THUMB_SIZE, THUMB_SIZE), cancellationToken ) }
调用方法
在结果回调中直接传入imageURI:
val sampleActivityRes = registerForActivityResult(TakePictureWithUriReturnContract()) { (isSuccess, imageURI) -> if (isSuccess) { binding.sampleImage.setImageURI(imageURI) val thumbnail = generateImageThumbnail(requireContext(), imageURI) // 使用缩略图 } }
额外注意事项
- 检查
FileProvider的authorities一致性:启动代码中你用了${requireContext().packageName}.fileprovider,但Manifest中是com.android.tripmemory.fileprovider,确保两者完全一致,否则会导致拍照失败或Uri解析错误; - 临时文件的清理:拍照完成后,若不再需要原始文件,记得及时删除,避免占用存储空间。
内容的提问来源于stack exchange,提问作者Sanjay Kapilesh
相关产品推荐
相关产品推荐

