红米设备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
相关产品推荐
相关产品推荐

