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

Android 11环境下发送邮件触发java.lang.VerifyError问题求助

解决Android 11下JavaMail的VerifyError问题

这个问题我之前也踩过坑,本质是Android 11引入的包可见性限制和你用的旧版JavaMail依赖不兼容导致的。下面是具体的解决方案:

问题原因

Android 11开始严格限制应用对第三方库内部包的访问权限,而com.sun.mail:android-mail:1.6.0版本比较老旧,没有适配这个新规则,导致系统阻止了com.sun.mail.handlers.text_plain这类内部类的加载,直接抛出了VerifyError。

解决方案

1. 升级JavaMail依赖到适配Android 11的版本

旧版本的JavaMail完全没考虑Android 11的包可见性问题,建议直接升级到最新稳定版(目前推荐1.6.7),修改你的Gradle依赖:

implementation 'com.sun.mail:android-mail:1.6.7'
implementation 'com.sun.mail:android-activation:1.6.7'

2. 在AndroidManifest.xml中添加包可见性声明

Android 11+要求应用明确声明需要访问的第三方包,在AndroidManifest.xml的根标签下添加<queries>标签,允许访问JavaMail的相关内部包:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="your.package.name">

    <!-- 声明需要访问的JavaMail包 -->
    <queries>
        <package android:name="com.sun.mail" />
        <package android:name="com.sun.mail.handlers" />
    </queries>

    <application ...>
        <!-- 你的应用原有配置 -->
    </application>
</manifest>

3. 优化邮件发送的线程等待逻辑(可选但强烈推荐)

你当前代码里用while (!loading[0]) {}自旋等待的方式会死死阻塞主线程,很容易触发ANR(应用无响应)。建议改成回调的方式处理发送结果,示例代码如下:

先定义一个回调接口:

public interface MailSendCallback {
    void onSendSuccess();
    void onSendFailure();
}

然后修改发送方法:

public static void sendEmail(String subject, String content, String[] recipients, MailSendCallback callback) {
    Properties properties = new Properties();
    properties.put("mail.smtp.auth", "true");
    properties.put("mail.smtp.starttls.enable", "true");
    properties.put("mail.smtp.host", "smtp.gmail.com");
    properties.put("mail.smtp.port", "587");

    Session session = Session.getInstance(properties, new Authenticator() {
        @Override
        protected PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication(USERNAME, PASSWORD);
        }
    });

    try {
        Message message = new MimeMessage(session);
        message.setFrom(new InternetAddress(USERNAME));
        InternetAddress[] addressTo = new InternetAddress[recipients.length];
        for (int i = 0; i < recipients.length; i++) {
            addressTo[i] = new InternetAddress(recipients[i]);
        }
        message.setRecipients(Message.RecipientType.TO, addressTo);
        message.setSubject(subject);
        message.setText(content);

        new Thread(() -> {
            try {
                Transport.send(message);
                // 回到主线程通知成功
                new Handler(Looper.getMainLooper()).post(callback::onSendSuccess);
            } catch (MessagingException e) {
                e.printStackTrace();
                new Handler(Looper.getMainLooper()).post(callback::onSendFailure);
            }
        }).start();
    } catch (MessagingException e) {
        e.printStackTrace();
        callback.onSendFailure();
    }
}

调用时可以这样用:

sendEmail("测试邮件", "这是测试内容", new String[]{"test@example.com"}, new MailSendCallback() {
    @Override
    public void onSendSuccess() {
        Toast.makeText(context, "邮件发送成功", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onSendFailure() {
        Toast.makeText(context, "邮件发送失败", Toast.LENGTH_SHORT).show();
    }
});

额外注意事项(Gmail专用)

如果用Gmail作为SMTP服务器:

  • 若账号开启了2FA(双重验证),必须使用应用专用密码代替普通登录密码
  • 若未开启2FA,需要在Google账号设置中临时开启"允许低安全性应用访问"(不推荐长期使用,建议优先启用2FA并使用应用密码)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 13:42:49