Android SDK: How To Send Email Without User Interaction Using SMTP

This tutorial will show you how to make an app to send an email without any user interaction, that is we will not make use of intents to use an existing app with pre-filled information but instead we will use SMTP, you will also be able to easily attach files by simply specifying the path and file name.

gmail inbox showing email sent from app

inbox showing email sent from app

External Libraries: JavaMail

Unfortunately though Android doesn’t support sending email like this out of the box, fortunately there is a Java class called JavaMail that does and there is even an Android port for it. Head over this website and download all three files: additional.jar, mail.jar and activation.jar . Put these files in a folder called lib inside your project folder as shown in the picture below.

javamail fjar files

location of JavaMail jar files as seen in eclipse's package explorer

Now that you have added the files to the lib folder, for each one: right click->Build Path->Add to Build Path

Mail Wrapper Class

Although the jar files you just added to your project provide the functions we need to send SMTP email they still need to be configured, fortunately for us someone already wrote a class to interface these jar files and all we have to do is add this class to our project into the src folder.

Make a file in your src folder called Mail.java with the following code, note that this is where you define define your SMTP domain and port. Gmail is used in this case:

Mail.java
package com.yoursite.automaticemail;


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) {
		this._to = toArr;
	}

	public void setFrom(String string) {
		this._from = string;
	}

	public void setSubject(String string) {
		this._subject = string;
	}

	// more of the getters and setters ….. 
} 

App Interface

Our interface will be just one button which upon clicking will attach a file and send the email to the specified address with the specified subject and body content.

send email button in android app

the app's interface, click the button to send the email

layout/main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<Button android:id="@+id/send_email"
	android:layout_width="fill_parent"
	android:layout_height="wrap_content"
	android:text="Send Email"
	android:onClick="sendEmail"/>
</LinearLayout>

Android Permissions Needed

The only permission we need is internet access.

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.yoursite.automaticemail"
      android:versionCode="1"
      android:versionName="1.0">
    <uses-sdk android:minSdkVersion="8" />

    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".AutomaticEmailActivity"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

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

Android Mail Activity

This activity is pretty short and self explanatory. The file am attaching is a picture called myPhoto.jpg located in my SD card.

AutomaticEmailActivity.java
package com.yoursite.automaticemail;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;

public class AutomaticEmailActivity extends Activity {
	private Mail m;
	/** Called when the activity is first created. */
	@Override 
	public void onCreate(Bundle savedInstanceState) { 
		super.onCreate(savedInstanceState); 
		setContentView(R.layout.main); 
		m = new Mail("yourEmail@domain.tld", "yourpassword"); 
	}

	public void sendEmail(View view){
		String[] toArr = {"toemail1@domain1.tld"}; // This is an array, you can add more emails, just separate them with a coma
		m.setTo(toArr); // load array to setTo function
		m.setFrom("fromEmail@domain.tld"); // who is sending the email 
		m.setSubject("subject"); 
		m.setBody("your message goes here"); 

		try { 
			m.addAttachment("/sdcard/myPicture.jpg");  // path to file you want to attach
			if(m.send()) { 
				// success
				Toast.makeText(AutomaticEmailActivity.this, "Email was sent successfully.", Toast.LENGTH_LONG).show(); 
			} else { 
				// failure
				Toast.makeText(AutomaticEmailActivity.this, "Email was not sent.", Toast.LENGTH_LONG).show(); 
			} 
		} catch(Exception e) { 
			// some other problem
			Toast.makeText(AutomaticEmailActivity.this, "There was a problem sending the email.", Toast.LENGTH_LONG).show(); 
		} 

	}
}

If everything goes as expected you’ll get this message, thanks to the toasts, after clicking the send email button:

android app: Button and success toast

success message

Files Location

Lastly here is a screenshot of my package explorer just in case you don’t know where the files go.

eclipse package explorer files

location of all files presented in this tutorial

What are you planning to do with this code? let us know in the comments below.

Related posts: