最近几天做好了应用【贱泰迪】,其中有个意见反馈,发送邮件,
我知道可以调用系统发送邮件,但这种方法有个弊端,就是您的手机必须安装Mail的客户端,
因此我想不用系统发送邮件这种方式,能不能向任意邮箱发送邮件呢?给我自己丢下了一个命题。
于是我调查,发现SMTP发送email 无需系统支持,无需配置,
经过多次尝试,多次失败,终于完成了此项功能。
先来看应用【贱泰迪】的效果,
填写您的邮箱、密码等,我就能收到您的反馈意见,是不是很方便呢,
更多的效果,您可以下载贱泰迪(http://down.mumayi.com/464309)查看。
此贴,讲这个功能给扣出来了,并附上其他的两种方法发送邮件。
效果图如下:
1、使用Mail客户端发送邮件
这种方法前提您的手机必须安装Mail客户端,您可以测试的时候下载QQ邮箱客户端,看看运行的效果。
- case R.id.button1:
- // 创建Intent
- Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
- // 设置内容类型
- emailIntent.setType("plain/text");
- // 设置额外信息
- emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL,
- new String[] { "收件人邮箱" });// 比如qq邮箱,测试的时候可以手机安装qq邮箱客户端
- emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "主题");
- emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, "内容");
- // 启动Activity
- startActivity(Intent.createChooser(emailIntent, "发送邮件..."));
- 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)方法一
- case R.id.button2:
- new Thread() {
- @Override
- public void run() {
- EmailSender sender = new EmailSender();
- // 设置服务器地址和端口,网上搜的到
- sender.setProperties("smtp.qq.com", "465");
- // 分别设置发件人,邮件标题和文本内容
- try {
- sender.setMessage("发件人邮箱", "主题主题1", "内容内容1");
- sender.setReceiver(new String[] { "收件人邮箱" });
- sender.sendEmail("smtp.qq.com", "发件人邮箱", "发件人邮箱密码");
- } catch (AddressException e) {
- e.printStackTrace();
- Log.e("wxl", "AddressException", e);
- } catch (MessagingException e) {
- e.printStackTrace();
- Log.e("wxl", "MessagingException", e);
- }
- }
- }.start();
- break;
复制代码
这里需要EmailSender.java
- package com.xiaomolong.example.smtpmail;
- 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.Message;
- import javax.mail.MessagingException;
- import javax.mail.Session;
- import javax.mail.Transport;
- import javax.mail.internet.AddressException;
- import javax.mail.internet.InternetAddress;
- import javax.mail.internet.MimeBodyPart;
- import javax.mail.internet.MimeMessage;
- import javax.mail.internet.MimeMultipart;
- public class EmailSender {
- private Properties properties;
- private Session session;
- private Message message;
- private MimeMultipart multipart;
- public EmailSender() {
- super();
- this.properties = new Properties();
- }
- public void setProperties(String host, String post) {
- // 地址
- this.properties.put("mail.smtp.host", host);
- // 端口号
- this.properties.put("mail.smtp.post", post);
- // 是否验证
- this.properties.put("mail.smtp.auth", true);
- this.session = Session.getInstance(properties);
- this.message = new MimeMessage(session);
- this.multipart = new MimeMultipart("mixed");
- }
- /**
- * 设置收件人
- *
- * @param receiver
- * @throws MessagingException
- */
- public void setReceiver(String[] receiver) throws MessagingException {
- Address[] address = new InternetAddress[receiver.length];
- for (int i = 0; i < receiver.length; i++) {
- address[i] = new InternetAddress(receiver[i]);
- }
- this.message.setRecipients(Message.RecipientType.TO, address);
- }
- /**
- * 设置邮件
- *
- * @param from
- * 来源
- * @param title
- * 标题
- * @param content
- * 内容
- * @throws AddressException
- * @throws MessagingException
- */
- public void setMessage(String from, String title, String content)
- throws AddressException,
- MessagingException {
- this.message.setFrom(new InternetAddress(from));
- this.message.setSubject(title);
- // 纯文本的话用setText()就行,不过有附件就显示不出来内容了
- MimeBodyPart textBody = new MimeBodyPart();
- textBody.setContent(content, "text/html;charset=gbk");
- this.multipart.addBodyPart(textBody);
- }
- /**
- * 添加附件
- *
- * @param filePath
- * 文件路径
- * @throws MessagingException
- */
- public void addAttachment(String filePath) throws MessagingException {
- FileDataSource fileDataSource = new FileDataSource(new File(filePath));
- DataHandler dataHandler = new DataHandler(fileDataSource);
- MimeBodyPart mimeBodyPart = new MimeBodyPart();
- mimeBodyPart.setDataHandler(dataHandler);
- mimeBodyPart.setFileName(fileDataSource.getName());
- this.multipart.addBodyPart(mimeBodyPart);
- }
- /**
- * 发送邮件
- *
- * @param host
- * 地址
- * @param account
- * 账户名
- * @param pwd
- * 密码
- * @throws MessagingException
- */
- public void sendEmail(String host, String account, String pwd)
- throws MessagingException {
- // 发送时间
- this.message.setSentDate(new Date());
- // 发送的内容,文本和附件
- this.message.setContent(this.multipart);
- this.message.saveChanges();
- // 创建邮件发送对象,并指定其使用SMTP协议发送邮件
- Transport transport = session.getTransport("smtp");
- // 登录邮箱
- transport.connect(host, account, pwd);
- // 发送邮件
- transport.sendMessage(message, message.getAllRecipients());
- // 关闭连接
- transport.close();
- }
- }
复制代码
(2)方法二
- case R.id.button3:
- new SendTask().execute();
- break;
复制代码
- class SendTask extends AsyncTask<Integer, Integer, String> {
- // 后面尖括号内分别是参数(例子里是线程休息时间),进度(publishProgress用到),返回值 类型
- @Override
- protected void onPreExecute() {
- // 第一个执行方法
- super.onPreExecute();
- }
- @Override
- protected String doInBackground(Integer... params) {
- // contact, contactPsw, title, content;
- String isok = "";
- Mails m = new Mails("发件人邮箱", "发件人邮箱密码");
- m.set_debuggable(false);
- String[] toArr = { "收件人邮箱" };
- m.set_to(toArr);
- m.set_from("发件人邮箱");
- m.set_subject("主题主题2");
- m.setBody("内容内容2");
- try {
- // m.addAttachment("/sdcard/filelocation");
- if (m.send()) {
- isok = "ok";
- } else {
- isok = "no";
- }
- } catch (Exception e) {
- Log.e("wxl", "Could not send email", e);
- }
- return isok;
- }
- @Override
- protected void onProgressUpdate(Integer... progress) {
- // 这个函数在doInBackground调用publishProgress时触发,虽然调用时只有一个参数
- // 但是这里取到的是一个数组,所以要用progesss[0]来取值
- // 第n个参数就用progress[n]来取值
- super.onProgressUpdate(progress);
- }
- @Override
- protected void onPostExecute(String result) {
- // doInBackground返回时触发,换句话说,就是doInBackground执行完后触发
- // 这里的result就是上面doInBackground执行后的返回值,所以这里是"执行完毕"
- // setTitle(result);
- if ("ok".equals(result)) {
- Toast.makeText(getApplicationContext(), "发送成功",
- Toast.LENGTH_SHORT).show();
- } else {
- Toast.makeText(getApplicationContext(), "发送失败",
- Toast.LENGTH_SHORT).show();
- }
- super.onPostExecute(result);
- }
- }
复制代码
这里需要Mails.java
- package com.xiaomolong.example.smtpmail;
- import java.util.Date;
- import java.util.Properties;
- import javax.activation.CommandMap;
- import javax.activation.DataHandler;
- import javax.activation.DataSource;
- import javax.activation.FileDataSource;
- import javax.activation.MailcapCommandMap;
- import javax.mail.BodyPart;
- 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;
- public class Mails extends javax.mail.Authenticator {
- private String _user;
- private String _pass;
- private String[] _to;
- private String _from;
- private String _port;
- private String _sport;
- private String _host;
- private String _subject;
- private String _body;
- private boolean _auth;
- private boolean _debuggable;
- private Multipart _multipart;
- public Mails() {
- _host = "smtp.qq.com"; // default smtp server
- _port = "465"; // default smtp port
- _sport = "465"; // default socketfactory port
- _user = ""; // username _pass = ""; // password
- _from = ""; // email sent from
- _subject = ""; // email subject
- _body = ""; // email body
- _debuggable = false; // debug mode on or off - default off
- _auth = true; // smtp authentication - default on
- _multipart = new MimeMultipart(); // There is something wrong with
- // MailCap, javamail can not find a
- // handler for the multipart/mixed
- // part, so this bit needs to be
- // added.
- MailcapCommandMap mc = (MailcapCommandMap) CommandMap
- .getDefaultCommandMap();
- mc.addMailcap("text/html;; x-java-content-handler=com.sun.mail.handlers.text_html");
- mc.addMailcap("text/xml;; x-java-content-handler=com.sun.mail.handlers.text_xml");
- mc.addMailcap("text/plain;; x-java-content-handler=com.sun.mail.handlers.text_plain");
- mc.addMailcap("multipart/*;; x-java-content-handler=com.sun.mail.handlers.multipart_mixed");
- mc.addMailcap("message/rfc822;; x-java-content-handler=com.sun.mail.handlers.message_rfc822");
- CommandMap.setDefaultCommandMap(mc);
- }
- public String get_user() {
- return _user;
- }
- public void set_user(String _user) {
- this._user = _user;
- }
- public String get_pass() {
- return _pass;
- }
- public void set_pass(String _pass) {
- this._pass = _pass;
- }
- public String[] get_to() {
- return _to;
- }
- public void set_to(String[] _to) {
- this._to = _to;
- }
- public String get_from() {
- return _from;
- }
- public void set_from(String _from) {
- this._from = _from;
- }
- public String get_port() {
- return _port;
- }
- public void set_port(String _port) {
- this._port = _port;
- }
- public String get_sport() {
- return _sport;
- }
- public void set_sport(String _sport) {
- this._sport = _sport;
- }
- public String get_host() {
- return _host;
- }
- public void set_host(String _host) {
- this._host = _host;
- }
- public String get_subject() {
- return _subject;
- }
- public void set_subject(String _subject) {
- this._subject = _subject;
- }
- public String get_body() {
- return _body;
- }
- public void set_body(String _body) {
- this._body = _body;
- }
- public boolean is_auth() {
- return _auth;
- }
- public void set_auth(boolean _auth) {
- this._auth = _auth;
- }
- public boolean is_debuggable() {
- return _debuggable;
- }
- public void set_debuggable(boolean _debuggable) {
- this._debuggable = _debuggable;
- }
- public Multipart get_multipart() {
- return _multipart;
- }
- public void set_multipart(Multipart _multipart) {
- this._multipart = _multipart;
- }
- public Mails(String user, String pass) {
- this();
- _user = user;
- _pass = pass;
- }
- public boolean send() throws Exception {
- Properties props = _setProperties();
- if (!_user.equals("") && !_pass.equals("") && _to.length > 0
- && !_from.equals("") && !_subject.equals("")
- && !_body.equals("")) {
- Session session = Session.getInstance(props, this);
- MimeMessage msg = new MimeMessage(session);
- msg.setFrom(new InternetAddress(_from));
- InternetAddress[] addressTo = new InternetAddress[_to.length];
- for (int i = 0; i < _to.length; i++) {
- addressTo[i] = new InternetAddress(_to[i]);
- }
- msg.setRecipients(MimeMessage.RecipientType.TO, addressTo);
- msg.setSubject(_subject);
- msg.setSentDate(new Date()); // setup message body
- BodyPart messageBodyPart = new MimeBodyPart();
- messageBodyPart.setText(_body);
- _multipart.addBodyPart(messageBodyPart); // Put parts in message
- msg.setContent(_multipart); // send email
- Transport.send(msg);
- return true;
- } else {
- return false;
- }
- }
- public void addAttachment(String filename) throws Exception {
- BodyPart messageBodyPart = new MimeBodyPart();
- DataSource source = new FileDataSource(filename);
- messageBodyPart.setDataHandler(new DataHandler(source));
- messageBodyPart.setFileName(filename);
- _multipart.addBodyPart(messageBodyPart);
- }
- @Override
- public PasswordAuthentication getPasswordAuthentication() {
- return new PasswordAuthentication(_user, _pass);
- }
- private Properties _setProperties() {
- Properties props = new Properties();
- props.put("mail.smtp.host", _host);
- if (_debuggable) {
- props.put("mail.debug", "true");
- }
- if (_auth) {
- props.put("mail.smtp.auth", "true");
- }
- props.put("mail.smtp.port", _port);
- props.put("mail.smtp.socketFactory.port", _sport);
- props.put("mail.smtp.socketFactory.class",
- "javax.net.ssl.SSLSocketFactory");
- props.put("mail.smtp.socketFactory.fallback", "false");
- return props;
- } // the getters and setters
- public String getBody() {
- return _body;
- }
- public void setBody(String _body) {
- this._body = _body;
- } // more of the getters and setters 锟斤拷.. }
- }
复制代码
代码粘完了,这里采用了线程和异步,对于新手可以学学。【贱泰迪】采用的是第二种方法。
下面开始说一下注意点:
首先加上联网的权限,<uses-permission android:name="android.permission.INTERNET" />,这是小问题
以上代码完成没有问题,但是运行会抛这样的异常:
这是为什么,使用SMTP来发送E-mail,因此您的邮箱必须开启此项服务,
【QQ邮箱】【设置】【账户】【POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务】如下图:
最后附上下载地址:http://download.csdn.net/detail/xiangzhihong8/6661655