Send Email in your Android Application

I’ve seen a lot of examples of how to send email from an android application.  All of them result in applications coming up in a chooser list that are not appropriate for sending email.  In this post, I’ll described the various solutions I found, and the solution that brings up only email clients.

If you want to skip the junk, and go straight to the solution, go to the last two code snippets at the end.

One variation, from stack overflow, goes something like this.

Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_EMAIL  , new String[]{"recipient@example.com"});
intent.putExtra(Intent.EXTRA_SUBJECT, "subject of email");
intent.putExtra(Intent.EXTRA_TEXT   , "body of email");
startActivity(Intent.createChooser(intent, "Send mail..."));

The reason this doesn’t work properly, is because it brings up pretty much any app that can handle text/plain content. To expect a user to send an email with bluetooth, or wifi, or evernote, is simply not appropriate. So, if your intention is to have them send an actual email, as opposed to sharing content in some other way, then this won’t work for you.

Another variation from stack overflow, is to replace the mime-type of text/plain with message/rfc822. This results in a list of applications that can handle “email message” content. As a result, if you have ever-note installed, it comes up in the list as well. It will happily store your complete RFC822 email message for you. However, this is a hack, and is totally not appropriate. That mime type implies that you have already constructed a complete and valid RFC822 email message, including headers and what not.

Finally, I was able to find an example on the IT Wizard website, that shows the almost proper way of doing this, using the mailto URI handling.  Theoretically, only valid email applications will ever come up in this list. It goes like this…

Intent intent = new Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:someone@example.com"));
intent.putExtra("subject", "my subject");
intent.putExtra("body", "my message");
startActivity(intent);

Unfortunately, that only works with gmail on my phone.  So, I revised it to include everything inside the mailto url.

Intent intent = new Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:someone@example.com?subject=" +
    Uri.encode("my subject") +  "&body=" +
    Uri.encode("My big long body with spaces, new lines, and all sorts of invalid URI characters"));
startActivity(intent);

Now the only activities that come up are email apps. 😀 Now, if you want the complete list of email applications to always come up for the user, whether they’ve chosen a “default” email app or not, then you need to start the activity like this…

startActivity(Intent.createChooser(intent, "your chooser title"));

I do not know how to attach files to an email, using this method; in fact I do not think it is possible, seeing the mailto: URL scheme is pretty limited.  So, unfortunately, if you want to attach files, you’re going to have to use one of the other methods, with the EXTRA_STREAM option to putExtra() and file URI pointing to a file on your android device.  As a result, you’ll just have to live with some non-email related applications coming up.

If someone has a way of making sure ONLY email apps come up, using the other methods, I’d sure like to hear about it.  Thanks.