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

如果我使用:

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

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


当前回答

要加附件,别忘了加。

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

其他回答

这里有很多解决方案。然而,我认为我们必须改变GMail的配置,以允许从不太安全的设备访问。转到下面的链接并启用它。这对我很有用

https://myaccount.google.com/lesssecureapps?pli=1

用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" />

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

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

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

为了帮助那些获得网络主线程异常与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;
        }
    }

SMTP

使用SMTP是一种方法,其他方法已经指出了如何做到这一点。请注意,在这样做的时候,您完全绕过了内置的邮件应用程序,并且必须提供SMTP服务器的地址、该服务器的用户名和密码,可以在代码中静态地提供,也可以从用户那里查询。

HTTP

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

邮件应用程序

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

也许你甚至可以找到一种方法来查询用户的帐户详细信息(这样你就可以将它们用于SMTP),尽管我高度怀疑这是可能的,因为这将是一个巨大的安全风险,而Android是建立得相当安全。