javax.mail 不适用于 Marshmallow 或更高版本的系统
javax.mail isn't working on Marshmallow or above systems
我正在尝试使用 javax.mail 包从 android 应用程序发送电子邮件
我发现 this 它在 premarshmallow 操作系统上工作得很好但是当我试图从装有 Marshmallow 或更高版本操作系统的手机发送电子邮件时
Transport.send(message)
挂起并且永远不会 return
这是我的 SendEmailTask
class
public static class SendEmailTask extends AsyncTask<Void, Void, Boolean> {
@Override
protected Boolean doInBackground(Void... params) {
int a=5;
Log.e("ErrorAsync","before out");
try {
Log.e("ErrorAsync","before in");
Transport.send(message);
Log.e("ErrorAsync","after in");
} catch (Exception e) {
e.printStackTrace();
Log.e("ErrorAsync",e.getMessage());
}
Log.e("ErrorAsync","after out");
return true;
}
@Override
protected void onPostExecute(Boolean result) {
}
@Override
protected void onPreExecute() {
if(android.os.Debug.isDebuggerConnected())
android.os.Debug.waitForDebugger();
}
@Override
protected void onProgressUpdate(Void... values) {}
}
logcat输出如下
09-12 08:29:21.872 6498-6542/? E/ErrorAsync: before out
09-12 08:29:21.873 6498-6542/? E/ErrorAsync: before in
我的问题是:
有什么方法可以在 Marshmallow 或更高版本的操作系统上以编程方式发送电子邮件?
我已经使用这个库创建了我的实现,并且很长一段时间以来它都运行良好。所以像下面这样尝试:
JSSEProvider.java
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;
}
});
}
}
MailSender.java
import android.util.Log;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.Security;
import java.util.Properties;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.BodyPart;
import javax.mail.Message;
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 MailSender extends javax.mail.Authenticator {
private String mailhost = "smtp.zoho.com";
private String user;
private String password;
private Session session;
private Multipart _multipart = new MimeMultipart();
static {
Security.addProvider(new JSSEProvider());
}
public MailSender(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);
BodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setText(body);
_multipart.addBodyPart(messageBodyPart);
// Put parts in message
message.setContent(_multipart);
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) {
e.printStackTrace();
}
}
public void addAttachment(String filename) throws Exception {
BodyPart messageBodyPart = new MimeBodyPart();
DataSource source = new FileDataSource(filename);
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName("download image");
_multipart.addBodyPart(messageBodyPart);
}
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");
}
}
}
Mail.java
import android.util.Log;
public class Mail {
String senderId,password,receiverId,subject,body;
public Mail() {
}
public void setSenderId(String senderId) {
this.senderId = senderId;
}
public void setPassword(String password) {
this.password = password;
}
public void setReceiverId(String receiverId) {
this.receiverId = receiverId;
}
public void setSubject(String subject) {
this.subject = subject;
}
public void setBody(String body) {
this.body = body;
}
public void sendMail(){
new Thread(new Runnable() {
public void run() {
try {
MailSender sender = new MailSender(
senderId,
password);
sender.sendMail(subject,
body,
senderId,
receiverId);
} catch (Exception e) {
Log.e("mailError",e.getMessage());
e.printStackTrace();
}
}
}).start();
}
}
将所有这些 class 放在一个包中。
您可以这样发送电子邮件:
Mail email = new Mail();
email.setReceiverId("");
email.setSenderId("");
email.setPassword("");
email.setSubject("");
email.setBody("");
email.sendMail();
备注
根据您的提供商更改 MailSender class 中的 smtp 设置。我用的是zoho mail.
我正在尝试使用 javax.mail 包从 android 应用程序发送电子邮件
我发现 this 它在 premarshmallow 操作系统上工作得很好但是当我试图从装有 Marshmallow 或更高版本操作系统的手机发送电子邮件时
Transport.send(message)
挂起并且永远不会 return
这是我的 SendEmailTask
class
public static class SendEmailTask extends AsyncTask<Void, Void, Boolean> {
@Override
protected Boolean doInBackground(Void... params) {
int a=5;
Log.e("ErrorAsync","before out");
try {
Log.e("ErrorAsync","before in");
Transport.send(message);
Log.e("ErrorAsync","after in");
} catch (Exception e) {
e.printStackTrace();
Log.e("ErrorAsync",e.getMessage());
}
Log.e("ErrorAsync","after out");
return true;
}
@Override
protected void onPostExecute(Boolean result) {
}
@Override
protected void onPreExecute() {
if(android.os.Debug.isDebuggerConnected())
android.os.Debug.waitForDebugger();
}
@Override
protected void onProgressUpdate(Void... values) {}
}
logcat输出如下
09-12 08:29:21.872 6498-6542/? E/ErrorAsync: before out
09-12 08:29:21.873 6498-6542/? E/ErrorAsync: before in
我的问题是: 有什么方法可以在 Marshmallow 或更高版本的操作系统上以编程方式发送电子邮件?
我已经使用这个库创建了我的实现,并且很长一段时间以来它都运行良好。所以像下面这样尝试:
JSSEProvider.java
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;
}
});
}
}
MailSender.java
import android.util.Log;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.Security;
import java.util.Properties;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.BodyPart;
import javax.mail.Message;
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 MailSender extends javax.mail.Authenticator {
private String mailhost = "smtp.zoho.com";
private String user;
private String password;
private Session session;
private Multipart _multipart = new MimeMultipart();
static {
Security.addProvider(new JSSEProvider());
}
public MailSender(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);
BodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setText(body);
_multipart.addBodyPart(messageBodyPart);
// Put parts in message
message.setContent(_multipart);
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) {
e.printStackTrace();
}
}
public void addAttachment(String filename) throws Exception {
BodyPart messageBodyPart = new MimeBodyPart();
DataSource source = new FileDataSource(filename);
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName("download image");
_multipart.addBodyPart(messageBodyPart);
}
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");
}
}
}
Mail.java
import android.util.Log;
public class Mail {
String senderId,password,receiverId,subject,body;
public Mail() {
}
public void setSenderId(String senderId) {
this.senderId = senderId;
}
public void setPassword(String password) {
this.password = password;
}
public void setReceiverId(String receiverId) {
this.receiverId = receiverId;
}
public void setSubject(String subject) {
this.subject = subject;
}
public void setBody(String body) {
this.body = body;
}
public void sendMail(){
new Thread(new Runnable() {
public void run() {
try {
MailSender sender = new MailSender(
senderId,
password);
sender.sendMail(subject,
body,
senderId,
receiverId);
} catch (Exception e) {
Log.e("mailError",e.getMessage());
e.printStackTrace();
}
}
}).start();
}
}
将所有这些 class 放在一个包中。 您可以这样发送电子邮件:
Mail email = new Mail();
email.setReceiverId("");
email.setSenderId("");
email.setPassword("");
email.setSubject("");
email.setBody("");
email.sendMail();
备注 根据您的提供商更改 MailSender class 中的 smtp 设置。我用的是zoho mail.