Kotlin拍照后无法上传图片至Firestore问题求助
问题原因
使用MediaStore.ACTION_IMAGE_CAPTURE时,默认只会通过data.getParcelableExtra("data")返回缩略图Bitmap,不会在data.data中提供图片Uri,所以你拿到的imageUrl为null,导致后续上传失败。要获取拍照后的原图Uri,需要提前指定图片的保存路径。
解决方案
1. 生成拍照图片的保存Uri(适配Android 10+)
创建方法生成图片保存路径,用FileProvider兼容Android 7.0+的文件访问限制:
private fun createImageFileUri(): Uri? { val imageFileName = "JPEG_${System.currentTimeMillis()}_" val storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES) val imageFile = File.createTempFile( imageFileName, ".jpg", storageDir ) return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { FileProvider.getUriForFile( this, "${packageName}.fileprovider", // 需与AndroidManifest中provider的authorities一致 imageFile ) } else { Uri.fromFile(imageFile) } }
2. 声明全局变量保存拍照Uri
在Activity中添加全局变量:
private var cameraImageUri: Uri? = null private val CAMERA_REQUEST_CODE = 100 private val GALLERY_REQUEST_CODE = 101 private var imageUrl: Uri? = null private var userId: String? = null
3. 修改相机启动逻辑
启动相机时,将生成的Uri传入EXTRA_OUTPUT参数:
private fun camera() { val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE) cameraImageUri = createImageFileUri() cameraImageUri?.let { intent.putExtra(MediaStore.EXTRA_OUTPUT, it) startActivityForResult(intent, CAMERA_REQUEST_CODE) } }
4. 更新onActivityResult处理逻辑
拍照成功后直接使用提前保存的cameraImageUri作为图片Uri:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) if (requestCode == CAMERA_REQUEST_CODE) { if (resultCode == Activity.RESULT_OK) { cameraImageUri?.let { uri -> profileImage.setImageURI(uri) imageUrl = uri println("From Camera...$uri") } } } if (requestCode == GALLERY_REQUEST_CODE) { if (resultCode == Activity.RESULT_OK) { imageUrl = data?.data imageUrl?.let { profileImage.setImageURI(it) println("From Gallery...$it") } } } }
5. 配置FileProvider(AndroidManifest.xml)
在application标签内添加FileProvider配置:
<provider android:name="androidx.core.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider>
然后在res/xml目录下创建file_paths.xml文件:
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-files-path name="my_images" path="Pictures" /> </paths>
6. 权限处理
在AndroidManifest.xml中声明所需权限:
<!-- 相机权限 --> <uses-permission android:name="android.permission.CAMERA" /> <!-- Android 9及以下需要存储权限 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="28" />
同时在代码中动态申请相机权限(Android 6.0+),可自行补充权限申请逻辑。
7. 验证上传方法
你的uploadUserImage方法无需修改,现在拍照后的Uri有效,可正常执行上传流程。
内容的提问来源于stack exchange,提问作者Eddie
相关产品推荐
相关产品推荐

