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

CameraX拍照报错:Invalid URI导致图片损坏问题求助

解决CameraX拍照时Invalid URI导致的图片损坏异常

问题根源

你代码里提前调用contentResolver.insert创建了一个空的MediaStore图片条目,随后CameraX的OutputFileOptions又尝试基于这个已存在的URI执行插入操作,触发了UnsupportedOperationException: Invalid URI,同时这个提前创建的空条目会在图库中显示为损坏图片。

修复方案

移除提前插入MediaStore的逻辑,让CameraX负责创建MediaStore条目并写入图片内容,具体修改如下:

修改后的代码

private fun takePhoto(specPic: String, context: Context, controller: LifecycleCameraController, onPhotoTaken: (Uri) -> Unit){
    val contentResolver = context.contentResolver
    val contentValues = ContentValues().apply {
        val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
        val current = LocalDateTime.now().format(formatter)
        put(MediaStore.MediaColumns.DISPLAY_NAME, specPic + "_$current")
        put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg")
        put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES)
    }

    // 直接基于ContentValues创建OutputFileOptions,无需提前插入URI
    val outputFileOptions = OutputFileOptions.Builder(
        contentResolver,
        MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
        contentValues
    ).build()

    controller.takePicture(outputFileOptions, ContextCompat.getMainExecutor(context), object : ImageCapture.OnImageSavedCallback {
        override fun onImageSaved(outputFileResults: ImageCapture.OutputFileResults) {
            outputFileResults.savedUri?.let { savedUri ->
                onPhotoTaken(savedUri)
            }
        }

        override fun onError(exception: ImageCaptureException) {
            Log.e("Camera", "Couldn't take photo:", exception)
        }
    })
}

关键修改点

  • 删除了val uri = contentResolver.insert(...)这行提前创建空条目的代码
  • 调整OutputFileOptions.Builder的参数:直接传入MediaStore.Images.Media.EXTERNAL_CONTENT_URI和contentValues,让CameraX完成从创建条目到写入图片的完整流程
  • 简化onImageSaved中的空判断逻辑

额外注意事项

  • 权限处理:Android 10(API 29)及以上版本,使用MediaStore保存图片无需WRITE_EXTERNAL_STORAGE权限;Android 9及以下版本仍需申请该权限
  • 文件名冲突:如果需要避免文件名重复,可以在DISPLAY_NAME中加入唯一标识(比如UUID)

内容的提问来源于stack exchange,提问作者Joelskoldator123

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 07:16:28