第一步、导入第三方jar包

Android实现发送邮件,首先需要依赖additional.jar、mail.jar和activation.jar这3个jar包。

Google提供了下载地址:https://code.google.com/archive/p/javamail-android/downloads 。

下载后添加到依赖(这里我就不详细说明了)。

第二步、创建相关类

1、创建MailInfo类,来代表一个即将被发送的邮件

package com.chuanye.maidian.mail;

import java.util.Properties;

public class MailInfo {
private String mailServerHost;// 发送邮件的服务器的IP
private 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.pop.host", this.mailServerHost);
p.put("mail.smtp.host", this.mailServerHost);
p.put("mail.smtp.port", this.mailServerPort);
//p.put("mail.smtp.auth", validate ? "true" : "false");
p.put("mail.smtp.auth", "true");//设置为true 才被允许,默认false //p.put("mail.smtp.socketFactory.class", SSL_FACTORY); // 使用JSSE的SSL
/*p.put("mail.smtp.socketFactory.fallback", "false"); // 只处理SSL的连接,对于非SSL的连接不做处理
p.put("mail.smtp.socketFactory.port", this.mailServerPort);
p.put("mail.smtp.ssl.enable", true);*/
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;
}
}

  2、创建认证类MyAuthenticator

package com.chuanye.maidian.mail;

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);
}
}

  3、创建邮件发送类MailSender

package com.chuanye.maidian.mail;

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());
}
// 根据邮件会话属性和密码验证器构造一个发送邮件的session
Session 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());
}
// 根据邮件会话属性和密码验证器构造一个发送邮件的session
Session 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属性表示接收者的类型为TO
mailMessage.setRecipient(Message.RecipientType.TO, to);
// 设置邮件消息的主题
mailMessage.setSubject(mailInfo.getSubject());
// 设置邮件消息发送的时间
mailMessage.setSentDate(new Date());
// MiniMultipart类是一个容器类,包含MimeBodyPart类型的对象
Multipart mainPart = new MimeMultipart();
// 创建一个包含HTML内容的MimeBodyPart
BodyPart 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() {
@Override
protected 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属性表示接收者的类型为TO
message.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.e("TAG", "创建带附件的邮件失败");
e.printStackTrace();
}
// 返回生成的邮件
return message;
}
}

  

第三步、发送邮件

这里举例发送文本邮件和带附件的邮件

public class MainActivity extends AppCompatActivity {

    private EditText editText;

    @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText = (EditText) findViewById(R.id.toAddEt);
} public void senTextMail(View view) {
SendMailUtil.send(editText.getText().toString());
} public void sendFileMail(View view) { File file = new File(Environment.getExternalStorageDirectory()+File.separator+"test.txt");
OutputStream os = null;
try {
os = new FileOutputStream(file);
String str = "hello world";
byte[] data = str.getBytes();
os.write(data);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if (os != null)os.close();
} catch (IOException e) {
}
}
SendMailUtil.send(file,editText.getText().toString());
}
}

  下面是发送邮件的SendMailUtil

package com.chuanye.maidian.mail;

import android.support.annotation.NonNull;

import java.io.File;

public class SendMailUtil {
//qq
//private static final String HOST = "smtp.qq.com";
//private static final String PORT = "587";
//private static final String FROM_ADD = "changyiqiang666@163.com";
//private static final String FROM_PSW = "qwertyuiop123456"; // //163
private static final String HOST = "smtp.163.com";
private static final String PORT = "25"; //或者465 994 //private static final String HOST = "pop.163.com";
//private static final String PORT = "995"; //或者465 994
private static final String FROM_ADD = "changyiqiang666@163.com";
private static final String FROM_PSW = "qwertyuiop123456";//qwertyuiop123456
//// private static final String TO_ADD = "2584770373@qq.com"; public static void send(final File file, String toAdd){
final MailInfo mailInfo = creatMail(toAdd);
final MailSender sms = new MailSender();
new Thread(new Runnable() {
@Override
public 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() {
@Override
public void run() {
sms.sendTextMail(mailInfo);
}
}).start();
} @NonNull
private static MailInfo creatMail(String toAdd) {
final MailInfo mailInfo = new MailInfo();
mailInfo.setMailServerHost(HOST);// 发送邮件的服务器的IP
mailInfo.setMailServerPort(PORT);// 发送邮件的服务器的端口
mailInfo.setValidate(true);// 是否需要身份验证
mailInfo.setUserName(FROM_ADD); // 你的邮箱地址 // 登陆邮件发送服务器的用户名
mailInfo.setPassword(FROM_PSW);// 您的邮箱密码 登陆邮件发送服务器的密码
mailInfo.setFromAddress(FROM_ADD); // 发送的邮箱 // 邮件发送者的地址
mailInfo.setToAddress(toAdd); // 发到哪个邮件去
mailInfo.setSubject("Hello"); // 邮件主题
mailInfo.setContent("Android 测试"); // 邮件文本
return mailInfo;
}
}

  特别注意:一定要打开邮箱POP3/IMAP/SMTP服务,不然认证会失败

需要把SendMailUtil 下的FROM_ADD,FROM_PSW配置成你自己的账号和授权码

 private static final String FROM_ADD = "changyiqiang666@163.com";
private static final String FROM_PSW = "qwertyuiop123456";//qwertyuiop123456

  另外端口我设置为了25

private static final String PORT = "25"; //或者465  994

 最后权限

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

  

 

不然会报如下错误

07-19 11:02:09.724 31125-32494/com.chuanye.maidian I/System.out: [socket] connection smtp.163.com/220.181.12.13:994;LocalPort=58772(0)
07-19 11:02:29.790 31125-32494/com.chuanye.maidian W/System.err: javax.mail.MessagingException: Could not connect to SMTP host: smtp.163.com, port: 994, response: -1
07-19 11:02:29.790 31125-32494/com.chuanye.maidian W/System.err: at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1379)
07-19 11:02:29.790 31125-32494/com.chuanye.maidian W/System.err: at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:412)
07-19 11:02:29.790 31125-32494/com.chuanye.maidian W/System.err: at javax.mail.Service.connect(Service.java:310)
07-19 11:02:29.790 31125-32494/com.chuanye.maidian W/System.err: at javax.mail.Service.connect(Service.java:169)
07-19 11:02:29.790 31125-32494/com.chuanye.maidian W/System.err: at javax.mail.Service.connect(Service.java:118)
07-19 11:02:29.790 31125-32494/com.chuanye.maidian W/System.err: at javax.mail.Transport.send0(Transport.java:188)
07-19 11:02:29.790 31125-32494/com.chuanye.maidian W/System.err: at javax.mail.Transport.send(Transport.java:118)
07-19 11:02:29.790 31125-32494/com.chuanye.maidian W/System.err: at com.chuanye.maidian.mail.MailSender.sendTextMail(MailSender.java:69)
07-19 11:02:29.790 31125-32494/com.chuanye.maidian W/System.err: at com.chuanye.maidian.mail.SendMailUtil$2.run(SendMailUtil.java:43)
07-19 11:02:29.790 31125-32494/com.chuanye.maidian W/System.err: at java.lang.Thread.run(Thread.java:818)
07-19 11:02:39.315 31125-31125/com.chuanye.maidian W/IInputConnectionWrapper: clearMetaKeyStates on inactive InputConnection
07-19 11:02:39.903 31125-31125/com.chuanye.maidian W/IInputConnectionWrapper: getTextBeforeCursor on inactive InputConnection
07-19 11:02:39.904 31125-31125/com.chuanye.maidian W/IInputConnectionWrapper: getTextAfterCursor on inactive InputConnection
07-19 11:02:39.906 31125-31125/com.chuanye.maidian W/IInputConnectionWrapper: clearMetaKeyStates on inactive InputConnection

  完成

参考于:https://blog.csdn.net/qiujiaxin050/article/details/81081651

https://www.jianshu.com/p/f940ebcae899

感谢

Android 中发送邮件的更多相关文章

  1. android中发送邮件

    在移动互联网时代,手机邮件已不是什么新鲜事了,我们可以使用内置的Gmail引擎来发送邮件,也可以使用SMTP来发送邮件,下面用一个简单示例来演示邮件的发送,包括单方发送邮件.多方发送邮件以及抄送邮件, ...

  2. Android 中常见控件的介绍和使用

    1 TextView文本框 1.1 TextView类的结构 TextView 是用于显示字符串的组件,对于用户来说就是屏幕中一块用于显示文本的区域.TextView类的层次关系如下: java.la ...

  3. Android 后台发送邮件 (收集应用异常信息+Demo代码)

    上一次说了如何收集我们已经发布的应用程序的错误信息,方便我们调试完善程序.上次说的收集方法主要是把收集的信息通过Http的post请求把相关的异常信息变成请求参数发送到服务器.这个对做过web开发的人 ...

  4. Android中的LinearLayout布局

    LinearLayout : 线性布局 在一般情况下,当有很多控件需要在一个界面列出来时,我们就可以使用线性布局(LinearLayout)了,  线性布局是按照垂直方向(vertical)或水平方向 ...

  5. Android中BroadcastReceiver的两种注册方式(静态和动态)详解

    今天我们一起来探讨下安卓中BroadcastReceiver组件以及详细分析下它的两种注册方式. BroadcastReceiver也就是"广播接收者"的意思,顾名思义,它就是用来 ...

  6. Android中使用ExpandableListView实现微信通讯录界面(完善仿微信APP)

    之前的博文<Android中使用ExpandableListView实现好友分组>我简单介绍了使用ExpandableListView实现简单的好友分组功能,今天我们针对之前的所做的仿微信 ...

  7. Android中ListView实现图文并列并且自定义分割线(完善仿微信APP)

    昨天的(今天凌晨)的博文<Android中Fragment和ViewPager那点事儿>中,我们通过使用Fragment和ViewPager模仿实现了微信的布局框架.今天我们来通过使用Li ...

  8. Android中Fragment和ViewPager那点事儿(仿微信APP)

    在之前的博文<Android中使用ViewPager实现屏幕页面切换和引导页效果实现>和<Android中Fragment的两种创建方式>以及<Android中Fragm ...

  9. Android中Fragment与Activity之间的交互(两种实现方式)

    (未给Fragment的布局设置BackGound) 之前关于Android中Fragment的概念以及创建方式,我专门写了一篇博文<Android中Fragment的两种创建方式>,就如 ...

随机推荐

  1. pipenv安装包时一直卡在Locking [packages] dependencies…,换pypi源

    Pipfile 中 source 源是 python 官网,服务器在国外,加载比较慢. 将 url 修改为清华的 pypi 源 https://pypi.tuna.tsinghua.edu.cn/si ...

  2. hbase配置hdfs的HA之后需要修改的路径

    hbase-site.xml中配置了hdfs的一个路径 <property> <name>hbase.rootdir</name> <value>hdf ...

  3. 生鲜超市项目错误及解决办法(安装mysqlclient)

    错误1:安装Mysqlclient D:\Mxshop>pip install mysqlclient- 1.4.4-cp27-cp27m-win32 报错: ERROR: Could not ...

  4. mybatis框架之多参数入参--传入Map集合

    需求:查询出指定性别和用户角色列表下的用户列表信息 实际上:mybatis在入参的时候,都是将参数封装成为map集合进行入参的,不管你是单参数入参,还是多参数入参,都是可以封装成map集合的,这是无可 ...

  5. SLAM:

    十四讲: 传感器约束了外部环境 测到的通常都是一些间接的物理量而不是直接的位置数据 只能通过一些间接的手段,从这些数据推算自己的位置 好处是没有对环境提出任何要求 camera:单目.双目.深度 Mo ...

  6. 【java】@SuppressWarnings

    作用:用于抑制编译器产生警告信息. 示例1——抑制单类型的警告: 示例2——抑制多类型的警告: 示例3——抑制所有类型的警告: 三.注解目标 通过 @SuppressWarnings 的源码可知,其注 ...

  7. 【可视化】Vue基础

    作者 | Jeskson 来源 | 达达前端小酒馆 Vue简介 Vue框架,框架的作者,尤雨溪,组件化,快速开发的特点. 生命周期 beforeCreate:组件刚刚被创建 created:组件创建完 ...

  8. mysql 聚集索引,非聚集索引,覆盖索引区别。

    把原站信息经过筛选贴过来,用于自己备忘.原站:https://www.cnblogs.com/aspwebchh/p/6652855.html ---------------------------- ...

  9. python总结九

    1.sql语句: ,; 解释:由hire_date进行排序,降序desc,最大的就是最晚进来的员工,limit  如果是只有一个参数的话,那么说明是除了前面多少个数据, 如果后面有两个参数的话,那么就 ...

  10. 初探Java设计模式5:一文了解Spring涉及到的9种设计模式

    本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下 ...