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

Android中使用ACTION_SENDTO发送邮件近期失效问题求助

问题描述

我在Android应用中使用Intent.ACTION_SENDTO向指定邮箱发送邮件,以下代码已上线约5年,一直正常运行,可正确填充收件人、主题及邮件正文:

fun sendEmail() {
    val intent = Intent(Intent.ACTION_SENDTO)
    intent.data = Uri.parse("mailto:")

    intent.putExtra(Intent.EXTRA_EMAIL, arrayOf<String>("myemail@email.com"))
    intent.putExtra(Intent.EXTRA_SUBJECT, "Email Subject here")

    val emailString = "<b>Email Message here</b>"

    if (Build.VERSION.SDK_INT >= 24) {
        intent.putExtra(Intent.EXTRA_TEXT, Html.fromHtml(emailString,Html.FROM_HTML_MODE_LEGACY))
    } else {
        @Suppress("DEPRECATION")
        intent.putExtra(Intent.EXTRA_TEXT, Html.fromHtml(emailString))
    }

    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

近几周收到多位用户反馈,邮件按钮突然失效,点击后无任何反应。

复现步骤:
在Android Studio模拟器上可复现该问题:intent.resolveActivity(packageManager)返回null,导致startActivity(intent)未执行。若去掉判断直接调用startActivity(intent),模拟器会打开预装的Gmail应用,但这属于不良实践,担心生产环境中无邮件应用的用户会遭遇崩溃。

编辑补充:已在运行Android 14的平板上复现该问题,但运行Android 9的手机上按钮功能正常。推测是近期Android更新导致intent.resolveActivity(packageManager)返回null,请问如何解决该问题?

解决方案

问题根源

Android 14(API 34)对隐式Intent的解析逻辑做了收紧调整,针对mailto:这类scheme的Intent,部分邮件应用的Intent过滤声明可能未完全符合新规则,导致resolveActivity()返回null,但实际存在可处理该Intent的应用。

具体解决方法

1. 替换resolveActivity为queryIntentActivities检查

使用packageManager.queryIntentActivities()替代resolveActivity(),它能更准确地找到所有可处理该Intent的应用,避免误判:

fun sendEmail() {
    val intent = Intent(Intent.ACTION_SENDTO)
    intent.data = Uri.parse("mailto:")

    intent.putExtra(Intent.EXTRA_EMAIL, arrayOf<String>("myemail@email.com"))
    intent.putExtra(Intent.EXTRA_SUBJECT, "Email Subject here")

    val emailString = "<b>Email Message here</b>"

    if (Build.VERSION.SDK_INT >= 24) {
        intent.putExtra(Intent.EXTRA_TEXT, Html.fromHtml(emailString,Html.FROM_HTML_MODE_LEGACY))
    } else {
        @Suppress("DEPRECATION")
        intent.putExtra(Intent.EXTRA_TEXT, Html.fromHtml(emailString))
    }

    // 替换原判断逻辑
    val availableActivities = packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY)
    if (availableActivities.isNotEmpty()) {
        startActivity(intent)
    } else {
        // 提示用户无可用邮件应用
        Toast.makeText(this, "未找到可用的邮件应用", Toast.LENGTH_SHORT).show()
    }
}

2. 捕获ActivityNotFoundException直接启动

放弃前置检查,直接调用startActivity()并捕获异常,这种方式更简洁,且能覆盖所有情况:

fun sendEmail() {
    val intent = Intent(Intent.ACTION_SENDTO)
    intent.data = Uri.parse("mailto:")

    intent.putExtra(Intent.EXTRA_EMAIL, arrayOf<String>("myemail@email.com"))
    intent.putExtra(Intent.EXTRA_SUBJECT, "Email Subject here")

    val emailString = "<b>Email Message here</b>"

    if (Build.VERSION.SDK_INT >= 24) {
        intent.putExtra(Intent.EXTRA_TEXT, Html.fromHtml(emailString,Html.FROM_HTML_MODE_LEGACY))
    } else {
        @Suppress("DEPRECATION")
        intent.putExtra(Intent.EXTRA_TEXT, Html.fromHtml(emailString))
    }

    try {
        startActivity(intent)
    } catch (e: ActivityNotFoundException) {
        Toast.makeText(this, "未找到可用的邮件应用", Toast.LENGTH_SHORT).show()
    }
}

3. 优化Intent构造(可选)

将收件人、主题直接嵌入mailto: Uri中,更符合ACTION_SENDTO的规范,部分邮件应用对这种格式的支持更稳定:

fun sendEmail() {
    // 直接将收件人、主题编码后放入mailto Uri
    val subject = Uri.encode("Email Subject here")
    val intent = Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:myemail@email.com?subject=$subject"))

    val emailString = "<b>Email Message here</b>"

    if (Build.VERSION.SDK_INT >= 24) {
        intent.putExtra(Intent.EXTRA_TEXT, Html.fromHtml(emailString,Html.FROM_HTML_MODE_LEGACY))
    } else {
        @Suppress("DEPRECATION")
        intent.putExtra(Intent.EXTRA_TEXT, Html.fromHtml(emailString))
    }

    // 配合上面两种判断方式之一使用
    try {
        startActivity(intent)
    } catch (e: ActivityNotFoundException) {
        Toast.makeText(this, "未找到可用的邮件应用", Toast.LENGTH_SHORT).show()
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 14:47:07