关于java:使用JavaMail API在Android中发送电子邮件,而不使用默认/内置应用程序

Sending Email in Android using JavaMail API without using the default/built-in app

我正在尝试在Android中创建一个邮件发送应用程序。

如果我使用:

1
Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);

这将启动内置的Android应用程序;我正在尝试不使用此应用程序直接单击"邮件发送"按钮。


使用JavaMail API使用Gmail身份验证在Android中发送电子邮件。

创建示例项目的步骤:

mail发送活动.java:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class MailSenderActivity extends Activity {

    @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) {
                try {  
                    GMailSender sender = new GMailSender("[email protected]","password");
                    sender.sendMail("This is Subject",  
                           "This is Body",  
                           "[email protected]",  
                           "[email protected]");  
                } catch (Exception e) {  
                    Log.e("SendMail", e.getMessage(), e);  
                }

            }
        });

    }
}

gmail发送程序.java:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
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");  
        }  
    }  
}

jsseprovider.java版本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/*
 *  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;
            }
        });
    }
}

在以下链接中添加3个jar到您的Android项目中

  • 小精灵
  • 活化罐
  • 加法罐

单击此处-如何添加外部JAR

别忘了在清单中添加这一行:

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

只需单击下面的链接,即可更改安全性较低的应用程序的帐户访问权限。https://www.google.com/settings/security/lessecureapps

运行项目并检查收件人的邮件帐户。干杯!

另外,别忘了,在Android中,你不能通过任何活动进行网络操作。因此,建议使用AsyncTaskIntentService来避免主线程上的网络异常。

JAR文件:https://code.google.com/archive/p/javamail-android/


感谢您提供宝贵的信息。代码工作正常。我也可以通过添加以下代码来添加附件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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);


Could not connect to SMTP host:
smtp.gmail.com, port: 465

在清单中添加此行:

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


您可以使用JavaMail API来处理电子邮件任务。javamail API在javaee包中提供,其jar可供下载。遗憾的是,它不能直接在Android应用程序中使用,因为它使用的awt组件在Android中完全不兼容。

您可以在以下位置找到Javamail的Android端口:网址:http://code.google.com/p/javamail-android/

将JAR添加到应用程序并使用SMTP方法


为了帮助那些在主线程上获取网络异常,sdk目标>9。这是使用上面的Droopie代码,但对任何代码都是类似的。

1
2
3
4
5
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();

StrictMode.setThreadPolicy(policy);

android.os.NetworkOnMainThreadException

您可以如下使用AsyncTask

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public void onClickMail(View view) {
    new SendEmailAsyncTask().execute();
}

class SendEmailAsyncTask extends AsyncTask <Void, Void, Boolean> {
    Mail m = new Mail("[email protected]","my password");

    public SendEmailAsyncTask() {
        if (BuildConfig.DEBUG) Log.v(SendEmailAsyncTask.class.getName(),"SendEmailAsyncTask()");
        String[] toArr = {"to [email protected]"};
        m.setTo(toArr);
        m.setFrom("from [email protected]");
        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服务器的地址、该服务器的用户名和密码,或者从用户那里查询。

超文本传输协议

另一种方法是使用一个简单的服务器端脚本(如php),该脚本接受一些URL参数并使用它们发送邮件。这样,您只需要从设备发出HTTP请求(使用内置库很容易实现),而不需要在设备上存储SMTP登录数据。与直接使用smtp相比,这是另外一种间接方式,但是由于从php发出HTTP请求和发送邮件非常容易,所以它可能比直接方式更简单。

邮件应用程序

如果邮件是从用户默认的邮件帐户发送的,而该帐户已经在电话中注册了,那么您必须采取其他方法。如果你有足够的时间和经验,你可能想检查Android电子邮件应用程序的源代码,看看它是否提供了一些入口点来发送没有用户交互的邮件(我不知道,但可能有一个)。

也许你甚至可以找到一种查询用户帐户详细信息的方法(这样你就可以将其用于SMTP),但我强烈怀疑这是可能的,因为这将是一个巨大的安全风险,并且安卓系统的构建相当安全。


100%带演示的工作代码,您也可以使用此答案发送多封电子邮件。

在此处下载项目

步骤1:下载邮件、激活、添加jar文件,并在Android Studio中添加到项目libs文件夹中。我添加了一个屏幕截图,见下面的下载链接

libs add

使用gmail登录(使用您的"从邮件"登录)并打开切换按钮链接

大多数人忘记了这一步,我希望你不会。

步骤2:完成此过程后。将这些类复制并传递到您的项目中。

爪哇

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
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.");
    }

}

发送邮件任务.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
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文件。

活动u mail.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
<?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>

发送邮件活动.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
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权限

希望它能起作用,如果它不起作用,那就在下面评论一下。


这里有一个alt版本,它也适用于我,并且有附件(已经在上面发布了,但与源链接不同的是,源链接是完整的,人们发布了,因为它缺少数据,所以无法让它工作)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
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 …..
}

在活动中调用它…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
@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("[email protected]","password");

      String[] toArr = {"[email protected]","[email protected]"};
      m.setTo(toArr);
      m.setFrom("[email protected]");
      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);
      }
    }
  });
}


如果使用"smtp.gmail.com"作为默认的smtp服务器,则发出警告。

谷歌会强迫你经常更改你的链接电子邮件帐户密码,因为他们过于热心的"可疑活动"政策。本质上,它将不同国家在短时间内重复发出的SMTP请求视为"可疑活动"。因为他们认为你(电子邮件帐户持有人)一次只能在一个国家。

当谷歌系统检测到"可疑活动"时,它将阻止更多的电子邮件,直到您更改密码。由于你已经将密码硬编码到应用程序中,所以每次发生这种情况时,你都必须重新发布应用程序,这并不理想。这在一周内发生了3次,我甚至把密码存储在另一台服务器上,每次谷歌强迫我更改密码时,我都会动态地获取密码。

因此,我建议使用许多免费的SMTP提供程序之一,而不是"smtp.gmail.com",以避免出现这种安全问题。使用相同的代码,但将"smtp.gmail.com"更改为新的smtp转发主机。


GmailBackground is small library to send an email in background without user interaction :

用途:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    BackgroundMail.newBuilder(this)
            .withUsername("[email protected]")
            .withPassword("password12345")
            .withMailto("[email protected]")
            .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();

配置:

1
2
3
4
5
6
7
repositories {
    // ...
    maven { url"https://jitpack.io" }
 }
 dependencies {
            compile 'com.github.yesidlazaro:GmailBackground:1.2.0'
    }

权限:

1
2
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>

对于附件,还需要设置读取外部存储权限:

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

来源

(我自己测试过)


编辑:Javamail 1.5.5声称支持Android,所以你不需要其他任何东西。

<罢工>我把最新的Javamail(1.5.4)移植到了Android上。在Maven Central有售,只需在build.gradle中添加以下内容即可~~

1
compile 'eu.ocathain.com.sun.mail:javax.mail:1.5.4'

然后,您可以按照官方教程进行操作。

源代码可从以下网址获取:https://bitback.org/artbristol/javamail-forked-android

< /打击>


我为其他需要帮助的人找到了一个较短的选择。代码是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package com.example.mail;

import java.util.Properties;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

public class SendMailTLS {

    public static void main(String[] args) {

        final String username ="[email protected]";
        final String password ="password";

        Properties props = new Properties();
        props.put("mail.smtp.auth","true");
        props.put("mail.smtp.starttls.enable","true");
        props.put("mail.smtp.host","smtp.gmail.com");
        props.put("mail.smtp.port","587");

        Session session = Session.getInstance(props,
          new javax.mail.Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication("username","password");
            }
          });

        try {

            Message message = new MimeMessage(session);
            message.setFrom(new InternetAddress("[email protected]"));
            message.setRecipients(Message.RecipientType.TO,
                InternetAddress.parse("[email protected]"));
            message.setSubject("Testing Subject");
            message.setText("Dear Mail Crawler,"
                +"

 No spam to my email, please!"
);

            Transport.send(message);

            System.out.println("Done");

        } catch (MessagingException e) {
            throw new RuntimeException(e);
        }
    }
}

来源:通过Javamail API发送电子邮件

希望这有帮助!祝你好运!


那些得到ClassDefNotFoundError的人试图将这三个jar文件移动到项目的lib文件夹中,这对我很有用!!


发送带有附件的邮件…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
public class SendAttachment{
                    public static void main(String [] args){
             //to address
                    String to="[email protected]";//change accordingly
                    //from address
                    final String user="[email protected]";//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();}
                  }
                }


我无法运行Vinayak B的代码。最后,我通过以下方式解决了这个问题:

1、使用此

2.应用异步任务。

3.更改发件人gmail帐户的安全问题。(更改为"打开")。


你考虑过使用ApacheCommons网络吗?从3.3开始,只需一个jar(并且您可以使用Gradle或Maven依赖它),就可以完成:http://blog.dahanne.net/2013/06/17/sending-a-mail-in-java-and-android-with-apache-commons-net/


无需用户干预,您可以按如下方式发送:

  • 从客户端APK发送电子邮件。这里,May.jar,Actudio.Jar需要发送Java电子邮件。如果添加这些罐子,可能会增加APK大小。

  • 或者,您可以在服务器端使用Web服务代码,该代码将使用相同的mail.jar和activation.jar来发送电子邮件。您可以通过AsyncTask调用Web服务并发送电子邮件。请参阅同一链接。

  • (但是,您需要知道邮件帐户的凭据)


    如果需要尽可能保持JAR库的小,可以单独包含smtp/pop3/imap函数,以避免"dex中的方法太多"问题。

    您可以从JavaNet网页中选择所需的JAR库,例如,mailapi.jar+imap.jar允许您以imap协议访问iCloud、hotmail邮件服务器。(在additional.jar和activation.jar的帮助下)


    我尝试使用@vinayak b提交的代码。但是,我收到一个错误消息:没有用于SMTP的提供程序

    我在这里创建了一个新问题,并提供了更多信息

    毕竟我自己能修好。我不得不用另一封邮件.jar我必须确保我的"访问不太安全的应用程序"已打开。

    我希望这能帮助任何有同样问题的人。完成后,这段代码也可以在Google Glass上工作。


    其他答案中提供的所有代码都是正确的,并且工作正常,但是有点混乱,所以我决定发布一个库(尽管仍在开发中)以更简单的方式使用它:androidmail。

    您只需创建一个邮件发送者,构建一个邮件并发送它(已经在后台用异步任务处理过)。

    4

    您可以接收所发送电子邮件的通知,它还支持不同的收件人类型(收件人、抄送和密件抄送)、附件和HTML:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    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")
        .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 :(
        }
    });

    您可以通过Gradle或Maven获得:

    1
    compile 'it.enricocandino:androidmail:1.0.0-SNAPSHOT'

    如果你有什么问题,请告诉我!:)


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
     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 = {"[email protected]",sEmailId};
     m.setFrom("[email protected]");

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


       }

    要添加附件,请不要忘记添加。

    1
    2
    3
    4
    5
    6
    7
    8
    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);