Explain Codes LogoExplain Codes Logo

Sending Email in Android using JavaMail API without using the default/built-in app

java
async-task
email-api
network-operations
Anton ShumikhinbyAnton Shumikhin·Sep 19, 2024
TLDR

Here's a quick guide on sending emails in Android using the JavaMail API:

Add the following dependencies in your build.gradle:

// Your trusty postman delivering your emails implementation 'com.sun.mail:android-mail:1.6.6' // Big brother who tells the postman what to do implementation 'com.sun.mail:android-activation:1.6.6'

Setup SMTP properties:

Properties props = new Properties(); props.put("mail.smtp.auth", "true"); // Knock knock, it's your postman props.put("mail.smtp.host", "smtp.gmail.com"); // Postman knows where to go props.put("mail.smtp.port", "587"); props.put("mail.smtp.starttls.enable", "true"); // Postman wears a helmet

Authenticate and send without an external client:

Session session = Session.getDefaultInstance(props, new Authenticator() { @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication("[email protected]", "your-password"); // Postman needs your key to the mailbox } }); Message message = new MimeMessage(session); message.setFrom(new InternetAddress("[email protected]")); message.setRecipient(Message.RecipientType.TO, new InternetAddress("[email protected]")); message.setSubject("Your Subject Here"); message.setText("Email body content"); Transport.send(message); // Off the postman goes

Remember to replace the placeholders with your actual credentials and email details. Also ensure that you have added Internet permission in your AndroidManifest.xml.

Deep dive: A developer's guide to email dispatch

1. Granting permissions: The all-access pass

Your app definitely needs the Internet permission. Make sure you've included this in your AndroidManifest.xml:

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

2. Async task: No more frozen UI screens

Asynchronous dispatch of emails is crucial for smooth user experience. Let's leverage AsyncTask or IntentService:

// And Async Task saves the day! new AsyncTask<Void, Void, Void>() { @Override protected Void doInBackground(Void... voids) { // Because neither users nor Postman likes waiting Transport.send(message); return null; } }.execute();

3. Big documents and MIME Type: No file left behind

Need to include attachments? Gear up with MimeMultipart and FileDataSource:

// The carry bag for your files MimeBodyPart messageBodyPart = new MimeBodyPart(); MimeMultipart multipart = new MimeMultipart(); messageBodyPart.setDataHandler(new DataHandler(new FileDataSource(file))); messageBodyPart.setFileName(file.getName()); multipart.addBodyPart(messageBodyPart); // Look mom, no hands: Attaching files like a pro message.setContent(multipart);

4. App Passwords: When an extra lock doesn’t hurt

In case of 2FA with Gmail, you gotta use an App Password. Change the necessary settings under your Google account security.

5. No more NetworkOnMainThreadException

Using a separate thread or AsyncTask for network operations will give NetworkOnMainThreadException a pass.

Advanced concepts and handling exceptions

6. Gmail Settings: Secure, but not too stubborn

Google could block less secure apps from accessing Gmail. Enable this access in your Gmail settings if you're not using OAuth 2.0 or an App Password.

7. Debugging made easy: Be your own detective

Track failed emails and catch exceptions like a pro, thanks to Logcat and robust exception handling:

try { Transport.send(message); } catch (MessagingException e) { // Oops, something went south Log.e("EmailSending", "Error: " + e.getMessage(), e); }

8. Independence from built-in app: Ditching the default

Strive for a seamless user experience by avoiding dependency on any external email client. A direct sending approach in your own app hits the sweet spot of user convenience and control.