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

如果我使用:

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

这将启动内置的Android应用程序;我试图发送邮件按钮点击直接不使用这个应用程序。


当前回答

如果使用“smtp.gmail.com”作为默认的smtp服务器,请注意。

谷歌将迫使您更改您的链接电子邮件帐户密码频繁由于他们过于热心的“可疑活动”政策。本质上,它将短时间内来自不同国家的重复smtp请求视为“可疑活动”。因为他们假设你(电子邮件账户持有人)一次只能在一个国家。

当谷歌系统检测到“可疑活动”时,它将阻止进一步的电子邮件,直到您更改密码。因为你已经将密码硬编码到应用程序中,每次发生这种情况,你都必须重新发布应用程序,这并不理想。这种情况发生在一周内3次对我来说,我甚至存储密码在另一个服务器上,每次谷歌强迫我更改密码时,我都动态地获取密码。

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

其他回答

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

从客户端apk发送电子邮件。这里mail.jar,激活。jar是发送java电子邮件所必需的。如果添加这些罐子,它可能会增加APK大小。 或者,您可以在服务器端代码中使用web服务,它将使用相同的mail.jar和activation.jar发送电子邮件。你可以通过asynctask调用web服务并发送电子邮件。参考相同的链接。

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

为了帮助那些获得网络主线程异常与SDK目标>9。这是使用droopie的代码上面,但将类似于任何工作。

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

StrictMode.setThreadPolicy(policy); 

android.os.NetworkOnMainThreadException

您可以如下所示使用AsyncTask

public void onClickMail(View view) {
    new SendEmailAsyncTask().execute();
}

class SendEmailAsyncTask extends AsyncTask <Void, Void, Boolean> {
    Mail m = new Mail("from@gmail.com", "my password");

    public SendEmailAsyncTask() {
        if (BuildConfig.DEBUG) Log.v(SendEmailAsyncTask.class.getName(), "SendEmailAsyncTask()");
        String[] toArr = { "to mail@gmail.com"};
        m.setTo(toArr);
        m.setFrom("from mail@gmail.com");
        m.setSubject("Email from Android");
        m.setBody("body.");
    }

    @Override
    protected Boolean doInBackground(Void... params) {
        if (BuildConfig.DEBUG) Log.v(SendEmailAsyncTask.class.getName(), "doInBackground()");
        try {
            m.send();
            return true;
        } catch (AuthenticationFailedException e) {
            Log.e(SendEmailAsyncTask.class.getName(), "Bad account details");
            e.printStackTrace();
            return false;
        } catch (MessagingException e) {
            Log.e(SendEmailAsyncTask.class.getName(), m.getTo(null) + "failed");
            e.printStackTrace();
            return false;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

这里是一个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 ….. 
}

在活动中调用它…

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

用Kotlin以编程方式发送电子邮件。

简单的电子邮件发送,没有其他所有功能(如附件)。 TLS始终开启 只有1 gradle电子邮件依赖也需要。

我还发现下面这些邮件POP服务非常有用:

https://support.office.com/en-gb/article/pop-and-imap-email-settings-for-outlook-8361e398-8af4-4e97-b147-6c6c4ac95353

使用方法:

    val auth = EmailService.UserPassAuthenticator("you@gmail.com", "yourPassword")
    val to = listOf(InternetAddress("to@email.com"))
    val from = InternetAddress("you@gmail.com")
    val email = EmailService.Email(auth, to, from, "Test Subject", "Hello Body World")
    val emailService = EmailService("smtp.gmail.com", 465)
    
    GlobalScope.launch { // or however you do background threads
        emailService.send(email)
    }

代码:

import java.util.*
import javax.mail.*
import javax.mail.internet.InternetAddress
import javax.mail.internet.MimeBodyPart
import javax.mail.internet.MimeMessage
import javax.mail.internet.MimeMultipart

class EmailService(private val server: String, private val port: Int) {

    data class Email(
        val auth: Authenticator,
        val toList: List<InternetAddress>,
        val from: Address,
        val subject: String,
        val body: String
    )

    class UserPassAuthenticator(private val username: String, private val password: String) : Authenticator() {
        override fun getPasswordAuthentication(): PasswordAuthentication {
            return PasswordAuthentication(username, password)
        }
    }

    fun send(email: Email) {
        val props = Properties()
        props["mail.smtp.auth"] = "true"
        props["mail.user"] = email.from
        props["mail.smtp.host"] = server
        props["mail.smtp.port"] = port
        props["mail.smtp.starttls.enable"] = "true"
        props["mail.smtp.ssl.trust"] = server
        props["mail.mime.charset"] = "UTF-8"
        val msg: Message = MimeMessage(Session.getDefaultInstance(props, email.auth))
        msg.setFrom(email.from)
        msg.sentDate = Calendar.getInstance().time
        msg.setRecipients(Message.RecipientType.TO, email.toList.toTypedArray())
//      msg.setRecipients(Message.RecipientType.CC, email.ccList.toTypedArray())
//      msg.setRecipients(Message.RecipientType.BCC, email.bccList.toTypedArray())
        msg.replyTo = arrayOf(email.from)

        msg.addHeader("X-Mailer", CLIENT_NAME)
        msg.addHeader("Precedence", "bulk")
        msg.subject = email.subject

        msg.setContent(MimeMultipart().apply {
            addBodyPart(MimeBodyPart().apply {
                setText(email.body, "iso-8859-1")
                //setContent(email.htmlBody, "text/html; charset=UTF-8")
            })
        })
        Transport.send(msg)
    }

    companion object {
        const val CLIENT_NAME = "Android StackOverflow programmatic email"
    }
}

Gradle:

dependencies {
    implementation 'com.sun.mail:android-mail:1.6.4'
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.3"
}

安卓清单:

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

我试着用@Vinayak B提交的代码。然而,我得到一个错误说:没有提供smtp

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

我终于自己修好了。我得用另一个邮件罐 我必须确保我的“不太安全的应用程序访问权限”被打开。

我希望这能帮助那些有同样问题的人。这样做后,这段代码也可以在谷歌玻璃上工作。