For those who want to use JavaMail with Kotlin in 2020:
First: Add these dependencies to your build.gradle file (official JavaMail Maven Dependencies)
implementation 'com.sun.mail:android-mail:1.6.5'
implementation 'com.sun.mail:android-activation:1.6.5'
implementation "org.bouncycastle:bcmail-jdk15on:1.65"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.7"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.7"
BouncyCastle is for security reasons.
Second: Add these permissions to your AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Third: When using SMTP, create a Config file
object Config { const val EMAIL_FROM = "You_Sender_Email@email.com" const val PASS_FROM = "Your_Sender_Password" const val EMAIL_TO = "Your_Destination_Email@email.com"}
Fourth: Create your Mailer Object
object Mailer {init { Security.addProvider(BouncyCastleProvider())}private fun props(): Properties = Properties().also { // Smtp server it["mail.smtp.host"] = "smtp.gmail.com" // Change when necessary it["mail.smtp.auth"] = "true" it["mail.smtp.port"] = "465" // Easy and fast way to enable ssl in JavaMail it["mail.smtp.ssl.enable"] = true }// Dont ever use "getDefaultInstance" like other examples do!private fun session(emailFrom: String, emailPass: String): Session = Session.getInstance(props(), object : Authenticator() { override fun getPasswordAuthentication(): PasswordAuthentication { return PasswordAuthentication(emailFrom, emailPass) }})private fun builtMessage(firstName: String, surName: String): String { return """<b>Name:</b> $firstName <br/><b>Surname:</b> $surName <br/>""".trimIndent()}private fun builtSubject(issue: String, firstName: String, surName: String):String { return """ $issue | $firstName, $surName""".trimIndent()}private fun sendMessageTo(emailFrom: String, session: Session, message: String, subject: String) { try { MimeMessage(session).let { mime -> mime.setFrom(InternetAddress(emailFrom)) // Adding receiver mime.addRecipient(Message.RecipientType.TO, InternetAddress(Config.EMAIL_TO)) // Adding subject mime.subject = subject // Adding message mime.setText(message) // Set Content of Message to Html if needed mime.setContent(message, "text/html") // send mail Transport.send(mime) } } catch (e: MessagingException) { Log.e("","") // Or use timber, it really doesn't matter }}fun sendMail(firstName: String, surName: String) { // Open a session val session = session(Config.EMAIL_FROM, Config.PASSWORD_FROM) // Create a message val message = builtMessage(firstName, surName) // Create subject val subject = builtSubject(firstName, surName) // Send Email CoroutineScope(Dispatchers.IO).launch { sendMessageTo(Config.EMAIL_FROM, session, message, subject) }}
Note
- If you want a more secure way to send your email (and you want a more secure way!), use http as mentioned in the solutions before (I will maybe add it later in this answer)
- You have to properly check, if the users phone has internet access, otherwise the app will crash.
- When using gmail, enable "less secure apps" (this will not work, when you gmail has two factors enabled) https://myaccount.google.com/lesssecureapps?pli=1
- Some credits belong to: https://medium.com/@chetan.garg36/android-send-mails-not-intent-642d2a71d2ee (he used RxJava for his solution)