如何使用安卓+qq邮箱发送邮件

前言
前段时间由于项目的需要,就是在Android应用里的用户反馈功能需要当用户输入反馈的文本信息后,用户点击提交按钮自动把反馈的文本信息已发送邮件的形式发送给开发者。

要实现这个功能,首先需要两个邮箱账号,一个是发送方的邮箱地址,一个是接收方的邮箱地址。还需要发送方的邮箱授权码(授权码一般是16位的字符串,生成后一般用于客户端的登录,下文会讲如何在登录网页版的邮箱自动生成授权码)、发送方的邮箱服务器(比如QQ邮箱的服务器为:smtp.qq.com)、发送方的邮箱端口号(比如QQ邮箱的端口号为:587)。这些流程都完成后就可以进行编码的操作了。

在开始编码之前首先在AndroidStudio的build.gradle的dependencies模块里引入实现发送邮箱相关的依赖库。

dependencies {...implementation 'com.sun.mail:android-mail:1.5.5'implementation 'com.sun.mail:android-activation:1.5.5'
}

然后在AndroidStudio的清单文件AndroidManifest.xml里添加访问网络相关权限。

    <uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

下面就正式进入编码的操作流程。

新建一个SendMailUtil.java工具类

package com.example.Email;import androidx.annotation.NonNull;import java.io.File;public class SendMailUtil {public static void send(final File file, String toAdd) {final MailInfo mailInfo = creatMail(toAdd);final MailSender sms = new MailSender();new Thread(new Runnable() {@Overridepublic void run() {sms.sendFileMail(mailInfo, file);}}).start();}public static void send(String toAdd) {final MailInfo mailInfo = creatMail(toAdd);final MailSender sms = new MailSender();new Thread(new Runnable() {@Overridepublic void run() {sms.sendTextMail(mailInfo);}}).start();}@NonNullprivate static MailInfo creatMail(String toAdd) {final MailInfo mailInfo = new MailInfo();mailInfo.setMailServerHost("smtp.qq.com");//发送方邮箱服务器mailInfo.setMailServerPort("587");//发送方邮箱端口号mailInfo.setValidate(true);mailInfo.setUserName("发送者邮箱地址"); // 发送者邮箱地址mailInfo.setPassword("发送者邮箱授权码");// 发送者邮箱授权码mailInfo.setFromAddress("发送者邮箱"); // 发送者邮箱mailInfo.setToAddress(toAdd); // 接收者邮箱mailInfo.setSubject("Android应用测试"); // 邮件主题mailInfo.setContent("哈哈"); // 邮件文本return mailInfo;}}

该类是获取发送邮件信息的类,只要获取发送方邮箱服务器、发送方邮箱端口号、发送者邮箱地址、发送者邮箱授权码、发送者邮箱、接收者邮箱、发送邮件的主题以及邮件文本的操作信息。

新建一个MailInfo.java实体类

package com.example.Email;import java.util.Properties;public class MailInfo {private String mailServerHost;// 发送邮件的服务器的IPprivate String mailServerPort;// 发送邮件的服务器的端口private String fromAddress;// 邮件发送者的地址private String toAddress;    // 邮件接收者的地址private String userName;// 登陆邮件发送服务器的用户名private String password;// 登陆邮件发送服务器的密码private boolean validate = true;// 是否需要身份验证private String subject;// 邮件主题private String content;// 邮件的文本内容private String[] attachFileNames;// 邮件附件的文件名/*** 获得邮件会话属性*/public Properties getProperties() {Properties p = new Properties();p.put("mail.smtp.host", this.mailServerHost);p.put("mail.smtp.port", this.mailServerPort);p.put("mail.smtp.auth", validate ? "true" : "false");return p;}public String getMailServerHost() {return mailServerHost;}public void setMailServerHost(String mailServerHost) {this.mailServerHost = mailServerHost;}public String getMailServerPort() {return mailServerPort;}public void setMailServerPort(String mailServerPort) {this.mailServerPort = mailServerPort;}public boolean isValidate() {return validate;}public void setValidate(boolean validate) {this.validate = validate;}public String[] getAttachFileNames() {return attachFileNames;}public void setAttachFileNames(String[] fileNames) {this.attachFileNames = fileNames;}public String getFromAddress() {return fromAddress;}public void setFromAddress(String fromAddress) {this.fromAddress = fromAddress;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public String getToAddress() {return toAddress;}public void setToAddress(String toAddress) {this.toAddress = toAddress;}public String getUserName() {return userName;}public void setUserName(String userName) {this.userName = userName;}public String getSubject() {return subject;}public void setSubject(String subject) {this.subject = subject;}public String getContent() {return content;}public void setContent(String textContent) {this.content = textContent;}}

在该类下主要对发送邮件的一些常用对象字段的序列化过程(如:发送邮件的服务器的IP、发送邮件的服务器的端口、邮件发送者的地址等)。

新建一个MailSender.java邮件发送器类

package com.example.Email;import android.util.Log;import java.io.File;
import java.util.Date;
import java.util.Properties;import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Address;
import javax.mail.Authenticator;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;/*** 邮件发送器*/
public class MailSender {/*** 以文本格式发送邮件** @param mailInfo 待发送的邮件的信息*/public boolean sendTextMail(final MailInfo mailInfo) {// 判断是否需要身份认证MyAuthenticator authenticator = null;Properties pro = mailInfo.getProperties();if (mailInfo.isValidate()) {// 如果需要身份认证,则创建一个密码验证器authenticator = new MyAuthenticator(mailInfo.getUserName(), mailInfo.getPassword());}// 根据邮件会话属性和密码验证器构造一个发送邮件的sessionSession sendMailSession = Session.getDefaultInstance(pro, authenticator);//      Session sendMailSession = Session.getInstance(pro, new Authenticator() {
//          @Override
//          protected PasswordAuthentication getPasswordAuthentication() {
//              return new PasswordAuthentication(mailInfo.getUserName(),mailInfo.getPassword());
//          }
//      });try {// 根据session创建一个邮件消息Message mailMessage = new MimeMessage(sendMailSession);// 创建邮件发送者地址Address from = new InternetAddress(mailInfo.getFromAddress());// 设置邮件消息的发送者mailMessage.setFrom(from);// 创建邮件的接收者地址,并设置到邮件消息中Address to = new InternetAddress(mailInfo.getToAddress());mailMessage.setRecipient(Message.RecipientType.TO, to);// 设置邮件消息的主题mailMessage.setSubject(mailInfo.getSubject());// 设置邮件消息发送的时间mailMessage.setSentDate(new Date());// 设置邮件消息的主要内容String mailContent = mailInfo.getContent();mailMessage.setText(mailContent);// 发送邮件Transport.send(mailMessage);return true;} catch (MessagingException ex) {ex.printStackTrace();}return false;}/*** 以HTML格式发送邮件** @param mailInfo 待发送的邮件信息*/public static boolean sendHtmlMail(MailInfo mailInfo) {// 判断是否需要身份认证MyAuthenticator authenticator = null;Properties pro = mailInfo.getProperties();// 如果需要身份认证,则创建一个密码验证器if (mailInfo.isValidate()) {authenticator = new MyAuthenticator(mailInfo.getUserName(), mailInfo.getPassword());}// 根据邮件会话属性和密码验证器构造一个发送邮件的sessionSession sendMailSession = Session.getDefaultInstance(pro, authenticator);try {// 根据session创建一个邮件消息Message mailMessage = new MimeMessage(sendMailSession);// 创建邮件发送者地址Address from = new InternetAddress(mailInfo.getFromAddress());// 设置邮件消息的发送者mailMessage.setFrom(from);// 创建邮件的接收者地址,并设置到邮件消息中Address to = new InternetAddress(mailInfo.getToAddress());// Message.RecipientType.TO属性表示接收者的类型为TOmailMessage.setRecipient(Message.RecipientType.TO, to);// 设置邮件消息的主题mailMessage.setSubject(mailInfo.getSubject());// 设置邮件消息发送的时间mailMessage.setSentDate(new Date());// MiniMultipart类是一个容器类,包含MimeBodyPart类型的对象Multipart mainPart = new MimeMultipart();// 创建一个包含HTML内容的MimeBodyPartBodyPart html = new MimeBodyPart();// 设置HTML内容html.setContent(mailInfo.getContent(), "text/html; charset=utf-8");mainPart.addBodyPart(html);// 将MiniMultipart对象设置为邮件内容mailMessage.setContent(mainPart);// 发送邮件Transport.send(mailMessage);return true;} catch (MessagingException ex) {ex.printStackTrace();}return false;}/*** 发送带附件的邮件** @param info* @return*/public boolean sendFileMail(MailInfo info, File file) {Message attachmentMail = createAttachmentMail(info, file);try {Transport.send(attachmentMail);return true;} catch (MessagingException e) {e.printStackTrace();return false;}}/*** 创建带有附件的邮件** @return*/private Message createAttachmentMail(final MailInfo info, File file) {//创建邮件MimeMessage message = null;Properties pro = info.getProperties();try {Session sendMailSession = Session.getInstance(pro, new Authenticator() {@Overrideprotected PasswordAuthentication getPasswordAuthentication() {return new PasswordAuthentication(info.getUserName(), info.getPassword());}});message = new MimeMessage(sendMailSession);// 设置邮件的基本信息//创建邮件发送者地址Address from = new InternetAddress(info.getFromAddress());//设置邮件消息的发送者message.setFrom(from);//创建邮件的接受者地址,并设置到邮件消息中Address to = new InternetAddress(info.getToAddress());//设置邮件消息的接受者, Message.RecipientType.TO属性表示接收者的类型为TOmessage.setRecipient(Message.RecipientType.TO, to);//邮件标题message.setSubject(info.getSubject());// 创建邮件正文,为了避免邮件正文中文乱码问题,需要使用CharSet=UTF-8指明字符编码MimeBodyPart text = new MimeBodyPart();text.setContent(info.getContent(), "text/html;charset=UTF-8");// 创建容器描述数据关系MimeMultipart mp = new MimeMultipart();mp.addBodyPart(text);// 创建邮件附件MimeBodyPart attach = new MimeBodyPart();FileDataSource ds = new FileDataSource(file);DataHandler dh = new DataHandler(ds);attach.setDataHandler(dh);attach.setFileName(MimeUtility.encodeText(dh.getName()));mp.addBodyPart(attach);mp.setSubType("mixed");message.setContent(mp);message.saveChanges();} catch (Exception e) {Log.i("Email", "创建带附件的邮件失败");e.printStackTrace();}// 返回生成的邮件return message;}
}

该类主要实现邮件发送器发送邮件的类型的类型(如以文本格式发送邮件或者以HTML格式发送邮件),还实现是否发送发送带附件的邮件功能。

最后新建一个MyAuthenticator.java邮件发送认证的类

package com.example.Email;import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;public class MyAuthenticator extends Authenticator {String userName = null;String password = null;public MyAuthenticator() {}public MyAuthenticator(String username, String password) {this.userName = username;this.password = password;}protected PasswordAuthentication getPasswordAuthentication() {return new PasswordAuthentication(userName, password);}
}

该类主要实现发送方邮箱地址以及授权码,并实现接口的暴露以便外部的调用。

配置和查看发送方邮箱的服务器、端口号以及授权码
不过大家有没有发现在实现这些类的时候需要配置一些发送方的邮箱相关的信息,比如发送方邮箱服务器、发送方的邮箱端口号、发送方的邮箱授权码等,这些信息开发者是怎样查看的呢?下面以QQ邮箱为例。

首先访问QQ邮箱的网址(https://mail.qq.com/ ),然后登录自己QQ邮箱账号后进入邮箱主页后进行以下操作。

点击“设置”按钮后进入邮箱设置的操作界面后在导航栏点击“帐号”按钮,如下图。

进入“账号”操作界面后往下滑找到“POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务”的设置功能。如下图。

然后把邮箱账号的“POP3/SMTP服务”和“IMAP/SMTP服务”开启了,开启成功后会自动分配一个16位字符串的授权码,如下图。该授权码一般用于代替在第三方客户端邮箱登录该邮箱账户时所用的密码,一般是为了邮箱密码的安全考虑。

配置完成后最后不要忘了点击底部的“保存更改”的按钮,否则配置信息无效。如下图。

这样就做完了。

重点是端口一定要设置为587,不能设置为465

要不然会出现错误:Could not connect to SMTP host: smtp.qq.com, port: 465, response: -1 clojure

错误描述:
465端口是为SMTPS(SMTP-over-SSL)协议服务开放的,这是SMTP协议基于SSL安全协议之上的一种变种协议,它继承了SSL安全协议的非对称加密的高度安全可靠性,可防止邮件泄露
所有要开启SSL

解决办法:
修改端口号为587

安卓+使用腾讯企业邮箱发送邮件

端口加服务器配置如下(端口同样都是587)不用看官方的

打开腾讯企业邮箱首页,找到设置,如下图。

找到邮箱绑定,开启安全登录,生成客户端专用密码。如下图

这个时候将上面的信息填入代码中相应位置即可

如何使用安卓+qq邮箱+腾讯企业邮箱发送邮件相关推荐

  1. Outlook/Microsfot邮件配置:QQ邮箱/腾讯企业邮箱

    记录下最终成功的记录 1.QQ邮箱配置 Step1 添加账户 Step 2 弹出的窗口中下拉至最下边:高级设置 Step 3 在弹出的窗口中选择Interner电子邮件 Step 4 填写配置信息,其 ...

  2. 企业邮箱 - 腾讯企业邮箱的域名解析方法

    记录类型 主机记录 记录值 优先级 MX @ mxbiz1.qq.com 5 MX @ mxbiz2.qq.com 10 CNAME mail tp.exmail.qq.com / TXT @ v=s ...

  3. JavaMail IMAPFolder.getMessageByUID 获取QQ和腾讯企业邮箱新邮件的问题

    前言:做任何事,不要放弃,静下心来找到最好的解决方案,会有柳暗花明的那天! 最近在做邮箱,我们用的是java mail 1.5.6,有个需求是根据邮件的uid来和本地数据库的邮件比对,得到最新邮件的u ...

  4. 腾讯企业邮箱申请步骤

    会有很多朋友会问到,腾讯企业邮箱怎么申请呢,这次小编针对企业邮箱申请这个话题来根大家聊聊. 1.QQ企业邮箱的费用 企业邮箱按用户数计费,以"年"为购买周期,低是150元/用户/年 ...

  5. 腾讯企业邮箱发错了邮件怎么办,“邮件撤回”帮您解决问题

    腾讯企业邮箱全新推出"邮件撤回"功用,此功用直接面向QQ邮箱.域名邮箱及腾讯企业邮箱用户 . 关于已发送的邮件,能够测验进行撤回(仅限发往腾讯企业邮箱的邮件,并在对方阅览之前). ...

  6. qq收不到oracle邮件,腾讯企业邮箱发送邮件失败

    一直使用的腾讯企业邮箱,但是最近发现发送邮件全是失败的,提示: javax.mail.MessagingException: Could not connect to SMTP host: smtp. ...

  7. qq邮箱日历同步服务器,QQ邮箱,腾讯企业邮箱,让你的日程跟着手机走

    企业老板每天的日程排得满满当当的,如何有效的规划自己的形成,提升自己的工作效率是摆在每一个企业管理者面前不得不面对的问题.而基于个人的日程管理也成为提升管理者工作效率的一种有效手段. QQ邮箱也许可以 ...

  8. java发送QQ群邮件,Java使用腾讯企业邮箱 、javamail 、 SSL 发送邮件/群发

    引入相关依赖: javax.mail mail 1.4.7 commons-io commons-io 2.4 如果使用spring的发邮件,还需要添加依赖: org.springframework ...

  9. SpringBoot发送邮件(QQ邮箱、腾讯企业邮箱、网易邮箱、阿里云邮箱...)

    目录 一.获取邮箱授权码 二.引入依赖 三.配置文件(请注意yml格式,或者使用.properties) 四.不带附件发邮箱 五.带附件发邮箱 六.邮箱类型拓展 本篇文章以QQ邮箱作为发件人写案例演示 ...

  10. 微信企业邮箱服务器配置错误,解决腾讯企业邮箱smtp.exmail.qq.com发邮件错误

    在程序开发中经常会用到php发电子邮件,在腾讯申请了企业邮箱后,一直用得好好的.不过好像最近腾讯企业邮箱升级更新了,用smtp服务器一发邮件就提示"Cannot connenct to re ...

最新文章

  1. Lombok(1.14.8) - @Synchronized
  2. 《设计模式之禅》学习笔记(一)
  3. Mysql在离线安装时启动失败:mysql服务无法启动,服务没有报告任何错误
  4. java设计模式观察者模式_Java设计模式(9)——观察者模式
  5. 我在学习技术的过程遇到的不会的单词(不断完善)
  6. 硬核机械手!失去手指的机械工程师独立打造
  7. Bash字符串处理(与Java对照) - 17.判断是否以另外的字符串结尾
  8. 个人收集的一些库、工具、技术介绍
  9. 牛客小白月赛3 I 排名【结构体排序/较复杂/细节】
  10. 学习数据库必须掌握的54条SQL查询语句
  11. 知识图谱表示学习-TransE算法
  12. 网络调试助手无法连接tcp服务器,W5500 TCP 客户端网络调试助手连不上
  13. 【Excel文件合并工具】
  14. c语言修改pdf文件内容,PDF怎么编辑修改?如何编辑PDF的内容?
  15. python计算excel平均值_python计算excel平均值和标准差
  16. 常见iOS开发面试题(有10w多访问量的面试题)
  17. CentOS 7下的软件安装方法及策略
  18. GameObject.Find()能否查找隐藏属性的游戏对象?
  19. 第三节-戴师兄数据分析学习笔记-excel最全函数
  20. 转:Processing 编程学习指南

热门文章

  1. html中dom什么意思,dom属性是什么意思啊 html dom是什么意思,通俗易懂
  2. 百度编辑器设置上传文件大小
  3. 关于给青轴润轴消除弹簧音[误]
  4. 苹果手机邮箱imap服务器没有响应,Apple手机的内置电子邮件地址突然显示imap.gmail.com没有响应,无法发送电子邮件...
  5. 看看最新BTA大厂的Java程序员的招聘技术标准,聪明人已经收藏了!
  6. 中国的ruby on rails 视频
  7. 绘制scara机器人工作空间
  8. 各利不同网站的盈利模式
  9. 电偶极子场强分布与电偶极矩的引进_物理量引进_电磁学
  10. rrd文件导入mysql_RRDtool 系列连载-5 :查询 RRD 数据库信息