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
相关产品推荐
相关产品推荐

