Android应用使用JavaMail API无法发邮件,Transport.send方法阻塞
问题解决方案
1 修复Network Security Config报错
- 在
res/xml目录下新建network_security_config.xml文件,写入以下内容:
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config cleartextTrafficPermitted="false"> <domain includeSubdomains="true">smtp.gmail.com</domain> </domain-config> </network-security-config>
- 打开
AndroidManifest.xml,在application标签中增加配置,关联上面的安全文件:
<application ... android:networkSecurityConfig="@xml/network_security_config" ...>
- 确认
AndroidManifest.xml中已添加网络权限,没有的话在manifest根标签下添加:
<uses-permission android:name="android.permission.INTERNET" />
2 解决Transport.send阻塞无报错问题
- 你当前仅捕获了
MessagingException,其他类型的异常会被直接吞掉,导致无报错信息,修改doInBackground中的异常捕获逻辑:
try { // 原有发送逻辑 Transport.send(mm); } catch (MessagingException e) { e.printStackTrace(); } catch (Exception e) { // 捕获其他所有异常,方便排查 e.printStackTrace(); }
- 给SMTP会话添加超时配置,避免无限阻塞,在Properties配置段增加以下参数:
props.put("mail.smtp.connectiontimeout", "10000"); // 连接超时10秒 props.put("mail.smtp.timeout", "15000"); // 数据传输超时15秒 props.put("mail.smtp.writetimeout", "10000"); // 写入超时10秒
3 修复Gmail账号登录权限问题
谷歌目前已禁止普通第三方应用直接使用账号原密码登录Gmail,需要做如下调整:
- 给你的Gmail账号开启两步验证
- 在谷歌账号安全中心生成应用专用密码,将
Config.PASSWORD替换为生成的应用专用密码,不要使用原账号登录密码 - 正式发布应用时不要在代码中硬编码账号密码,需使用安全的加密存储方案
4 可选优化
AsyncTask在Android 11及以上版本已被废弃,后续可替换为协程(Coroutine)或WorkManager实现后台邮件发送逻辑。
内容的提问来源于stack exchange,提问作者AlessandroF
相关产品推荐
相关产品推荐

