Android Kotlin带PDF附件邮件发送失败问题求助
问题分析与解决方案
核心问题1:FileProvider路径配置不匹配
你使用的<external-files-path>指向应用私有外部存储(路径为/storage/emulated/0/Android/data/[你的包名]/files/),但PDF文件实际存储在公共Documents目录(/storage/emulated/0/Documents/),两者路径范围不重合,导致FileProvider无法生成有效的可访问URI。
修正步骤:修改file_paths.xml
将原配置替换为<external-path>(对应外部存储根目录):
<external-path name="documents" path="Documents/" />
核心问题2:Intent Action选择不适配带附件场景
ACTION_SENDTO主要用于纯文本邮件发送,部分邮件客户端(如Gmail)对该Action处理附件的支持存在缺陷,换成ACTION_SEND更适配带附件的需求。
修正步骤:调整邮件发送代码
private fun envio(nombre :String) { val direcciones = arrayOf(binding.etEnvio.text.toString()) val asunto = "Prueba intent implícito" val texto = "Este es un mensaje de prueba que queremos enviar" val pdfFile = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS), "$nombre.pdf") // 先验证文件是否存在 if (!pdfFile.exists()) { Log.e("ENVIO", "PDF文件不存在:${pdfFile.absolutePath}") return } Log.d("ENVIO", "准备发送PDF:${pdfFile.absolutePath}") val intent = Intent(Intent.ACTION_SEND) // 设置MIME类型,过滤仅邮件应用 intent.type = "message/rfc822" intent.putExtra(Intent.EXTRA_EMAIL, direcciones) intent.putExtra(Intent.EXTRA_SUBJECT, asunto) intent.putExtra(Intent.EXTRA_TEXT, texto) // 生成FileProvider可访问的URI val pdfUri = FileProvider.getUriForFile(this, "com.example.appcamara.fileprovider", pdfFile) intent.putExtra(Intent.EXTRA_STREAM, pdfUri) // 授予邮件客户端临时读取权限 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) startActivity(Intent.createChooser(intent, "Elige cliente de correo:")) }
额外验证项
动态权限申请:Android 6.0(API 23)及以上版本,
WRITE_EXTERNAL_STORAGE和READ_EXTERNAL_STORAGE需要动态申请,确保代码中已处理权限请求:private fun requestStoragePermissions() { if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), 1001) } }文件生成有效性:确认
pdf()函数确实将文件写入了公共Documents目录,可通过手机文件管理器手动检查对应路径是否存在目标PDF。Android 10+适配:Android 10(API 29)及以上版本,若坚持使用
File类操作公共目录,需在AndroidManifest.xml的<application>标签中添加:android:requestLegacyExternalStorage="true"(该配置仅适用于API 29-30,Android 11及以上建议使用
MediaStoreAPI或申请MANAGE_EXTERNAL_STORAGE权限)
内容的提问来源于stack exchange,提问作者Hugo Jiménez
相关产品推荐
相关产品推荐

