You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 02:15:36