基于smtp协议的邮件系统(自己写的)

最近几天做好了应用【贱泰迪】,其中有个意见反馈,发送邮件,
我知道可以调用系统发送邮件,但这种方法有个弊端,就是您的手机必须安装Mail的客户端,
因此我想不用系统发送邮件这种方式,能不能向任意邮箱发送邮件呢?给我自己丢下了一个命题。
于是我调查,发现SMTP发送email 无需系统支持,无需配置,
经过多次尝试,多次失败,终于完成了此项功能。
先来看应用【贱泰迪】的效果,
基于smtp协议的邮件系统(自己写的)

填写您的邮箱、密码等,我就能收到您的反馈意见,是不是很方便呢,
更多的效果,您可以下载贱泰迪(http://down.mumayi.com/464309)查看。
此贴,讲这个功能给扣出来了,并附上其他的两种方法发送邮件。
效果图如下:
基于smtp协议的邮件系统(自己写的)基于smtp协议的邮件系统(自己写的)

1、使用Mail客户端发送邮件
这种方法前提您的手机必须安装Mail客户端,您可以测试的时候下载QQ邮箱客户端,看看运行的效果。
  1. case R.id.button1:
  2.                         // 创建Intent
  3.                         Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
  4.                         // 设置内容类型
  5.                         emailIntent.setType("plain/text");
  6.                         // 设置额外信息
  7.                         emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL,
  8.                                         new String[] { "收件人邮箱" });// 比如qq邮箱,测试的时候可以手机安装qq邮箱客户端
  9.                         emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "主题");
  10.                         emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, "内容");
  11.                         // 启动Activity
  12.                         startActivity(Intent.createChooser(emailIntent, "发送邮件..."));
  13.                         break;
复制代码

2、使用SMTP发送邮件
这是此贴的重点所在,SMTP的全称是“Simple Mail Transfer Protocol”,即简单邮件传输协议。
它是一组用于从源地址到目的地址传输邮件的规范,通过它来控制邮件的中转方式。
SMTP 协议属于 TCP/IP 协议簇,它帮助每台计算机在发送或中转信件时找到下一个目的地。
SMTP 服务器就是遵循 SMTP 协议的发送邮件服务器。
它需要三个jar包,下载地址:https://code.google.com/p/javamail-android/downloads/list
下载后复制libs,即可。
下面介绍两种方法实现使用SMTP发送邮件
(1)方法一
  1. case R.id.button2:
  2.                         new Thread() {
  3.                                 @Override
  4.                                 public void run() {
  5.                                         EmailSender sender = new EmailSender();
  6.                                         // 设置服务器地址和端口,网上搜的到
  7.                                         sender.setProperties("smtp.qq.com", "465");
  8.                                         // 分别设置发件人,邮件标题和文本内容
  9.                                         try {
  10.                                                 sender.setMessage("发件人邮箱", "主题主题1", "内容内容1");
  11.                                                 sender.setReceiver(new String[] { "收件人邮箱" });
  12.                                                 sender.sendEmail("smtp.qq.com", "发件人邮箱", "发件人邮箱密码");
  13.                                         } catch (AddressException e) {
  14.                                                 e.printStackTrace();
  15.                                                 Log.e("wxl", "AddressException", e);
  16.                                         } catch (MessagingException e) {
  17.                                                 e.printStackTrace();
  18.                                                 Log.e("wxl", "MessagingException", e);
  19.                                         }
  20.                                 }
  21.                         }.start();

  22.                         break;
复制代码

这里需要EmailSender.java
  1. package com.xiaomolong.example.smtpmail;

  2. import java.io.File;
  3. import java.util.Date;
  4. import java.util.Properties;
  5. import javax.activation.DataHandler;
  6. import javax.activation.FileDataSource;
  7. import javax.mail.Address;
  8. import javax.mail.Message;
  9. import javax.mail.MessagingException;
  10. import javax.mail.Session;
  11. import javax.mail.Transport;
  12. import javax.mail.internet.AddressException;
  13. import javax.mail.internet.InternetAddress;
  14. import javax.mail.internet.MimeBodyPart;
  15. import javax.mail.internet.MimeMessage;
  16. import javax.mail.internet.MimeMultipart;

  17. public class EmailSender {
  18.         private Properties properties;
  19.         private Session session;
  20.         private Message message;
  21.         private MimeMultipart multipart;

  22.         public EmailSender() {
  23.                 super();
  24.                 this.properties = new Properties();
  25.         }

  26.         public void setProperties(String host, String post) {
  27.                 // 地址
  28.                 this.properties.put("mail.smtp.host", host);
  29.                 // 端口号
  30.                 this.properties.put("mail.smtp.post", post);
  31.                 // 是否验证
  32.                 this.properties.put("mail.smtp.auth", true);
  33.                 this.session = Session.getInstance(properties);
  34.                 this.message = new MimeMessage(session);
  35.                 this.multipart = new MimeMultipart("mixed");
  36.         }

  37.         /**
  38.          * 设置收件人
  39.          *
  40.          * @param receiver
  41.          * @throws MessagingException
  42.          */
  43.         public void setReceiver(String[] receiver) throws MessagingException {
  44.                 Address[] address = new InternetAddress[receiver.length];
  45.                 for (int i = 0; i < receiver.length; i++) {
  46.                         address[i] = new InternetAddress(receiver[i]);
  47.                 }
  48.                 this.message.setRecipients(Message.RecipientType.TO, address);
  49.         }

  50.         /**
  51.          * 设置邮件
  52.          *
  53.          * @param from
  54.          *            来源
  55.          * @param title
  56.          *            标题
  57.          * @param content
  58.          *            内容
  59.          * @throws AddressException
  60.          * @throws MessagingException
  61.          */
  62.         public void setMessage(String from, String title, String content)
  63.                         throws AddressException,

  64.                         MessagingException {
  65.                 this.message.setFrom(new InternetAddress(from));
  66.                 this.message.setSubject(title);
  67.                 // 纯文本的话用setText()就行,不过有附件就显示不出来内容了
  68.                 MimeBodyPart textBody = new MimeBodyPart();
  69.                 textBody.setContent(content, "text/html;charset=gbk");
  70.                 this.multipart.addBodyPart(textBody);
  71.         }

  72.         /**
  73.          * 添加附件
  74.          *
  75.          * @param filePath
  76.          *            文件路径
  77.          * @throws MessagingException
  78.          */
  79.         public void addAttachment(String filePath) throws MessagingException {
  80.                 FileDataSource fileDataSource = new FileDataSource(new File(filePath));
  81.                 DataHandler dataHandler = new DataHandler(fileDataSource);
  82.                 MimeBodyPart mimeBodyPart = new MimeBodyPart();
  83.                 mimeBodyPart.setDataHandler(dataHandler);
  84.                 mimeBodyPart.setFileName(fileDataSource.getName());
  85.                 this.multipart.addBodyPart(mimeBodyPart);
  86.         }

  87.         /**
  88.          * 发送邮件
  89.          *
  90.          * @param host
  91.          *            地址
  92.          * @param account
  93.          *            账户名
  94.          * @param pwd
  95.          *            密码
  96.          * @throws MessagingException
  97.          */
  98.         public void sendEmail(String host, String account, String pwd)
  99.                         throws MessagingException {
  100.                 // 发送时间
  101.                 this.message.setSentDate(new Date());
  102.                 // 发送的内容,文本和附件
  103.                 this.message.setContent(this.multipart);
  104.                 this.message.saveChanges();
  105.                 // 创建邮件发送对象,并指定其使用SMTP协议发送邮件
  106.                 Transport transport = session.getTransport("smtp");
  107.                 // 登录邮箱
  108.                 transport.connect(host, account, pwd);
  109.                 // 发送邮件
  110.                 transport.sendMessage(message, message.getAllRecipients());
  111.                 // 关闭连接
  112.                 transport.close();
  113.         }
  114. }
复制代码

(2)方法二
  1. case R.id.button3:
  2.                         new SendTask().execute();
  3.                         break;
复制代码
  1. class SendTask extends AsyncTask<Integer, Integer, String> {
  2.                 // 后面尖括号内分别是参数(例子里是线程休息时间),进度(publishProgress用到),返回值 类型

  3.                 @Override
  4.                 protected void onPreExecute() {
  5.                         // 第一个执行方法

  6.                         super.onPreExecute();
  7.                 }

  8.                 @Override
  9.                 protected String doInBackground(Integer... params) {
  10.                         // contact, contactPsw, title, content;
  11.                         String isok = "";
  12.                         Mails m = new Mails("发件人邮箱", "发件人邮箱密码");
  13.                         m.set_debuggable(false);
  14.                         String[] toArr = { "收件人邮箱" };
  15.                         m.set_to(toArr);
  16.                         m.set_from("发件人邮箱");
  17.                         m.set_subject("主题主题2");
  18.                         m.setBody("内容内容2");
  19.                         try {
  20.                                 // m.addAttachment("/sdcard/filelocation");
  21.                                 if (m.send()) {

  22.                                         isok = "ok";
  23.                                 } else {
  24.                                         isok = "no";

  25.                                 }
  26.                         } catch (Exception e) {
  27.                                 Log.e("wxl", "Could not send email", e);
  28.                         }
  29.                         return isok;
  30.                 }

  31.                 @Override
  32.                 protected void onProgressUpdate(Integer... progress) {
  33.                         // 这个函数在doInBackground调用publishProgress时触发,虽然调用时只有一个参数
  34.                         // 但是这里取到的是一个数组,所以要用progesss[0]来取值
  35.                         // 第n个参数就用progress[n]来取值

  36.                         super.onProgressUpdate(progress);
  37.                 }

  38.                 @Override
  39.                 protected void onPostExecute(String result) {
  40.                         // doInBackground返回时触发,换句话说,就是doInBackground执行完后触发
  41.                         // 这里的result就是上面doInBackground执行后的返回值,所以这里是"执行完毕"
  42.                         // setTitle(result);
  43.                         if ("ok".equals(result)) {
  44.                                 Toast.makeText(getApplicationContext(), "发送成功",
  45.                                                 Toast.LENGTH_SHORT).show();
  46.                         } else {
  47.                                 Toast.makeText(getApplicationContext(), "发送失败",
  48.                                                 Toast.LENGTH_SHORT).show();
  49.                         }
  50.                         super.onPostExecute(result);
  51.                 }

  52.         }
复制代码

这里需要Mails.java
  1. package com.xiaomolong.example.smtpmail;

  2. import java.util.Date;
  3. import java.util.Properties;

  4. import javax.activation.CommandMap;
  5. import javax.activation.DataHandler;
  6. import javax.activation.DataSource;
  7. import javax.activation.FileDataSource;
  8. import javax.activation.MailcapCommandMap;
  9. import javax.mail.BodyPart;
  10. import javax.mail.Multipart;
  11. import javax.mail.PasswordAuthentication;
  12. import javax.mail.Session;
  13. import javax.mail.Transport;
  14. import javax.mail.internet.InternetAddress;
  15. import javax.mail.internet.MimeBodyPart;
  16. import javax.mail.internet.MimeMessage;
  17. import javax.mail.internet.MimeMultipart;

  18. public class Mails extends javax.mail.Authenticator {
  19.         private String _user;
  20.         private String _pass;
  21.         private String[] _to;
  22.         private String _from;
  23.         private String _port;
  24.         private String _sport;
  25.         private String _host;
  26.         private String _subject;
  27.         private String _body;
  28.         private boolean _auth;
  29.         private boolean _debuggable;
  30.         private Multipart _multipart;

  31.         public Mails() {
  32.                 _host = "smtp.qq.com"; // default smtp server
  33.                 _port = "465"; // default smtp port
  34.                 _sport = "465"; // default socketfactory port
  35.                 _user = ""; // username _pass = ""; // password
  36.                 _from = ""; // email sent from
  37.                 _subject = ""; // email subject
  38.                 _body = ""; // email body
  39.                 _debuggable = false; // debug mode on or off - default off
  40.                 _auth = true; // smtp authentication - default on
  41.                 _multipart = new MimeMultipart(); // There is something wrong with
  42.                                                                                         // MailCap, javamail can not find a
  43.                                                                                         // handler for the multipart/mixed
  44.                                                                                         // part, so this bit needs to be
  45.                                                                                         // added.
  46.                 MailcapCommandMap mc = (MailcapCommandMap) CommandMap
  47.                                 .getDefaultCommandMap();
  48.                 mc.addMailcap("text/html;; x-java-content-handler=com.sun.mail.handlers.text_html");
  49.                 mc.addMailcap("text/xml;; x-java-content-handler=com.sun.mail.handlers.text_xml");
  50.                 mc.addMailcap("text/plain;; x-java-content-handler=com.sun.mail.handlers.text_plain");
  51.                 mc.addMailcap("multipart/*;; x-java-content-handler=com.sun.mail.handlers.multipart_mixed");
  52.                 mc.addMailcap("message/rfc822;; x-java-content-handler=com.sun.mail.handlers.message_rfc822");
  53.                 CommandMap.setDefaultCommandMap(mc);
  54.         }

  55.         public String get_user() {
  56.                 return _user;
  57.         }

  58.         public void set_user(String _user) {
  59.                 this._user = _user;
  60.         }

  61.         public String get_pass() {
  62.                 return _pass;
  63.         }

  64.         public void set_pass(String _pass) {
  65.                 this._pass = _pass;
  66.         }

  67.         public String[] get_to() {
  68.                 return _to;
  69.         }

  70.         public void set_to(String[] _to) {
  71.                 this._to = _to;
  72.         }

  73.         public String get_from() {
  74.                 return _from;
  75.         }

  76.         public void set_from(String _from) {
  77.                 this._from = _from;
  78.         }

  79.         public String get_port() {
  80.                 return _port;
  81.         }

  82.         public void set_port(String _port) {
  83.                 this._port = _port;
  84.         }

  85.         public String get_sport() {
  86.                 return _sport;
  87.         }

  88.         public void set_sport(String _sport) {
  89.                 this._sport = _sport;
  90.         }

  91.         public String get_host() {
  92.                 return _host;
  93.         }

  94.         public void set_host(String _host) {
  95.                 this._host = _host;
  96.         }

  97.         public String get_subject() {
  98.                 return _subject;
  99.         }

  100.         public void set_subject(String _subject) {
  101.                 this._subject = _subject;
  102.         }

  103.         public String get_body() {
  104.                 return _body;
  105.         }

  106.         public void set_body(String _body) {
  107.                 this._body = _body;
  108.         }

  109.         public boolean is_auth() {
  110.                 return _auth;
  111.         }

  112.         public void set_auth(boolean _auth) {
  113.                 this._auth = _auth;
  114.         }

  115.         public boolean is_debuggable() {
  116.                 return _debuggable;
  117.         }

  118.         public void set_debuggable(boolean _debuggable) {
  119.                 this._debuggable = _debuggable;
  120.         }

  121.         public Multipart get_multipart() {
  122.                 return _multipart;
  123.         }

  124.         public void set_multipart(Multipart _multipart) {
  125.                 this._multipart = _multipart;
  126.         }

  127.         public Mails(String user, String pass) {
  128.                 this();
  129.                 _user = user;
  130.                 _pass = pass;
  131.         }

  132.         public boolean send() throws Exception {
  133.                 Properties props = _setProperties();
  134.                 if (!_user.equals("") && !_pass.equals("") && _to.length > 0
  135.                                 && !_from.equals("") && !_subject.equals("")
  136.                                 && !_body.equals("")) {
  137.                         Session session = Session.getInstance(props, this);
  138.                         MimeMessage msg = new MimeMessage(session);
  139.                         msg.setFrom(new InternetAddress(_from));
  140.                         InternetAddress[] addressTo = new InternetAddress[_to.length];
  141.                         for (int i = 0; i < _to.length; i++) {
  142.                                 addressTo[i] = new InternetAddress(_to[i]);
  143.                         }
  144.                         msg.setRecipients(MimeMessage.RecipientType.TO, addressTo);
  145.                         msg.setSubject(_subject);
  146.                         msg.setSentDate(new Date()); // setup message body
  147.                         BodyPart messageBodyPart = new MimeBodyPart();
  148.                         messageBodyPart.setText(_body);
  149.                         _multipart.addBodyPart(messageBodyPart); // Put parts in message
  150.                         msg.setContent(_multipart); // send email
  151.                         Transport.send(msg);
  152.                         return true;
  153.                 } else {
  154.                         return false;
  155.                 }
  156.         }

  157.         public void addAttachment(String filename) throws Exception {
  158.                 BodyPart messageBodyPart = new MimeBodyPart();
  159.                 DataSource source = new FileDataSource(filename);
  160.                 messageBodyPart.setDataHandler(new DataHandler(source));
  161.                 messageBodyPart.setFileName(filename);
  162.                 _multipart.addBodyPart(messageBodyPart);
  163.         }

  164.         @Override
  165.         public PasswordAuthentication getPasswordAuthentication() {
  166.                 return new PasswordAuthentication(_user, _pass);
  167.         }

  168.         private Properties _setProperties() {
  169.                 Properties props = new Properties();
  170.                 props.put("mail.smtp.host", _host);
  171.                 if (_debuggable) {
  172.                         props.put("mail.debug", "true");
  173.                 }
  174.                 if (_auth) {
  175.                         props.put("mail.smtp.auth", "true");
  176.                 }
  177.                 props.put("mail.smtp.port", _port);
  178.                 props.put("mail.smtp.socketFactory.port", _sport);
  179.                 props.put("mail.smtp.socketFactory.class",
  180.                                 "javax.net.ssl.SSLSocketFactory");
  181.                 props.put("mail.smtp.socketFactory.fallback", "false");
  182.                 return props;
  183.         } // the getters and setters

  184.         public String getBody() {
  185.                 return _body;
  186.         }

  187.         public void setBody(String _body) {

  188.                 this._body = _body;
  189.         } // more of the getters and setters 锟斤拷.. }
  190. }

复制代码

代码粘完了,这里采用了线程和异步,对于新手可以学学。【贱泰迪】采用的是第二种方法。
下面开始说一下注意点:
首先加上联网的权限,<uses-permission android:name="android.permission.INTERNET" />,这是小问题
以上代码完成没有问题,但是运行会抛这样的异常:
基于smtp协议的邮件系统(自己写的)

这是为什么,使用SMTP来发送E-mail,因此您的邮箱必须开启此项服务,
【QQ邮箱】【设置】【账户】【POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务】如下图:
基于smtp协议的邮件系统(自己写的)

基于smtp协议的邮件系统(自己写的)


最后附上下载地址:http://download.csdn.net/detail/xiangzhihong8/6661655

上一篇:手机卫士04-自定义显示图片


下一篇:10倍处理能力 阿里云推云上首个支持12层4K非编NAS产品