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

图库选图无法设置到ImageView,拍照触发FileUriExposedException闪退

解决方案

看起来你碰到了两个典型的图片选择/拍照场景问题,我来帮你逐个解决:

1. 修复图库选图后图片不显示问题

图库选图后图片无法显示,大概率是你在处理返回的Uri时没有正确解析成Bitmap,或者缺少必要的读取权限。

步骤1:确保权限配置

在AndroidManifest.xml中添加读取外部存储的权限(如果是Android 10+,可以用android:requestLegacyExternalStorage="true"兼容旧逻辑,或者改用Scoped Storage):

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- Android 10+ 兼容配置 -->
<application
    ...
    android:requestLegacyExternalStorage="true">

步骤2:正确处理图库返回的Uri

如果用AndroidX的registerForActivityResult,可以这么写:

// 初始化图库选择Launcher
val pickImageLauncher = registerForActivityResult(ActivityResultContracts.GetContent()) { uri ->
    uri?.let {
        try {
            // 通过ContentResolver解析Uri获取Bitmap
            val bitmap = MediaStore.Images.Media.getBitmap(contentResolver, it)
            yourImageView.setImageBitmap(bitmap)
        } catch (e: IOException) {
            e.printStackTrace()
            Toast.makeText(this, "图片加载失败", Toast.LENGTH_SHORT).show()
        }
    }
}

// 按钮点击触发图库选择
galleryBtn.setOnClickListener {
    pickImageLauncher.launch("image/*")
}

如果是用旧的startActivityForResult,逻辑类似,在onActivityResult的RESULT_OK分支里做同样的Uri解析即可。

2. 解决拍照时的FileUriExposedException闪退问题

这个错误是Android 7.0(API 24)及以上的安全限制导致的:直接暴露file://格式的Uri给相机应用会被系统拦截,必须用FileProvider生成content://格式的安全Uri。

步骤1:配置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>

步骤2:创建file_paths.xml文件

在res/xml目录下新建file_paths.xml(没有xml目录就自己创建),内容如下:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 指定拍照临时图的存储路径,这里用应用私有外部目录 -->
    <external-files-path
        name="temp_photos"
        path="Pictures/" />
</paths>

这个路径是应用的私有外部存储目录,Android 10+不需要额外申请WRITE权限。

步骤3:修改拍照逻辑,用FileProvider生成Uri

private var tempImagePath: String? = null // 保存临时图片路径

// 创建临时图片文件
private fun createTempImageFile(): File {
    val storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES)
    return File.createTempFile(
        "camera_temp_", /* 文件前缀 */
        ".jpg", /* 文件后缀 */
        storageDir /* 存储目录 */
    ).apply {
        tempImagePath = absolutePath
    }
}

// 拍照Launcher
val takePhotoLauncher = registerForActivityResult(ActivityResultContracts.TakePicture()) { success ->
    if (success && tempImagePath != null) {
        // 拍照成功,加载图片到ImageView
        val bitmap = BitmapFactory.decodeFile(tempImagePath)
        yourImageView.setImageBitmap(bitmap)
    } else {
        Toast.makeText(this, "拍照失败", Toast.LENGTH_SHORT).show()
    }
}

// 拍照按钮点击事件
cameraBtn.setOnClickListener {
    val tempFile = createTempImageFile()
    // 生成content://格式的Uri
    val photoUri = FileProvider.getUriForFile(
        this,
        "${packageName}.fileprovider", // 和Manifest里的authorities保持一致
        tempFile
    )
    takePhotoLauncher.launch(photoUri)
}

额外注意点

  • 如果用旧的startActivityForResult启动相机,需要给Uri添加临时权限:
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
  • Android 13+需要申请READ_MEDIA_IMAGES权限替代READ_EXTERNAL_STORAGE,记得动态申请权限。

把这些修改完成后,你的图库选图和拍照功能应该就能正常工作了!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 03:40:32