Java转Kotlin后调用相机拍照报错问题排查
结合你提供的代码片段和Android开发中Java转Kotlin的常见坑,导致拍照报错的原因通常集中在以下几个方面:
可空类型的强制非空滥用:
Kotlin对空安全的严格要求是和Java最大的区别之一。在Java中你可能直接使用File photoFile = createImageFile();,即使createImageFile()返回null也可能靠后续逻辑容错,但转Kotlin后如果写成:var photoFile: File = createImageFile() // 这里如果createImageFile抛出IO异常或返回null,直接崩溃或者后续用
photoFile!!强制非空,一旦createImageFile()因为存储权限不足、存储目录不可用等原因返回null,就会直接抛出NullPointerException。正确的做法应该是用可空类型+非空判断:var photoFile: File? = try { createImageFile() } catch (ex: IOException) { // 打印异常或提示用户存储错误 null } photoFile?.let { file -> // 后续处理相机Intent和Uri }FileProvider Uri生成的空指针问题:
Android 7.0及以上必须用FileProvider生成content://格式的Uri来替代file://。转Kotlin时如果没有对photoFile做非空校验就直接生成Uri:val photoURI = FileProvider.getUriForFile(this, "your.provider.authority", photoFile!!)一旦
photoFile为null,这里就会直接崩溃。必须先确保photoFile不为空再执行Uri生成逻辑。动态权限处理的疏漏:
相机和存储权限属于危险权限,需要动态申请。Java转Kotlin时,可能没有正确实现权限请求的回调逻辑,比如onRequestPermissionsResult的处理。如果权限被用户拒绝,调用相机Intent时会直接失败,甚至抛出SecurityException。Kotlin中应该在调用相机前先检查权限:if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { // 启动相机Intent } else { ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE), REQUEST_PERMISSIONS_CODE) }配置变化导致的文件路径丢失:
当Activity因屏幕旋转等配置变化重建时,photoFile的引用会丢失,导致onActivityResult中无法找到拍摄的图片。Java中你可能通过onSaveInstanceState保存文件路径,但转Kotlin时如果没有正确恢复这个路径(比如没处理savedInstanceState为null的情况),就会导致后续处理图片时找不到文件。UCrop初始化的参数错误:
虽然ucrop:2.2.1-native兼容Kotlin,但转Kotlin时可能在传递Uri给UCrop时没有处理可空性。比如如果拍摄后的图片Uri为null,直接传入UCrop的of()方法就会报错。需要确保Uri非空后再启动UCrop:photoURI?.let { uri -> UCrop.of(uri, destinationUri) .withAspectRatio(1f, 1f) .start(this) }
内容的提问来源于stack exchange,提问作者Akhil T Mohan

