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

Kotlin Android应用点击分享按钮崩溃:TransactionTooLargeException

问题根源分析

你遇到的TransactionTooLargeException是因为Binder事务传递的数据量超过了Android系统限制(单次Binder事务的大小上限通常在1MB左右)。核心错误出在代码逻辑的两个关键点:

  1. Intent.EXTRA_STREAM参数的用途被误用——它要求传递的是文件的Uri,而不是Base64字符串。
  2. 你的imageViewToPdf返回Base64格式的PDF内容,Base64编码会让数据体积膨胀约30%,再加上扫描文档生成的PDF本身体积不小(日志显示已达5.5MB),直接通过Intent传递超大字符串必然触发事务大小限制。
排查步骤
  1. 确认imageViewToPdf的输出:检查该函数确实返回了Base64字符串而非文件路径/Uri,这是触发崩溃的直接原因。
  2. 验证数据体积:将生成的Base64字符串转为字节数组,计算其长度,会发现远超过1MB的Binder事务上限。
解决思路与代码调整

1. 修改PDF生成逻辑,输出文件而非Base64字符串

让imageViewToPdf生成PDF文件并保存到应用的外部私有存储目录,返回File对象而非字符串:

fun imageViewToPdf(imageView: ImageView): File? {
    // 从ImageView获取Bitmap
    val bitmap = (imageView.drawable as BitmapDrawable).bitmap ?: return null
    // 创建存储PDF的目录与文件
    val docsDir = context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS) ?: return null
    val pdfFile = File(docsDir, "scanned_doc_${System.currentTimeMillis()}.pdf")
    
    // 示例:使用AndroidPdfLibrary将Bitmap写入PDF
    PdfDocument().apply {
        val pageInfo = PdfDocument.PageInfo.Builder(bitmap.width, bitmap.height, 1).create()
        val page = startPage(pageInfo)
        val canvas = page.canvas
        canvas.drawBitmap(bitmap, 0f, 0f, null)
        finishPage(page)
        writeTo(FileOutputStream(pdfFile))
        close()
    }
    return pdfFile.takeIf { it.exists() && it.length() > 0 }
}

2. 使用FileProvider生成可分享的Uri

Android 7.0及以上禁止直接暴露文件Uri,必须通过FileProvider生成安全Uri:

  • 在AndroidManifest.xml中注册FileProvider:
<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">
    <external-files-path name="documents" path="Documents" />
</paths>

3. 修正分享逻辑,传递正确的Uri并授予权限

shareBtn.setOnClickListener {
    val pdfFile = imageViewToPdf(croppedImageView) ?: return@setOnClickListener
    // 生成安全Uri
    val pdfUri = FileProvider.getUriForFile(this, "${packageName}.fileprovider", pdfFile)
    
    val shareIntent = Intent(Intent.ACTION_SEND).apply {
        putExtra(Intent.EXTRA_STREAM, pdfUri)
        type = "application/pdf"
        // 授予接收应用临时读取权限
        addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
    }
    startActivity(Intent.createChooser(shareIntent, "分享扫描文档"))
}

4. 额外优化建议

  • 转PDF前压缩Bitmap:扫描的图片分辨率通常很高,可通过Bitmap.compress()压缩后再写入PDF,进一步减小文件体积。
  • 清理旧文件:每次生成新PDF时,删除目录下的旧文件,避免占用过多存储。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 08:30:44