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

Vin*_*tti 638 java email android jakarta-mail android-intent

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

如果我使用:

Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
Run Code Online (Sandbox Code Playgroud)

这将启动内置的Android应用程序; 我正在尝试直接发送邮件,而不使用此应用程序.

Vin*_*tti 747

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

创建示例项目的步骤:

MailSenderActivity.java:

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("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);   
                } 

            }
        });

    }
}
Run Code Online (Sandbox Code Playgroud)

GMailSender.java:

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");   
        }   
    }   
}  
Run Code Online (Sandbox Code Playgroud)

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;
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

在您的Android项目的以下链接中添加3个罐子

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

并且不要忘记在清单中添加此行:

<uses-permission android:name="android.permission.INTERNET" />
Run Code Online (Sandbox Code Playgroud)

只需点击以下链接即可更改安全性较低的应用的帐户访问权限 https://www.google.com/settings/security/lesssecureapps

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

PS并且不要忘记你不能从android中的任何Activity做网络操作.因此,建议在主线程异常时使用AsyncTaskIntentService避免网络.

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

  • 对于抱怨/询问如何获取用户密码的人 - 这不是这里的想法.这适用于您的(开发人员)电子邮件帐户.如果您想依赖用户的电子邮件帐户,您应该使用电子邮件意图,这在其他帖子中有广泛讨论. (51认同)
  • 您的代码似乎使用硬编码的用户名和密码.这目前是一个安全风险(意味着,上传到市场的apk是否被反编译)? (49认同)
  • 无论如何在没有将密码放入代码的情况下收到电子邮件?如果我要求他们发送电子邮件,我认为用户会感到震惊...... (12认同)
  • 为我工作!!! 不要忘记向您的应用程序清单添加使用权限INTERNET (10认同)
  • 嗨感谢您的代码.但是我在GMailSender发件人上获得了java.lang.NoClassDefFoundError =关于mailsenderactivity的新GMailSender(...).我包括所有罐子并添加到构建路径.我花了一些时间来解决它.但我没有得到解决方案.请帮我. (7认同)
  • 这段代码适用于Android 2.3但不是最新版本的android 4.0.表示不在android 4.0.3上发送邮件 (6认同)
  • 您在GMailSender.sendMail()中遇到问题.问题是没有错误超出sendMail,因为你在其中包含所有代码的try..catch.你应该从sendMail中删除try..catch.否则就无法检测到错误 (5认同)
  • 我收到java.lang.NoClassDefFoundError:com.som.mail.GMailSender ???? 可能是什么原因 ?该课程在我的项目中,但这个例外即将到来. (5认同)
  • 这里似乎是[这个答案代码的原始链接](http://www.ssaurel.com/blog/how-to-send-an-email-with-javamail-api-in-android/),以及附加说明(即,您需要[在Gmail帐户上启用安全性较低的应用](https://www.google.com/settings/security/lesssecureapps)).另一个[相关教程](http://www.jondev.net/articles/Sending_Emails_without_User_Intervention_(no_Intents)_in_Android). (5认同)
  • 是否可以使用它来附加jpeg? (4认同)
  • 对于那些遇到Android 4问题的人,请按照http://www.jondev.net/articles/Sending_Emails_without_User_Intervention_%28no_Intents%29_in_Android教程进行操作,并从`AsyncTask`执行实际发送. (4认同)
  • 考虑到逆向工程APK包的容易程度,您认为这是一种安全的方法吗?我的意思是,用纯文本存储密码对我来说听起来不太好...... (4认同)
  • 是否可以发送没有硬编码用户名和密码的邮件? (3认同)
  • 如果有人害怕他的密码,你可以把它放在资源中并在代码中使用它.我反编译了一些应用程序,无法获取任何xml文件内容,只有java文件. (3认同)
  • 这一行:Security.addProvider(new com.provider.JSSEProvider()); 在GmailSender.java中突出显示为错误.有谁知道这行代码的解决方案?我的包名是什么需要指出的?谢谢 (3认同)
  • 它对我来说不适合我用permision的相同代码.没有错误但没有发送邮件 (3认同)
  • @Vinayak B.:问题是:你如何获得这些信息?"username@gmail.com","密码" (3认同)
  • 因为这里的3个罐子的链接已经死了是一个更新:https://code.google.com/archive/p/javamail-android/downloads (3认同)
  • 这仍然有效吗?我试过了,但没有错误,但也没有电子邮件。 (3认同)
  • @Vinayank你知道我们如何检查发送的邮件是成功还是失败? (2认同)
  • 我收到此错误javax.mail.MessagingException:未知的SMTP主机:smtp.gmail.com; (2认同)
  • 所以我们必须向用户询问他们的密码才能完成这项工作?这不会降低客户互动。 (2认同)
  • 不是直接链接到 JAR,而是链接到项目页面。您需要遵守 android-javamail 的许可证 (2认同)
  • 非常感谢.这段代码有效.有没有办法使用此代码通过电子邮件发送文件. (2认同)
  • 像@AndroidDev一样,即使使用2.3也是同样的问题.将尝试其他解决方案. (2认同)
  • 嗨frdz它不适合我..Error :: android.os.NetworkOnMainThreadException (2认同)
  • 只需点击下方链接即可停用安全检查https://www.google.com/settings/security/lesssecureapps (2认同)
  • 大家好,你能帮帮我吗?我没有收到任何错误,但我的测试收件人电子邮件没有收到邮件。有谁知道这可能的原因? (2认同)
  • 除非您添加新线程,否则这将无法工作:请参见此处http://www.ssaurel.com/blog/how-to-send-an-email-with-javamail-api-in-android/ (2认同)
  • 没有异常或错误,但没有电子邮件收件箱或垃圾邮件 (2认同)

ash*_*ddy 69

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

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);
Run Code Online (Sandbox Code Playgroud)

  • 你在哪里附上这段代码?你能告诉我吗? (7认同)
  • 将其添加到GmailSender.java (6认同)

小智 54

无法连接到SMTP主机:smtp.gmail.com,port:465

在清单中添加以下行:

<uses-permission android:name="android.permission.INTERNET" />
Run Code Online (Sandbox Code Playgroud)

  • 这不是解决方案,但没有它它不会工作 (26认同)

Ksh*_*wal 39

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

您可以在以下位置找到适用于JavaMail的Android端口:http: //code.google.com/p/javamail-android/

将jar添加到您的应用程序并使用SMTP方法

  • 我已经移植了最新的JavaMail,它可以在Maven Central的"eu.ocathain.com.sun.mail:javax.mail:1.5.2"下找到. (6认同)

Rya*_*ner 28

为了帮助那些使用SDK Target> 9获得网络主线程异常的人.这是使用上面的droopie代码,但对任何代码都可以使用.

StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();

StrictMode.setThreadPolicy(policy); 

android.os.NetworkOnMainThreadException
Run Code Online (Sandbox Code Playgroud)

您可以使用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;
        }
    }
Run Code Online (Sandbox Code Playgroud)


Len*_*mel 23

SMTP

使用SMTP是一种方法,其他人已经指出了如何做到这一点.请注意,在执行此操作时,您完全绕过内置邮件应用程序,并且必须在代码中静态提供SMTP服务器的地址,该服务器的用户名和密码,或者从用户查询.

HTTP

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

邮件申请

如果邮件应从他已在手机上注册的用户默认邮件帐户发送,则您必须采取其他方法.如果您有足够的时间和经验,您可能需要查看Android电子邮件应用程序的源代码,看看它是否提供了一些无需用户交互即可发送邮件的入口点(我不知道,但也许有一个).

也许您甚至找到了一种查询用户帐户详细信息的方法(因此您可以将它们用于SMTP),但我非常怀疑这是可能的,因为这将是一个巨大的安全风险,并且Android的构建相当安全.


Arp*_*tel 23

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

这里下载项目

步骤1: 下载邮件,激活,附加jar文件,并在android studio中添加项目libs文件夹.我添加了一个屏幕截图,见下面的链接

libs添加

使用Gmail登录(使用您的邮件)和TURN ON 切换按钮LINK

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

第2步: 完成此过程后.将这些类复制并过去到您的项目中.

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.");
    }

}
Run Code Online (Sandbox Code Playgroud)

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

}
Run Code Online (Sandbox Code Playgroud)

第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>
Run Code Online (Sandbox Code Playgroud)

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);
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

注意不要忘记在AndroidManifest.xml文件中添加Internet权限

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

希望它能工作,如果不是那么只是在下面评论.

  • 这样安全吗?如果我用硬编码的用户和密码替换"fromEmail"和"fromPassword",我是否必须担心安全问题? (2认同)

小智 22

这是一个alt版本,也适用于我,并有附件(上面已经发布但完整版本不同于源链接,人们发布他们不能让它工作,因为它缺少数据)

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 ….. 
}
Run Code Online (Sandbox Code Playgroud)

并在活动中称呼它...

@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); 
      } 
    } 
  }); 
} 
Run Code Online (Sandbox Code Playgroud)

  • 对于javax.mail.AuthenticationFailedException,您需要启用此设置https://www.google.com/settings/security/lesssecureapps (2认同)

Mar*_*ark 13

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

由于过度热心的"可疑活动"政策,Google会强制您经常更改关联的电子邮件帐户密码.实质上,它在短时间内将来自不同国家的重复smtp请求视为"可疑活动".因为他们认为您(电子邮件帐户持有人)一次只能在一个国家/地区.

当谷歌系统检测到"可疑活动"时,它将阻止更多电子邮件,直到您更改密码.由于您将密码硬编码到应用程序中,因此每次发生这种情况时都必须重新发布应用程序,这并不理想.这对我来说每周发生3次,我甚至将密码存储在另一台服务器上,并且每次google强制我更改密码时动态获取密码.

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

  • 这是一个好点。但是,您能否举一个使用代码的备用电子邮件提供商的示例(仅替换 smtp 和登录详细信息)。我已经用 hushmail 和 email.com 试过了,但没有成功。会继续和其他人一起尝试。 (2认同)

S.R*_*S.R 11

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();
Run Code Online (Sandbox Code Playgroud)

组态:

repositories {
    // ...
    maven { url "https://jitpack.io" }
 }
 dependencies {
            compile 'com.github.yesidlazaro:GmailBackground:1.2.0'
    }
Run Code Online (Sandbox Code Playgroud)

权限:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
Run Code Online (Sandbox Code Playgroud)

另外,对于附件,您需要设置READ_EXTERNAL_STORAGE权限:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
Run Code Online (Sandbox Code Playgroud)

资源

(我自己测试过)


art*_*tol 7

编辑: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'
Run Code Online (Sandbox Code Playgroud)

然后,您可以按照官方教程.

源代码可在此处获取:https://bitbucket.org/artbristol/javamail-forked-android


Shr*_*nda 7

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

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 = "username@gmail.com";
        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("from-email@gmail.com"));
            message.setRecipients(Message.RecipientType.TO,
                InternetAddress.parse("to-email@gmail.com"));
            message.setSubject("Testing Subject");
            message.setText("Dear Mail Crawler,"
                + "\n\n No spam to my email, please!");

            Transport.send(message);

            System.out.println("Done");

        } catch (MessagingException e) {
            throw new RuntimeException(e);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

希望这可以帮助!祝好运!


Ras*_*hid 5

用于发送带有附件的邮件..

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();}
                  }
                }
Run Code Online (Sandbox Code Playgroud)


小智 5

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


归档时间:

查看次数:

414756 次

最近记录:

6 年 前