Android Kotlin中如何通过Intent使用Bitmap分享图片?
Android Kotlin中如何通过Intent使用Bitmap分享图片?
嗨,我来帮你解决这个Bitmap分享的问题!你遇到的URI权限问题其实是Android权限机制里的常见坑,下面给你一步步讲正确的实现方式,确保其他应用能正常访问到你的图片:
核心思路
从Android 7.0(API 24)开始,系统禁止跨应用直接传递file://格式的URI,会抛出FileUriExposedException。正确的做法是用FileProvider生成content://格式的URI,并给目标应用临时的读取权限,这样就能安全地分享图片了。
具体实现步骤
1. 配置FileProvider
首先在AndroidManifest.xml里注册FileProvider,它是Android官方提供的用于安全共享文件的组件:
<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> ... </application>
这里的authorities建议用你的应用包名加上.fileprovider,避免和其他应用冲突;exported必须设为false(FileProvider不需要对外暴露);grantUriPermissions设为true才能允许临时授权。
2. 创建文件路径配置文件
在res/xml目录下新建file_paths.xml(没有xml目录就自己创建),用来指定允许共享的文件目录——既然你之前是存在缓存里的,就配置缓存路径:
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <!-- path="."表示允许共享整个缓存目录下的文件 --> <cache-path name="shared_images" path="." /> </paths>
3. 编写Kotlin分享函数
下面是完整的分享Bitmap的工具函数,包含写入缓存、生成授权URI、创建Intent的全流程:
import android.content.Context import android.content.Intent import android.graphics.Bitmap import android.graphics.Bitmap.CompressFormat import android.net.Uri import androidx.core.content.FileProvider import java.io.File import java.io.FileOutputStream import java.io.IOException fun shareBitmap(bitmap: Bitmap, context: Context) { // 1. 创建缓存文件,用时间戳命名避免重复 val cacheFile = File(context.cacheDir, "shared_img_${System.currentTimeMillis()}.png") try { // 2. 将Bitmap写入缓存文件 FileOutputStream(cacheFile).use { outputStream -> bitmap.compress(CompressFormat.PNG, 100, outputStream) outputStream.flush() } } catch (e: IOException) { e.printStackTrace() return // 写入失败直接返回 } // 3. 通过FileProvider生成可安全共享的content:// URI val authority = "${context.packageName}.fileprovider" val imageUri = FileProvider.getUriForFile(context, authority, cacheFile) // 4. 构建分享Intent val shareIntent = Intent(Intent.ACTION_SEND).apply { type = "image/png" // 对应图片格式 putExtra(Intent.EXTRA_STREAM, imageUri) // 关键:给接收应用临时读取该URI的权限 addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) } // 5. 启动选择器让用户选分享应用 context.startActivity(Intent.createChooser(shareIntent, "选择分享应用")) }
你之前可能缺失的关键步骤
- 没用到FileProvider:直接传递
file://URI会触发权限拒绝,Android 7.0+禁止跨应用暴露私有文件路径; - 漏加临时读取权限:
FLAG_GRANT_READ_URI_PERMISSION是必须的,没有它接收应用会因权限不足读不到图片。
额外小提示
- 要分享JPG格式的话,把压缩格式改成
CompressFormat.JPEG,同时将Intent的type设为"image/jpeg"即可; - 缓存文件会被系统在缓存不足时自动清理,无需手动删除;如果想更严谨,也可以在分享完成后手动清理(需要结合生命周期处理);
- 这套方案完全兼容Android 10+的Scoped Storage,不需要申请额外存储权限。
备注:内容来源于stack exchange,提问作者Lily Monta
相关产品推荐
相关产品推荐

