To send an email from your app with an attachment like image, video, etc. We can do this by calling 2-3 functions.
First, we need to add some required permission in AndroidManifest.xml as below.
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.GET_ACCOUNTS" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Then add necessary dependency as below,
implementation 'com.google.android.gms:play-services-auth:17.0.0' implementation('com.google.api-client:google-api-client-android:1.23.0') { exclude group: 'org.apache.httpcomponents' } implementation('com.google.apis:google-api-services-gmail:v1-rev82-1.23.0') { exclude group: 'org.apache.httpcomponents' } implementation files('libs/mail.jar') implementation files('libs/activation.jar') implementation files('libs/additionnal.jar')
You can download the above .jar file from below link,
https://code.google.com/archive/p/javamail-android/downloads
Now write code to create Mail with attachment as below,
// Method to create email Params @Throws(MessagingException::class) private fun createEmail( to: List<String>, from: String, subject: String, bodyText: String ): MimeMessage? { val props = Properties() val session: Session = Session.getDefaultInstance(props, null) val email = MimeMessage(session) val fAddress = InternetAddress(from) email.setFrom(fAddress) to.forEachIndexed { index, s -> val tAddress = InternetAddress(s) email.addRecipient(javax.mail.Message.RecipientType.TO, tAddress) } email.subject = subject // Create Multipart object and add MimeBodyPart objects to this object val multipart: Multipart = MimeMultipart() // Changed for adding attachment and text email.setText(bodyText) val textBody: BodyPart = MimeBodyPart() textBody.setText(bodyText) multipart.addBodyPart(textBody) if (fileName != "") { // Create new MimeBodyPart object and set DataHandler object to this object val attachmentBody = MimeBodyPart() val filename: String = fileName // change accordingly val source = FileDataSource(filename) attachmentBody.dataHandler = DataHandler(source) attachmentBody.fileName = filename multipart.addBodyPart(attachmentBody) } //Set the multipart object to the message object email.setContent(multipart) return email }
Then, create a message to send in email,
@Throws(MessagingException::class, IOException::class) private fun createMessageWithEmail(email: MimeMessage): Message? { val bytes = ByteArrayOutputStream() email.writeTo(bytes) val encodedEmail: String = Base64.encodeBase64URLSafeString(bytes.toByteArray()) val message = Message() message.raw = encodedEmail return message }
Finally, send mail. Here you have to run send mail code in the background thread. For that, I have used doAsync of Anko library(Extension of Coroutines).
Dependency for Anko :
implementation "org.jetbrains.anko:anko-commons:0.10.0"
private fun sendEmail() { var mService: Gmail? = null var mLastError = null val transport = AndroidHttp.newCompatibleTransport() val jsonFactory = JacksonFactory.getDefaultInstance() mService = Gmail.Builder( transport, jsonFactory, mCredential ).setApplicationName(resources.getString(R.string.app_name)) .build() // getting Values for to Address, from Address, Subject and Body val user = "me" val to = etEmail.text.trim().toString() val from = mCredential!!.selectedAccountName val subject = "DemoSubject" val body = "Demo body" var mimeMessage: MimeMessage? = null var response = "" val toArrayList = to.split(",") doAsync { try { mimeMessage = createEmail(toArrayList, from, subject, body) var message = createMessageWithEmail(mimeMessage!!) // GMail's official method to send email with oauth2.0 message = mService.users().messages().send(user, message).execute() runOnUiThread { if (message.id != null && message.id != "") { Toast.makeText( this@MainActivity, "Mail sent successfully", Toast.LENGTH_SHORT ) .show() } } println("Message id: " + message.id) println(message.toPrettyString()) } catch (e: UserRecoverableAuthIOException) { startActivityForResult(e.intent, REQUEST_AUTHORIZATION) } catch (e: GoogleJsonResponseException) { runOnUiThread { if (e.details.errors[0].domain.equals("global", true)) { Toast.makeText( this@MainActivity, "Mail not send, Please use Gmail id", Toast.LENGTH_SHORT ) .show() } else { Toast.makeText(this@MainActivity, "Can't send mail", Toast.LENGTH_SHORT) .show() } } } catch (e: Exception) { e.printStackTrace() } } }
Now, set UI component,
btnSendEmail.setOnClickListener { if (!isGooglePlayServicesAvailable()) { acquireGooglePlayServices() } else { startActivityForResult( mCredential!!.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER ) } }
Call sendMail() function from onActivityResult.
You can find full demo code from below link,
https://github.com/android-inheritx/SendMailUsingGmailAPI
Note : You can send mail from the “gmail.com” domain only.