使用JavaMail API在Android中发送电子邮件,而不使用默认/内置应用程序
我正在尝试在Android中创build邮件发送应用程序。
如果我使用:
Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
这将启动内置的Android应用程序; 我试图直接发送button上的邮件, 而不使用此应用程序。
使用Gmail身份validation,使用JavaMail API在Android中发送电子邮件
创build示例项目的步骤:
MailSenderActivity.java
YOUR PACKAGE; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; public class MailSenderActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); final Button send = (Button) this.findViewById(R.id.send); send.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { // TODO Auto-generated method stub try { GMailSender sender = new GMailSender("username@gmail.com", "password"); sender.sendMail("This is Subject", "This is Body", "user@gmail.com", "user@yahoo.com"); } catch (Exception e) { Log.e("SendMail", e.getMessage(), e); } } }); } }
GMailSender.java
YOUR PACKAGE; import javax.activation.DataHandler; import javax.activation.DataSource; import javax.mail.Message; import javax.mail.PasswordAuthentication; import javax.mail.Session; import javax.mail.Transport; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.Security; import java.util.Properties; public class GMailSender extends javax.mail.Authenticator { private String mailhost = "smtp.gmail.com"; private String user; private String password; private Session session; static { Security.addProvider(new com.provider.JSSEProvider()); } public GMailSender(String user, String password) { this.user = user; this.password = password; Properties props = new Properties(); props.setProperty("mail.transport.protocol", "smtp"); props.setProperty("mail.host", mailhost); props.put("mail.smtp.auth", "true"); props.put("mail.smtp.port", "465"); props.put("mail.smtp.socketFactory.port", "465"); props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); props.put("mail.smtp.socketFactory.fallback", "false"); props.setProperty("mail.smtp.quitwait", "false"); session = Session.getDefaultInstance(props, this); } protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(user, password); } public synchronized void sendMail(String subject, String body, String sender, String recipients) throws Exception { try{ MimeMessage message = new MimeMessage(session); DataHandler handler = new DataHandler(new ByteArrayDataSource(body.getBytes(), "text/plain")); message.setSender(new InternetAddress(sender)); message.setSubject(subject); message.setDataHandler(handler); if (recipients.indexOf(',') > 0) message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(recipients)); else message.setRecipient(Message.RecipientType.TO, new InternetAddress(recipients)); Transport.send(message); }catch(Exception e){ } } public class ByteArrayDataSource implements DataSource { private byte[] data; private String type; public ByteArrayDataSource(byte[] data, String type) { super(); this.data = data; this.type = type; } public ByteArrayDataSource(byte[] data) { super(); this.data = data; } public void setType(String type) { this.type = type; } public String getContentType() { if (type == null) return "application/octet-stream"; else return type; } public InputStream getInputStream() throws IOException { return new ByteArrayInputStream(data); } public String getName() { return "ByteArrayDataSource"; } public OutputStream getOutputStream() throws IOException { throw new IOException("Not Supported"); } } }
JSSE提供商
JSSEProvider.java
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * @author Alexander Y. Kleymenov * @version $Revision$ */ import java.security.AccessController; import java.security.Provider; public final class JSSEProvider extends Provider { public JSSEProvider() { super("HarmonyJSSE", 1.0, "Harmony JSSE Provider"); AccessController.doPrivileged(new java.security.PrivilegedAction<Void>() { public Void run() { put("SSLContext.TLS", "org.apache.harmony.xnet.provider.jsse.SSLContextImpl"); put("Alg.Alias.SSLContext.TLSv1", "TLS"); put("KeyManagerFactory.X509", "org.apache.harmony.xnet.provider.jsse.KeyManagerFactoryImpl"); put("TrustManagerFactory.X509", "org.apache.harmony.xnet.provider.jsse.TrustManagerFactoryImpl"); return null; } }); } }
在您的Android项目的以下链接添加3个jar子
- 的mail.jar
- 的activation.jar
- additional.jar
点击这里 – 如何添加外部jar子
不要忘记在清单中添加这一行:
<uses-permission android:name="android.permission.INTERNET" />
只需点击下面的链接,即可更改安全性较低的应用的帐户访问权限 https://www.google.com/settings/security/lesssecureapps
运行该项目并检查您的收件人邮件帐户的邮件。 干杯!
PS不要忘记,你不能从android的任何活动做networking操作。 因此,build议使用AsyncTask
或IntentService
来避免主线程exception的networking。
Jar文件: https : //code.google.com/archive/p/javamail-android/
感谢您提供宝贵的信息。 代码工作正常。 我可以通过添加下面的代码来添加附件。
private Multipart _multipart; _multipart = new MimeMultipart(); public void addAttachment(String filename,String subject) throws Exception { BodyPart messageBodyPart = new MimeBodyPart(); DataSource source = new FileDataSource(filename); messageBodyPart.setDataHandler(new DataHandler(source)); messageBodyPart.setFileName(filename); _multipart.addBodyPart(messageBodyPart); BodyPart messageBodyPart2 = new MimeBodyPart(); messageBodyPart2.setText(subject); _multipart.addBodyPart(messageBodyPart2); } message.setContent(_multipart);
无法连接到SMTP主机:smtp.gmail.com,端口:465
在清单中添加这一行:
<uses-permission android:name="android.permission.INTERNET" />
您可以使用JavaMail API来处理您的电子邮件任务。 JavaMail API在JavaEE包中可用,其jar包可供下载。 可悲的是,它不能直接在Android应用程序中使用,因为它使用的是Android中完全不兼容的AWT组件。
您可以在以下位置findJavaMail的Android端口: http : //code.google.com/p/javamail-android/
将jar添加到您的应用程序并使用SMTP方法
为了帮助那些在SDK目标> 9的情况下获得networking主线程exception。 这是使用上面的droopie的代码,但任何工作都会类似。
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy); android.os.NetworkOnMainThreadException
你可以像下面一样使用AsyncTask
public void onClickMail(View view) { new SendEmailAsyncTask().execute(); } class SendEmailAsyncTask extends AsyncTask <Void, Void, Boolean> { Mail m = new Mail("from@gmail.com", "my password"); public SendEmailAsyncTask() { if (BuildConfig.DEBUG) Log.v(SendEmailAsyncTask.class.getName(), "SendEmailAsyncTask()"); String[] toArr = { "to mail@gmail.com"}; m.setTo(toArr); m.setFrom("from mail@gmail.com"); m.setSubject("Email from Android"); m.setBody("body."); } @Override protected Boolean doInBackground(Void... params) { if (BuildConfig.DEBUG) Log.v(SendEmailAsyncTask.class.getName(), "doInBackground()"); try { m.send(); return true; } catch (AuthenticationFailedException e) { Log.e(SendEmailAsyncTask.class.getName(), "Bad account details"); e.printStackTrace(); return false; } catch (MessagingException e) { Log.e(SendEmailAsyncTask.class.getName(), m.getTo(null) + "failed"); e.printStackTrace(); return false; } catch (Exception e) { e.printStackTrace(); return false; } }
SMTP
使用SMTP是一种方式,其他人已经指出了如何做到这一点。 只要注意,在这样做的时候,你完全避开了内置的邮件应用程序,你将不得不提供SMTP服务器的地址,该服务器的用户名和密码,静态地在你的代码中,或从用户查询。
HTTP
另一种方式将涉及一个简单的服务器端脚本,如PHP,它需要一些URL参数,并使用它们来发送邮件。 这样,您只需要从设备发出一个HTTP请求(很容易就可以使用内置的库),并且不需要在设备上存储SMTPlogin数据。 与直接的SMTP用法相比,这是一个更直接的方式,但是因为从PHP发出HTTP请求和发送邮件非常容易,所以它可能比直接的方式更简单。
邮件应用程序
如果邮件将从他已经在手机上注册的用户默认邮件帐户发送,则必须采取其他方法。 如果您有足够的时间和经验,您可能需要检查Android电子邮件应用程序的源代码,以查看它是否提供了一些无需用户交互(我不知道,但也许有一个)发送邮件的入口点。
也许你甚至可以find一种方式来查询用户帐户的详细信息(所以你可以使用他们的SMTP),虽然我高度怀疑这是可能的,因为这将是一个巨大的安全风险和安全构buildAndroid。
这里是一个替代版本,也适用于我和附件(已发布上面,但完整的版本不像来源链接,人们张贴他们不能得到它的工作,因为它的缺失数据)
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 Mail 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 Mail() { _host = "smtp.gmail.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 Mail(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; } public void setTo(String[] toArr) { // TODO Auto-generated method stub this._to=toArr; } public void setFrom(String string) { // TODO Auto-generated method stub this._from=string; } public void setSubject(String string) { // TODO Auto-generated method stub this._subject=string; } // more of the getters and setters ….. }
并把它称为一个活动…
@Override public void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(R.layout.main); Button addImage = (Button) findViewById(R.id.send_email); addImage.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { Mail m = new Mail("gmailusername@gmail.com", "password"); String[] toArr = {"bla@bla.com", "lala@lala.com"}; m.setTo(toArr); m.setFrom("wooo@wooo.com"); m.setSubject("This is an email sent using my Mail JavaMail wrapper from an Android device."); m.setBody("Email body."); try { m.addAttachment("/sdcard/filelocation"); if(m.send()) { Toast.makeText(MailApp.this, "Email was sent successfully.", Toast.LENGTH_LONG).show(); } else { Toast.makeText(MailApp.this, "Email was not sent.", Toast.LENGTH_LONG).show(); } } catch(Exception e) { //Toast.makeText(MailApp.this, "There was a problem sending the email.", Toast.LENGTH_LONG).show(); Log.e("MailApp", "Could not send email", e); } } }); }
演示100%的工作代码您也可以使用这个答案发送多个电子邮件。
在这里下载项目
第1步:下载邮件,激活,额外的jar文件,并添加到您的项目在Android Studio的库文件夹 。 我添加了一个屏幕截图,见下面的链接
使用Gmail( 使用邮件 )login并开启切换buttonLINK
大多数人忘了这一步,我希望你不会。
第二步:完成这个过程后。 将这些课程复制并粘贴到您的项目中。
GMail.java
import android.util.Log; import java.io.UnsupportedEncodingException; import java.util.List; import java.util.Properties; 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.MimeMessage; public class GMail { final String emailPort = "587";// gmail's smtp port final String smtpAuth = "true"; final String starttls = "true"; final String emailHost = "smtp.gmail.com"; String fromEmail; String fromPassword; List<String> toEmailList; String emailSubject; String emailBody; Properties emailProperties; Session mailSession; MimeMessage emailMessage; public GMail() { } public GMail(String fromEmail, String fromPassword, List<String> toEmailList, String emailSubject, String emailBody) { this.fromEmail = fromEmail; this.fromPassword = fromPassword; this.toEmailList = toEmailList; this.emailSubject = emailSubject; this.emailBody = emailBody; emailProperties = System.getProperties(); emailProperties.put("mail.smtp.port", emailPort); emailProperties.put("mail.smtp.auth", smtpAuth); emailProperties.put("mail.smtp.starttls.enable", starttls); Log.i("GMail", "Mail server properties set."); } public MimeMessage createEmailMessage() throws AddressException, MessagingException, UnsupportedEncodingException { mailSession = Session.getDefaultInstance(emailProperties, null); emailMessage = new MimeMessage(mailSession); emailMessage.setFrom(new InternetAddress(fromEmail, fromEmail)); for (String toEmail : toEmailList) { Log.i("GMail", "toEmail: " + toEmail); emailMessage.addRecipient(Message.RecipientType.TO, new InternetAddress(toEmail)); } emailMessage.setSubject(emailSubject); emailMessage.setContent(emailBody, "text/html");// for a html email // emailMessage.setText(emailBody);// for a text email Log.i("GMail", "Email Message created."); return emailMessage; } public void sendEmail() throws AddressException, MessagingException { Transport transport = mailSession.getTransport("smtp"); transport.connect(emailHost, fromEmail, fromPassword); Log.i("GMail", "allrecipients: " + emailMessage.getAllRecipients()); transport.sendMessage(emailMessage, emailMessage.getAllRecipients()); transport.close(); Log.i("GMail", "Email sent successfully."); } }
SendMailTask.java
import android.app.Activity; import android.app.ProgressDialog; import android.os.AsyncTask; import android.util.Log; import java.util.List; public class SendMailTask extends AsyncTask { private ProgressDialog statusDialog; private Activity sendMailActivity; public SendMailTask(Activity activity) { sendMailActivity = activity; } protected void onPreExecute() { statusDialog = new ProgressDialog(sendMailActivity); statusDialog.setMessage("Getting ready..."); statusDialog.setIndeterminate(false); statusDialog.setCancelable(false); statusDialog.show(); } @Override protected Object doInBackground(Object... args) { try { Log.i("SendMailTask", "About to instantiate GMail..."); publishProgress("Processing input...."); GMail androidEmail = new GMail(args[0].toString(), args[1].toString(), (List) args[2], args[3].toString(), args[4].toString()); publishProgress("Preparing mail message...."); androidEmail.createEmailMessage(); publishProgress("Sending email...."); androidEmail.sendEmail(); publishProgress("Email Sent."); Log.i("SendMailTask", "Mail Sent."); } catch (Exception e) { publishProgress(e.getMessage()); Log.e("SendMailTask", e.getMessage(), e); } return null; } @Override public void onProgressUpdate(Object... values) { statusDialog.setMessage(values[0].toString()); } @Override public void onPostExecute(Object result) { statusDialog.dismiss(); } }
第3步:现在您可以根据您的需要更改此类,也可以使用此类发送多个邮件。 我提供xml和java文件。
activity_mail.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingLeft="20dp" android:paddingRight="20dp" android:paddingTop="30dp"> <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingTop="10dp" android:text="From Email" /> <EditText android:id="@+id/editText1" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#FFFFFF" android:cursorVisible="true" android:editable="true" android:ems="10" android:enabled="true" android:inputType="textEmailAddress" android:padding="5dp" android:textColor="#000000"> <requestFocus /> </EditText> <TextView android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingTop="10dp" android:text="Password (For from email)" /> <EditText android:id="@+id/editText2" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#FFFFFF" android:ems="10" android:inputType="textPassword" android:padding="5dp" android:textColor="#000000" /> <TextView android:id="@+id/textView3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingTop="10dp" android:text="To Email" /> <EditText android:id="@+id/editText3" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#ffffff" android:ems="10" android:inputType="textEmailAddress" android:padding="5dp" android:textColor="#000000" /> <TextView android:id="@+id/textView4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingTop="10dp" android:text="Subject" /> <EditText android:id="@+id/editText4" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#ffffff" android:ems="10" android:padding="5dp" android:textColor="#000000" /> <TextView android:id="@+id/textView5" android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingTop="10dp" android:text="Body" /> <EditText android:id="@+id/editText5" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#ffffff" android:ems="10" android:inputType="textMultiLine" android:padding="35dp" android:textColor="#000000" /> <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Send Email" /> </LinearLayout>
SendMailActivity.java
import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.TextView; import java.util.Arrays; import java.util.List; public class SendMailActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final Button send = (Button) this.findViewById(R.id.button1); send.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { Log.i("SendMailActivity", "Send Button Clicked."); String fromEmail = ((TextView) findViewById(R.id.editText1)) .getText().toString(); String fromPassword = ((TextView) findViewById(R.id.editText2)) .getText().toString(); String toEmails = ((TextView) findViewById(R.id.editText3)) .getText().toString(); List<String> toEmailList = Arrays.asList(toEmails .split("\\s*,\\s*")); Log.i("SendMailActivity", "To List: " + toEmailList); String emailSubject = ((TextView) findViewById(R.id.editText4)) .getText().toString(); String emailBody = ((TextView) findViewById(R.id.editText5)) .getText().toString(); new SendMailTask(SendMailActivity.this).execute(fromEmail, fromPassword, toEmailList, emailSubject, emailBody); } }); } }
注意不要忘记在AndroidManifest.xml文件中添加Internet权限
<uses-permission android:name="android.permission.INTERNET"/>
希望它的工作,如果它不只是下面的评论。
警告如果使用“smtp.gmail.com”作为默认的SMTP服务器的话。
由于Google过度热忱的“可疑活动”政策,Google会强制您经常更改您的链接电子邮件帐户密码。 从本质上来说,它将来自不同国家的短时间内的重复请求视为“可疑活动”。 因为他们认为你(电子邮件账户持有人)一次只能在一个国家。
当谷歌系统检测到“可疑活动”时,它将阻止进一步的电子邮件,直到您更改密码。 正如你将硬编码到应用程序的密码,你必须重新发布应用程序每次发生这种情况,不理想。 这一周发生了三次,我甚至将密码存储在另一台服务器上,并且每次谷歌强迫我改变密码时都会dynamic地提取密码。
所以我推荐使用许多免费的smtp提供者之一而不是“smtp.gmail.com”来避免这个安全问题。 使用相同的代码,但将“smtp.gmail.com”更改为新的smtp转发主机。
编辑:JavaMail 1.5.5 声称支持Android ,所以你不应该需要任何东西。
我已经将最新的JavaMail(1.5.4)移植到Android。 它在Maven Central中可用,只需将以下内容添加到 build.gradle
~~
compile 'eu.ocathain.com.sun.mail:javax.mail:1.5.4'
然后你可以按照官方教程 。
源代码可以在这里find: https : //bitbucket.org/artbristol/javamail-forked-android
GmailBackground是一个小型图书馆,在后台发送电子邮件,无需用户交互:
用法:
BackgroundMail.newBuilder(this) .withUsername("username@gmail.com") .withPassword("password12345") .withMailto("toemail@gmail.com") .withType(BackgroundMail.TYPE_PLAIN) .withSubject("this is the subject") .withBody("this is the body") .withOnSuccessCallback(new BackgroundMail.OnSuccessCallback() { @Override public void onSuccess() { //do some magic } }) .withOnFailCallback(new BackgroundMail.OnFailCallback() { @Override public void onFail() { //do some magic } }) .send();
组态:
dependencies { compile 'com.github.yesidlazaro:GmailBackground:1.2.0' }
权限:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.INTERNET"/>
同样对于附件,您需要设置READ_EXTERNAL_STORAGE权限:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
资源
(我自己testing过)
用附件发送邮件
public class SendAttachment{ public static void main(String [] args){ //to address String to="abc@abc.com";//change accordingly //from address final String user="efg@efg.com";//change accordingly final String password="password";//change accordingly 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); //1) get the session object Properties properties = System.getProperties(); properties.put("mail.smtp.port", "465"); properties.put("mail.smtp.host", "smtp.gmail.com"); properties.put("mail.smtp.socketFactory.port", "465"); properties.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); properties.put("mail.smtp.auth", "true"); properties.put("mail.smtp.port", "465"); Session session = Session.getDefaultInstance(properties, new javax.mail.Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(user,password); } }); //2) compose message try{ MimeMessage message = new MimeMessage(session); message.setFrom(new InternetAddress(user)); message.addRecipient(Message.RecipientType.TO,new InternetAddress(to)); message.setSubject("Hii"); //3) create MimeBodyPart object and set your message content BodyPart messageBodyPart1 = new MimeBodyPart(); messageBodyPart1.setText("How is This"); //4) create new MimeBodyPart object and set DataHandler object to this object MimeBodyPart messageBodyPart2 = new MimeBodyPart(); //Location of file to be attached String filename = Environment.getExternalStorageDirectory().getPath()+"/R2832.zip";//change accordingly DataSource source = new FileDataSource(filename); messageBodyPart2.setDataHandler(new DataHandler(source)); messageBodyPart2.setFileName("Hello"); //5) create Multipart object and add MimeBodyPart objects to this object Multipart multipart = new MimeMultipart(); multipart.addBodyPart(messageBodyPart1); multipart.addBodyPart(messageBodyPart2); //6) set the multiplart object to the message object message.setContent(multipart ); //7) send message Transport.send(message); System.out.println("MESSAGE SENT...."); }catch (MessagingException ex) {ex.printStackTrace();} } }
你有没有考虑使用Apache Commons Net? 自3.3以来,只有一个jar(你可以依靠它使用gradle或maven),你完成了: http ://blog.dahanne.net/2013/06/17/sending-a-mail-in-java- 和Android的使用的Apache公地网/
那些正在得到ClassDefNotFoundError
尝试将三个jar文件移动到您的项目的lib文件夹,它为我工作!
我无法运行Vinayak B的代码。 最后我解决了这个问题如下:
1.使用这个
2.应用AsyncTask。
3.Changing security issue of sender gmail account.(Change to "TURN ON") in this
Without user intervention, you can send as follows:
-
Send email from client apk. Here mail.jar, activation.jar is required to send java email. If these jars are added, it might increase the APK Size.
-
Alternatively, You can use a web-service at the server side code, which will use the same mail.jar and activation.jar to send email. You can call the web-service via asynctask and send email. Refer same link.
(But, you will need to know the credentials of the mail account)
Add jar files mail.jar,activation.jar,additionnal.jar String sub="Thank you for your online registration" ; Mail m = new Mail("emailid", "password"); String[] toArr = {"ekkatrainfo@gmail.com",sEmailId}; m.setFrom("ekkatrainfo@gmail.com"); m.setTo(toArr); m.setSubject(sub); m.setBody(msg); try{ if(m.send()) { } else { } } catch(Exception e) { Log.e("MailApp", "Could not send email", e); } package com.example.ekktra; 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 Mail 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 Mail() { _host = "smtp.gmail.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 Mail(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; } public void setTo(String[] toArr) { // TODO Auto-generated method stub this._to=toArr; } public void setFrom(String string) { // TODO Auto-generated method stub this._from=string; } public void setSubject(String string) { // TODO Auto-generated method stub this._subject=string; } }
In case that you are demanded to keep the jar library as small as possible, you can include the SMTP/POP3/IMAP function separately to avoid the "too many methods in the dex" problem.
You can choose the wanted jar libraries from the javanet web page , for example, mailapi.jar + imap.jar can enable you to access icloud, hotmail mail server in IMAP protocol. (with the help of additional.jar and activation.jar)
I tried using the code that @Vinayak B submitted. However I'm getting an error saying: No provider for smtp
I created a new question for this with more information HERE
I was able to fix it myself after all. I had to use an other mail.jar and I had to make sure my " access for less secure apps " was turned on.
I hope this helps anyone who has the same problem. With this done, this piece of code works on the google glass too.
All the code provided in the other answers is correct and is working fine, but a bit messy, so I decided to publish a library (still in development though) to use it in a easier way: AndroidMail .
You have just to create a MailSender, build a mail and send it (already handled in background with an AsyncTask).
MailSender mailSender = new MailSender(email, password); Mail.MailBuilder builder = new Mail.MailBuilder(); Mail mail = builder .setSender(senderMail) .addRecipient(new Recipient(recipient)) .setText("Hello") .build(); mailSender.sendMail(mail);
You can receive a notification for the email sent and it has also the support for different Recipients types (TO, CC and BCC), attachments and html:
MailSender mailSender = new MailSender(email, password); Mail.MailBuilder builder = new Mail.MailBuilder(); Mail mail = builder .setSender(senderMail) .addRecipient(new Recipient(recipient)) .addRecipient(new Recipient(Recipient.TYPE.CC, recipientCC)) .setText("Hello") .setHtml("<h1 style=\"color:red;\">Hello</h1>") .addAttachment(new Attachment(filePath, fileName)) .build(); mailSender.sendMail(mail, new MailSender.OnMailSentListener() { @Override public void onSuccess() { // mail sent! } @Override public void onError(Exception error) { // something bad happened :( } });
You can get it via Gradle or Maven:
compile 'it.enricocandino:androidmail:1.0.0-SNAPSHOT'
Please let me know if you have any issue with it! 🙂
These sources explain to you step by step what actually each code line does:
-
Sending email with attachment using JavaMail API
-
Send e-mail with attachment in Java
-
Download attachments in e-mail messages using JavaMail
To add attachment, don't forget to add.
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);