使用registerForActivityResult拍照后result.data?.data为null,图片无法显示
解决拍照后ImageView无法显示图片(result.data?.data为null)的问题
相机可正常启动,权限不足时弹窗正常弹出,但拍摄完成后图片无法在ImageView中显示,根源是result.data?.data返回null。
问题原因
当通过intent.putExtra(EXTRA_OUTPUT, imagePath)指定拍照文件的保存路径时,系统不会将图片Uri存入result.data?.data,而是直接将照片写入你指定的文件中,因此此时result.data?.data必然为null。
解决方案
拍照前记录下图片的保存路径,在拍照完成后直接通过该路径加载图片到ImageView。
修改后的代码:
- 保存拍照路径并启动相机的函数:
// 全局变量,存储拍照后的图片路径 private var capturedImagePath: String? = null fun displayCamera(activity: Activity) { val destPath = activity.getExternalFilesDir(null)?.absolutePath ?: return val imagesFolder = File(destPath, activity.resources.getString(R.string.app_name)) try { imagesFolder.mkdirs() val imgFile = File(imagesFolder, Date().time.toString() + ".jpg") capturedImagePath = imgFile.absolutePath // 保存图片路径 val imagePath = FileProvider.getUriForFile( activity, "com.example.shoppinglist.provider", imgFile ) val intent = Intent(ACTION_IMAGE_CAPTURE) intent.putExtra(EXTRA_OUTPUT, imagePath) cameraResult.launch(intent) } catch (e: Exception) { e.printStackTrace() } }
- 处理拍照结果的回调:
private val cameraResult = registerForActivityResult( ActivityResultContracts.StartActivityForResult() ) { result: ActivityResult -> if (result.resultCode == Activity.RESULT_OK) { capturedImagePath?.let { path -> // 通过路径创建Uri并设置到ImageView val imageUri = Uri.fromFile(File(path)) binding.profilepic.setImageURI(imageUri) // 可选:使用Glide等图片加载库优化加载(避免OOM) // Glide.with(this).load(path).into(binding.profilepic) } } }
- 按钮点击逻辑(无需修改):
if (checkPermissions(this@RegistrationActivity)) { displayCamera(this@RegistrationActivity) } else { requestPermission(requestMultiplePermissionLauncher) }
额外注意事项
- 若遇到屏幕旋转等配置变更,
capturedImagePath可能丢失,可通过onSaveInstanceState方法保存路径,在onRestoreInstanceState中恢复。 - Android 10及以上版本中,直接使用
Uri.fromFile可能触发文件访问权限问题,建议通过FileProvider生成内容Uri,或者将图片信息插入MediaStore获取合法Uri。 - 大尺寸图片直接通过
setImageURI加载可能导致内存溢出,推荐使用Glide、Coil等图片加载库进行压缩和缓存优化。
内容的提问来源于stack exchange,提问作者Jayanta Sarkar
相关产品推荐
相关产品推荐

