如何兼容Android 10及以下版本用Kotlin实现向WhatsApp分享图片
原代码报错核心原因
Intent.EXTRA_STREAM参数要求传入*内容URI(Content URI)*类型的数据,你传入的ByteArray无法被第三方应用(比如WhatsApp)识别解析- Android 10开始分区存储正式落地,旧的公共存储写入API
MediaStore.Images.Media.insertImage被废弃,旧版本的分享逻辑不再适用。
前置配置:注册FileProvider
要向外部应用分享私有目录文件,需要先配置FileProvider完成授权,首先在AndroidManifest.xml的<application>标签中添加如下配置:
<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>
接着在res/xml目录下新建file_paths.xml,声明允许分享的目录路径:
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 对应应用内部缓存目录的images子目录 --> <cache-path name="shared_images" path="images/" /> </paths>
Android 10+ 适配的分享逻辑(Kotlin)
无需申请任何存储权限,直接将Bitmap存入应用私有缓存目录后生成授权URI分享即可,适配全系统版本:
btnSocialMedia.setOnClickListener { bitmapCreated?.let { bitmap -> try { // 1. 将Bitmap写入应用私有缓存目录 val imageCacheDir = File(cacheDir, "images") if (!imageCacheDir.exists()) imageCacheDir.mkdirs() val targetImageFile = File(imageCacheDir, "share_${System.currentTimeMillis()}.png") val outputStream = FileOutputStream(targetImageFile) bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream) outputStream.flush() outputStream.close() // 2. 生成FileProvider授权的Content URI val shareUri = FileProvider.getUriForFile( this, "${packageName}.fileprovider", // 和Manifest中配置的authorities保持一致 targetImageFile ) // 3. 构造分享意图 val shareIntent = Intent(Intent.ACTION_SEND).apply { type = "image/*" putExtra(Intent.EXTRA_STREAM, shareUri) // 可选配置:要直接唤起WhatsApp可添加下行,未安装WhatsApp会自动降级到系统分享选择器 setPackage("com.whatsapp") // 给目标应用授予URI临时读取权限 addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) } // 4. 启动分享 startActivity(Intent.createChooser(shareIntent, "分享照片")) } catch (e: Exception) { e.printStackTrace() // 可自行添加异常提示逻辑,比如未安装WhatsApp、存储异常等 } } ?: run { // 自行处理Bitmap为空的情况 } }
注意事项
- 如果需要将图片持久化保存到公共相册,也可以通过MediaStore新API插入到公共
Pictures目录获取URI后再分享,无需使用FileProvider。 - 该逻辑完全符合Android 10+分区存储规则,不需要申请任何存储权限。
内容的提问来源于stack exchange,提问作者MilkBottle
相关产品推荐
相关产品推荐

