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

红米设备Intent.createChooser分享图片无应用选项问题

红米设备Intent.createChooser分享图片无应用选项问题

问题现象

开发过程中先将图片保存至设备外部存储,随后通过Intent.putExtra(Intent.EXTRA_STREAM, uri)传入对应图片URI,设置MIME类型为image/jpg,再调用Intent.createChooser发起分享。该逻辑在其他品牌安卓设备上均可正常运行,但在红米设备上,图片虽成功存储,却无法弹出包含社交媒体应用的分享选择菜单。

复现信息

实现流程为:首先调用shareImage方法,在该方法内部调用saveMediaToStorage方法获取图片URI,红米设备上的异常表现:
异常运行截图
原有实现代码如下:

var finalUri: Uri?=null
var fos: OutputStream? = null
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
    requireContext().contentResolver?.also { resolver ->
        val contentValues = ContentValues().apply {
            put(MediaStore.MediaColumns.DISPLAY_NAME, filename)
            put(MediaStore.MediaColumns.MIME_TYPE, "image/jpg")
            put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES)
        }
        val imageUri: Uri? = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)
        finalUri=imageUri
        fos = imageUri?.let { resolver.openOutputStream(it) }
    }
} else {
    val imagesDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
    val image = File(imagesDir, filename)
    finalUri= FileProvider.getUriForFile(requireContext(),"${requireContext().packageName}.provider",image)
        //image.toUri()
    fos = FileOutputStream(image)
}
fos?.use {
    bitmap?.compress(Bitmap.CompressFormat.JPEG, 100, it)
    it.close()
}

return finalUri
}

private fun shareImage() {

    Glide.with(requireContext())
        .asBitmap()
        .load(badge?.image)
        .into(object : CustomTarget<Bitmap>() {
            override fun onResourceReady(
                resource: Bitmap,
                transition: Transition<in Bitmap>?
            ) {

               val uri= saveMediaToStorage(resource,"${badge?.name}.jpg")
                val shareIntent = Intent()
                shareIntent.putExtra(
                    Intent.EXTRA_TEXT,
                    "${badge?.name} \n\nLorem ipsum dolor sit amet. Quo alias fuga vel rerum quod ad voluptatem debitis?"
                )
                shareIntent.action = Intent.ACTION_SEND
                shareIntent.putExtra(Intent.EXTRA_STREAM, uri)
                shareIntent.type = "image/jpg"
                startActivity(Intent.createChooser(shareIntent,  "Share Badge via..."))

            }

            override fun onLoadCleared(placeholder: Drawable?) {
            }
        })

}

问题原因

MIUI系统对分享Intent的校验规则比原生安卓更严格,现有代码存在三个触发MIUI过滤应用的问题:

  • MIME类型配置错误:标准JPEG格式图片的官方MIME类型为image/jpeg,image/jpg是非标准写法,MIUI会严格匹配MIME类型,错误类型会导致系统检索不到支持的应用。
  • 缺少Uri临时访问权限:通过MediaStore、FileProvider生成的分享Uri,没有给Intent添加FLAG_GRANT_READ_URI_PERMISSION标记时,MIUI会直接拦截其他应用对该Uri的读取请求,所有无法读取图片的应用都会被系统从分享列表中过滤。
  • 未配置ClipData:部分MIUI版本不会主动从EXTRA_STREAM中提取Uri生成ClipData,缺少ClipData的分享Intent会被判定为无效内容,过滤所有应用选项。

修复方案

修改分享Intent的配置逻辑,修正后的代码如下:

// 替换原有shareIntent的初始化逻辑
val shareIntent = Intent(Intent.ACTION_SEND).apply {
    // 修正为标准JPEG MIME类型
    type = "image/jpeg"
    putExtra(Intent.EXTRA_TEXT, "${badge?.name} \n\nLorem ipsum dolor sit amet. Quo alias fuga vel rerum quod ad voluptatem debitis?")
    putExtra(Intent.EXTRA_STREAM, uri)
    // 授予接收方临时读取Uri的权限
    addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
    // 主动设置ClipData,适配MIUI特殊校验逻辑
    clipData = ClipData.newUri(requireContext().contentResolver, "share_badge", uri)
}
startActivity(Intent.createChooser(shareIntent, "Share Badge via..."))

额外校验项

  • 检查AndroidManifest.xml中FileProvider的路径配置,确保Android Q以下版本的配置包含Pictures目录的访问授权,避免低版本MIUI读取文件失败。
  • 如果需要兼容更多图文混合分享场景,可将MIME类型临时设置为*/*,但优先使用image/jpeg可以过滤掉不相关的应用选项,体验更好。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 18:06:25