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

Kotlin中如何使用Intent实现图片分享到其他应用的功能

你当前代码报错的核心原因是:调用系统相机拍照未指定输出路径时,返回的Intent中data?.data为null,仅在extra中携带低分辨率缩略图Bitmap,你传入空Uri到分享Intent自然触发错误。

前置配置(必须)

1. 清单文件配置

在AndroidManifest.xml中添加如下配置:

<!-- 存储权限,Android 13及以上无需WRITE_EXTERNAL_STORAGE -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />

<application ...>
    <!-- FileProvider配置,7.0及以上共享文件必须 -->
    <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>

2. FileProvider路径配置

在res目录下新建xml文件夹,创建file_paths.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-files-path name="my_images" path="Pictures" />
    <external-path name="external_files" path="."/>
</paths>
完整功能代码
import android.content.Intent
import android.graphics.Bitmap
import android.net.Uri
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.provider.MediaStore
import android.widget.Button
import android.widget.ImageView
import android.widget.Toast
import androidx.core.content.FileProvider
import java.io.File
import java.io.FileOutputStream
import java.io.OutputStream

class MainActivity : AppCompatActivity() {
    private lateinit var iv: ImageView
    private lateinit var shareBtn: Button
    private var currentImageBitmap: Bitmap? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val takePhotoBtn = findViewById<Button>(R.id.btn)
        iv = findViewById(R.id.iV)
        shareBtn = findViewById(R.id.Share)

        // 拍照按钮逻辑
        takePhotoBtn.setOnClickListener{
            val takePhotoIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
            startActivityForResult(takePhotoIntent, 1)
        }

        // 分享按钮逻辑
        shareBtn.setOnClickListener {
            currentImageBitmap?.let { bitmap ->
                shareImage(bitmap)
            } ?: run {
                Toast.makeText(this, "请先拍摄图片", Toast.LENGTH_SHORT).show()
            }
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if(resultCode == RESULT_OK && requestCode == 1 && data != null){
            // 获取缩略图Bitmap
            val imageBitmap = data.extras?.get("data") as Bitmap
            currentImageBitmap = imageBitmap
            iv.setImageBitmap(imageBitmap)
        }
    }

    // 核心分享方法
    private fun shareImage(bitmap: Bitmap) {
        // 先将Bitmap保存到本地获取Uri
        val imageUri = saveBitmapToFile(bitmap) ?: return

        val shareIntent = Intent(Intent.ACTION_SEND)
        shareIntent.type = "image/*"
        // 给第三方应用授予Uri读取权限
        shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
        shareIntent.putExtra(Intent.EXTRA_STREAM, imageUri)
        // 避免没有可处理应用崩溃
        if (shareIntent.resolveActivity(packageManager) != null) {
            startActivity(Intent.createChooser(shareIntent, "分享图片到"))
        } else {
            Toast.makeText(this, "没有可处理分享的应用", Toast.LENGTH_SHORT).show()
        }
    }

    // 将Bitmap保存为文件并返回可共享的Uri
    private fun saveBitmapToFile(bitmap: Bitmap): Uri? {
        return try {
            val imagesFolder = File(getExternalFilesDir(null), "Pictures")
            if (!imagesFolder.exists()) imagesFolder.mkdirs()
            val imageFile = File(imagesFolder, "share_image_${System.currentTimeMillis()}.jpg")

            val outputStream: OutputStream = FileOutputStream(imageFile)
            bitmap.compress(Bitmap.CompressFormat.JPEG, 90, outputStream)
            outputStream.flush()
            outputStream.close()

            // 生成可共享的FileProvider Uri
            FileProvider.getUriForFile(this, "${packageName}.fileprovider", imageFile)
        } catch (e: Exception) {
            e.printStackTrace()
            Toast.makeText(this, "图片保存失败", Toast.LENGTH_SHORT).show()
            null
        }
    }
}
关键改动说明
  • 提前保存ImageView展示的Bitmap,不依赖拍照返回的空Uri
  • 采用官方推荐的FileProvider生成可跨应用访问的Uri,替换不安全的StrictMode绕过方案
  • 给分享Intent添加读取权限标记,避免第三方应用无法访问图片
  • 增加异常兜底逻辑,避免无处理应用时崩溃

内容的提问来源于stack exchange,提问作者Divyanshu Dobriyal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.08 12:12:01