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

如何不使用insertImage()通过MediaStore获取ImageView的Bitmap路径实现分享

适配分区存储的Bitmap分享实现方案

错误原因

你的代码触发空指针的核心原因是:MediaStore.Images.Media.insertImage在Android 10(API 29)及以上版本已正式废弃,受分区存储规则限制,该方法会直接返回null,后续调用Uri.parse(null)就会抛出空指针异常。

实现步骤

1. 配置说明

无需申请额外读写存储权限,仅需确保AndroidManifest.xml中没有声明已过时的WRITE_EXTERNAL_STORAGE等权限(Android 10及以上写入公共媒体目录无需权限)。

2. 完整实现代码

binding.btnShareOne.setOnClickListener {
    val shareIntent = Intent(Intent.ACTION_SEND).apply {
        type = "image/*"
        // 给目标应用临时授予Uri读取权限,必须添加
        addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
    }

    // 从ImageView获取Bitmap
    val bitmap = binding.ivLayoutOne.drawable.toBitmap()
    
    // 构建MediaStore写入参数
    val contentValues = ContentValues().apply {
        put(MediaStore.Images.Media.DISPLAY_NAME, "temp_share_${System.currentTimeMillis()}.png")
        put(MediaStore.Images.Media.MIME_TYPE, "image/png")
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            // 指定存储路径为公共相册下的TempShare目录
            put(MediaStore.Images.Media.RELATIVE_PATH, "${Environment.DIRECTORY_PICTURES}/TempShare")
            // 标记图片为待写入状态,避免写入过程中被其他应用扫描到
            put(MediaStore.Images.Media.IS_PENDING, 1)
        }
    }

    // 插入MediaStore获取Uri
    val contentResolver = contentResolver
    val imageUri = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)

    imageUri?.let { uri ->
        // 将Bitmap写入到Uri对应的输出流
        contentResolver.openOutputStream(uri)?.use { outputStream ->
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream)
        }

        // 写入完成,更新标记允许其他应用访问
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            contentValues.clear()
            contentValues.put(MediaStore.Images.Media.IS_PENDING, 0)
            contentResolver.update(uri, contentValues, null, null)
        }

        // 携带Uri启动分享
        shareIntent.putExtra(Intent.EXTRA_STREAM, uri)
        startActivity(Intent.createChooser(shareIntent, "Share Image"))
    } ?: run {
        // 处理Uri生成失败的情况,可自定义提示
        Toast.makeText(this, "图片分享失败", Toast.LENGTH_SHORT).show()
    }
}

可选优化

如果不需要长期保留分享的临时图片,可以在分享完成后调用contentResolver.delete(imageUri, null, null)删除对应文件,避免占用用户存储空间。

内容的提问来源于stack exchange,提问作者Debayan Ghosh Dastider

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 12:06:01