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

Android10/11拍照/选图上传服务器 CanHub库onActivityResult返回data为空

问题根因
  • 调用系统相机时未预先指定输出Uri,Android 10及以上版本系统相机默认不会在返回的data中携带图片Uri,直接读取data?.data必然为空
  • onActivityResult逻辑存在明显错误:裁剪结果对应的requestCode固定为CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE,你在该分支下判断requestCode等于GALLERY_REQUEST_CODE或CAMERA_REQUEST_CODE的条件永远不成立,裁剪后逻辑无法正常执行
  • 若未动态申请相机、存储读写权限,也会触发返回数据为空的问题
修复步骤

1. 配置FileProvider用于适配文件访问

首先在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>

在AndroidManifest.xml中添加FileProvider配置:

<provider
    android:name="androidx.core.content.FileProvider"
    android:authorities="${你的应用包名}.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths" />
</provider>

2. 调整相机调用逻辑,预先创建输出Uri

调用相机前先创建待保存的图片文件和对应的Uri,不要依赖系统返回的data获取Uri:

// 全局变量保存相机输出Uri
private var cameraOutputUri: Uri? = null

private fun openCamera() {
    // 创建图片存储文件
    val photoFile = File(
        requireContext().getExternalFilesDir(Environment.DIRECTORY_PICTURES),
        "camera_${System.currentTimeMillis()}.jpg"
    )
    // 生成FileProvider Uri
    cameraOutputUri = FileProvider.getUriForFile(
        requireContext(),
        "${requireContext().packageName}.fileprovider",
        photoFile
    )
    // 启动相机
    val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
    intent.putExtra(MediaStore.EXTRA_OUTPUT, cameraOutputUri)
    // 授予Uri临时访问权限
    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
    startActivityForResult(intent, CAMERA_REQUEST_CODE)
}

3. 修复onActivityResult逻辑

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    when (requestCode) {
        GALLERY_REQUEST_CODE -> {
            if (resultCode == Activity.RESULT_OK) {
                data?.data?.let { uri ->
                    launchImageCrop(uri)
                }
            }
        }
        CAMERA_REQUEST_CODE -> {
            if (resultCode == Activity.RESULT_OK) {
                // 直接用预先创建的cameraOutputUri,不要从data里读取
                cameraOutputUri?.let { uri ->
                    launchImageCrop(uri)
                }
            }
        }
        CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE -> {
            val result = CropImage.getActivityResult(data)
            if (resultCode == Activity.RESULT_OK) {
                // 直接拿裁剪后的Uri转文件即可,不需要转Bitmap避免OOM
                val cropFile = File(result.uri.path)
                viewModel.getUserCardInfo(cropFile)
            } else if (resultCode == CropImage.CROP_IMAGE_ACTIVITY_RESULT_ERROR_CODE) {
                val error = result.error
                Toast.makeText(requireContext(), error.message, Toast.LENGTH_SHORT).show()
            }
        }
    }
}

4. 补充动态权限申请

确保在调用相机/相册前动态申请以下权限:

  • 相机权限:Manifest.permission.CAMERA
  • 存储权限:Android 12及以下申请Manifest.permission.READ_EXTERNAL_STORAGE,Android 13及以上替换为READ_MEDIA_IMAGES

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.20 05:45:05