678
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/html");
intent.putExtra(Intent.EXTRA_EMAIL, "emailaddress@emailaddress.com");
intent.putExtra(Intent.EXTRA_SUBJECT, "Subject");
intent.putExtra(Intent.EXTRA_TEXT, "I'm email body.");
startActivity(Intent.createChooser(intent, "Send Email"));

The above code opens a dialog showing the following apps:- Bluetooth, Google Docs, Yahoo Mail, Gmail, Orkut, Skype, etc.

Actually, I want to filter these list options. I want to show only email-related apps e.g. Gmail, and Yahoo Mail. How to do it?

I've seen such an example on the 'Android Market application.

  1. Open the Android Market app
  2. Open any application where the developer has specified his/her email address. (If you can't find such an app just open my app:- market://details?id=com.becomputer06.vehicle.diary.free, OR search by 'Vehicle Diary')
  3. Scroll down to 'DEVELOPER'
  4. Click on 'Send Email'

The dialog shows only email Apps e.g. Gmail, Yahoo Mail, etc. It does not show Bluetooth, Orkut, etc. What code produces such dialog?

Ramesh R
  • 7,009
  • 4
  • 25
  • 38
dira
  • 30,304
  • 14
  • 54
  • 69
  • 4
    Sorry, this is not possible with Intent.ACTION_SEND. Maybe it works with an intent directly to the gmail-App but I don't know if this is possible. – Thommy Jan 02 '12 at 13:57
  • 22
    In case anyone happens to learn here about email intents, EXTRA_MAIL should correspond to a `String[]`, not just a `String` as shown here. – bigstones Aug 16 '12 at 15:44
  • possible duplicate of [Send email via gmail](http://stackoverflow.com/questions/8284706/send-email-via-gmail) – Sergey Glotov Sep 25 '13 at 08:05
  • Possible duplicate of [Using Android Intent.ACTION\_SEND for sending email](http://stackoverflow.com/questions/4883199/using-android-intent-action-send-for-sending-email) – A P Feb 03 '17 at 07:25
  • See here for some good advice: https://medium.com/@cketti/android-sending-email-using-intents-3da63662c58f – Felix D. Jul 27 '17 at 12:36
  • Does this answer your question? [How to send emails from my Android application?](https://stackoverflow.com/questions/2197741/how-to-send-emails-from-my-android-application) – A P Feb 12 '20 at 06:50
  • This did not work for me in 2020. here if my working solution: https://stackoverflow.com/a/62877003/2155858 – Rajeev Jayaswal Dec 19 '20 at 13:55

40 Answers40

979

UPDATE

Official approach:

public void composeEmail(String[] addresses, String subject) {
    Intent intent = new Intent(Intent.ACTION_SENDTO);
    intent.setData(Uri.parse("mailto:")); // only email apps should handle this
    intent.putExtra(Intent.EXTRA_EMAIL, addresses);
    intent.putExtra(Intent.EXTRA_SUBJECT, subject);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

Ref link

OLD ANSWER

The accepted answer doesn't work on the 4.1.2. This should work on all platforms:

Intent emailIntent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts(
            "mailto","abc@gmail.com", null));
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Subject");
emailIntent.putExtra(Intent.EXTRA_TEXT, "Body");
startActivity(Intent.createChooser(emailIntent, "Send email..."));

Update: According to marcwjj, it seems that on 4.3, we need to pass string array instead of a string for email address to make it work. We might need to add one more line:

intent.putExtra(Intent.EXTRA_EMAIL, addresses); // String[] addresses
thanhbinh84
  • 17,876
  • 6
  • 62
  • 69
  • 8
    You are right, and it doesn't either on 4.2. So this is actually the only correct answer, thanks! – mDroidd Mar 31 '13 at 16:22
  • 13
    This is perfect. Someone below mentioned that specifying the "mailto" part is what narrows the available options to email clients. Using Uri.fromParts("mailto", "", null) will put the cursor in the recipient field - perfect for what I needed. – Shaggy Aug 17 '13 at 10:33
  • 3
    is there a way to set the body with this? – Malabarba Aug 31 '13 at 17:13
  • 25
    Try this emailIntent.putExtra(Intent.EXTRA_TEXT, "I'm email body."); – thanhbinh84 Sep 01 '13 at 00:16
  • 1
    In some circumstances, this caused an exception: "Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?" To fix that, at least this works: `Intent chooser = Intent.createChooser(emailIntent, "Send email..."); chooser.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(chooser);` – Jonik Nov 07 '13 at 13:37
  • 16
    If you don't have a specific recipient, this also works: `Uri.fromParts("mailto", "", null)` – Phil Nov 13 '13 at 15:39
  • Is it possible to attach image? – Arst Oct 20 '14 at 01:19
  • You can try i.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(pic)) and i.setType("image/png"), but you need to check on several OS versions as I had problem with attaching txt files, it worked on a version of OS, but would be different on the others – thanhbinh84 Oct 20 '14 at 04:46
  • Why it doesn't work for me? I have installed email apps. – chenzhongpu Oct 23 '14 at 14:44
  • 31
    This does not work on my Android 4.3 any more. Please check out the official Android doc on sending email as intent, which works perfectly: https://developer.android.com/guide/components/intents-common.html#Email – marcwjj Apr 13 '15 at 20:57
  • Keep in mind that the EXTRA_EMAIL should allways be a String array, not a String with one address because that will be ignored. – Roel Sep 17 '15 at 11:13
  • 1
    You shouldn't create a chooser if you want the user to send the email directly to an email address of your choice. [Ref](https://developer.android.com/reference/android/content/Intent.html#ACTION_CHOOSER) Instead you should just do `startActivity(emailIntent)` – Jelmer Brands Dec 29 '17 at 13:53
  • This solution doesn't work with GMX Mail app. This one worked with every app I tested https://stackoverflow.com/a/17886006/1329901 – Egis Apr 20 '20 at 08:03
  • 1
    Unfortunately this trusty old answer no longer works well (in recent Gmail versions?) — with this code, **subject & body are lost**. Right now, the best way seems to be Approach 2 from here: https://medium.com/better-programming/the-imperfect-android-send-email-action-59610dfd1c2d – Jonik Dec 01 '20 at 10:54
  • `intent.resolveActivity()` gives warning see here: https://developer.android.com/training/package-visibility – Izak Apr 07 '21 at 03:46
  • Why MailTo doesn't appear in the Gmail in updated answer ? – Ahmed Elsayed Apr 28 '21 at 08:57
  • this will work in all android os except android 12 os. – Gaurav Mandlik Sep 08 '22 at 03:48
  • is there any changes in android 12 os for direct jump to email applications? – Gaurav Mandlik Sep 08 '22 at 03:49
281

There are three main approaches:

String email = /* Your email address here */
String subject = /* Your subject here */
String body = /* Your body here */
String chooserTitle = /* Your chooser title here */

1. Custom Uri:

Uri uri = Uri.parse("mailto:" + email)
    .buildUpon()
    .appendQueryParameter("subject", subject)
    .appendQueryParameter("body", body)
    .build();

Intent emailIntent = new Intent(Intent.ACTION_SENDTO, uri);
startActivity(Intent.createChooser(emailIntent, chooserTitle));

2. Using Intent extras:

Intent emailIntent = new Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:" + email));
emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
emailIntent.putExtra(Intent.EXTRA_TEXT, body);
//emailIntent.putExtra(Intent.EXTRA_HTML_TEXT, body); //If you are using HTML in your body text

startActivity(Intent.createChooser(emailIntent, "Chooser Title"));

3. Support Library ShareCompat:

Activity activity = /* Your activity here */

ShareCompat.IntentBuilder.from(activity)
    .setType("message/rfc822")
    .addEmailTo(email)
    .setSubject(subject)
    .setText(body)
    //.setHtmlText(body) //If you are using HTML in your body text
    .setChooserTitle(chooserTitle)
    .startChooser();
zOqvxf
  • 1,469
  • 15
  • 18
dira
  • 30,304
  • 14
  • 54
  • 69
  • 2
    This worked much better for me - the other options popped up some straight things (Skype, for example) as possible handlers. – Chris Rae Jul 08 '13 at 21:38
  • 2
    If you have a `%` symbol in the buffer, some characters in the resulting email won't be correctly encoded. You need to perform the `Uri.encode` dance suggested by @minipif. – Giulio Piancastelli Aug 02 '13 at 15:07
  • 19
    This are the best answers here, don't waste your time trying others, the second one here is what i chose and it works perfectly, only showing the pure email apps, not gDrive, not bluetooth.. etc. Thanks @becomputer06 – Hugo Nov 10 '14 at 12:34
  • 1
    Be careful about "&" character. If you got & character in email body, these method will cut off body after & . For example, if you send body like "I am & a sample body" you will get just "I am" – Emre Koç Oct 19 '15 at 08:31
  • 1
    For `SENDTO` (and using `URI.encode` if that's important) my phone doesn't show any apps to handle the intent. On `SEND` it does show Gmail and in the alternatives a lot more. – Zelphir Kaltstahl Jan 28 '16 at 13:31
  • Beautiful answer. I knew the first two well but learned something new Specially the last one; about ShareCompat! Thank you – sud007 Jun 04 '16 at 17:39
  • 7
    ShareCompat results in almost all the apps, not just email clients! – rpattabi Jun 22 '16 at 03:47
  • @Zelphir - that happened to me, too. And none of these answers handle attachments. – Kristy Welsh Dec 22 '16 at 19:58
  • The approach #2 works correctly and matches the docs. If you have no attachments, that's the right one. One thing - you can omit inluding recpieints emails in Uri.parse statement and pass them in extras of the intent, the way to do this is here: https://developer.android.com/guide/components/intents-common.html#Email – Kirill Starostin Feb 21 '19 at 11:09
  • 3
    3rd option with `.setType("message/rfc822")` gives me too much irrelevant options in Chooser dialog (Android 8.1). The good old `Intent.ACTION_SENDTO` approach works best! – Kirill Karmazin Apr 01 '19 at 16:32
  • 1
    On a Huawei P10: option 1 works, but option 2 and 3 result in the subject and body fields not being pre-filled, when gmail is selected. – Carmen Oct 07 '19 at 09:16
  • 1
    In the latest android(i.e 10) versions, only the custom URI method is working. – Tushar Bapte Dec 21 '19 at 06:39
  • 1
    First approach will not work well, as `appendQueryParameter` will remove the recipient part. More info here: https://stackoverflow.com/a/12035226/485986 – jpmcosta Jan 08 '20 at 17:48
  • `ShareCompat.IntentBuilder.from(activity)...` is now deprecated. Use `new ShareCompat.IntentBuilder(activity)...` instead. – ecle Sep 23 '22 at 07:46
  • `ShareCompat` can handle attachments well: `addStream()` for every attachment Uri – ecle Sep 23 '22 at 08:26
236

when you will change your intent.setType like below you will get

intent.setType("text/plain");

Use android.content.Intent.ACTION_SENDTO to get only the list of e-mail clients, with no facebook or other apps. Just the email clients. Ex:

new Intent(Intent.ACTION_SENDTO);

I wouldn't suggest you get directly to the email app. Let the user choose his favorite email app. Don't constrain him.

If you use ACTION_SENDTO, putExtra does not work to add subject and text to the intent. Use Uri to add the subject and body text.

EDIT: We can use message/rfc822 instead of "text/plain" as the MIME type. However, that is not indicating "only offer email clients" -- it indicates "offer anything that supports message/rfc822 data". That could readily include some application that are not email clients.

message/rfc822 supports MIME Types of .mhtml, .mht, .mime

Salil Pandit
  • 1,498
  • 10
  • 13
Padma Kumar
  • 19,893
  • 17
  • 73
  • 130
  • 7
    Can you please provide some code to produce the desired output? – dira Jan 02 '12 at 15:11
  • 9
    @becomputer06 refer this: http://stackoverflow.com/questions/8284706/send-email-via-gmail – Padma Kumar Jan 03 '12 at 06:58
  • 89
    The intent chooser says `no apps installed to perform this intent` when I use `ACTION_SENDTO`. I'm using Android 4.1.2 and I have an email app installed... – ffleandro Nov 28 '12 at 12:06
  • @ffleandro did you login the email app with your credentials. – Padma Kumar Nov 28 '12 at 12:50
  • 4
    The 'correct' way is the answer from Magnus. I recommend original poster to change the accepted answer. – jhabbott Feb 12 '13 at 16:33
  • 12
    Using the MIME type to perform a send operation is a bad idea, because you're basically instructing Android to provide a list of apps that support sending a file of type `message/rfc822`. That's **not** the same as sending an e-mail. Use the `mailto:` protocol instead, because that's what e-mail clients actually understand. – Paul Lammertsma May 28 '13 at 09:59
  • Answer https://stackoverflow.com/a/16217921/5245903 below is much much better and the correct answer. – Veneet Reddy Jan 26 '18 at 13:55
  • worked but also need to add intent.setData(Uri.parse("mailto:")); – Dev Mar 22 '18 at 14:18
  • This did not work for me in 2020, here is my working solution: https://stackoverflow.com/a/62877003/2155858 – Rajeev Jayaswal Dec 19 '20 at 13:57
118

This is quoted from Android official doc, I've tested it on Android 4.4, and works perfectly. See more examples at https://developer.android.com/guide/components/intents-common.html#Email

public void composeEmail(String[] addresses, String subject) {
    Intent intent = new Intent(Intent.ACTION_SENDTO);
    intent.setData(Uri.parse("mailto:")); // only email apps should handle this
    intent.putExtra(Intent.EXTRA_EMAIL, addresses);
    intent.putExtra(Intent.EXTRA_SUBJECT, subject);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}
Ziem
  • 6,579
  • 8
  • 53
  • 86
marcwjj
  • 1,705
  • 1
  • 12
  • 11
110

A late answer, although I figured out a solution which could help others:

Java version

Intent emailIntent = new Intent(Intent.ACTION_SENDTO);
emailIntent.setData(Uri.parse("mailto:abc@xyz.com"));
startActivity(Intent.createChooser(emailIntent, "Send feedback"));

Kotlin version

val emailIntent = Intent(Intent.ACTION_SENDTO).apply { 
    data = Uri.parse("mailto:abc@xyz.com")
}
startActivity(Intent.createChooser(emailIntent, "Send feedback"))

This was my output (only Gmail + Inbox suggested):

my output

I got this solution from the Android Developers site.

Community
  • 1
  • 1
capt.swag
  • 10,335
  • 2
  • 41
  • 41
47

This works for me:

Intent intent = new Intent(Intent.ACTION_SENDTO);
intent.setData(Uri.parse("mailto:"));
intent.putExtra(Intent.EXTRA_EMAIL, new String[] { "me@somewhere.com" });
intent.putExtra(Intent.EXTRA_SUBJECT, "My subject");

startActivity(Intent.createChooser(intent, "Email via..."));

Most importantly: Use the ACTION_SENDTO action rather than the ACTION_SEND action. I've tried it on a couple of Android 4.4 devices and:

  1. It correctly limits the chooser pop-up to only display email applications (Email, Gmail, Yahoo Mail etc); and
  2. It correctly inserts the email address and subject into the email.
Adil Hussain
  • 30,049
  • 21
  • 112
  • 147
37

This is the proper way to send the e-mail intent according to the Android Developer Official Documentation

Add these lines of code to your app:

Intent intent = new Intent(Intent.ACTION_SEND);//common intent 
intent.setData(Uri.parse("mailto:")); // only email apps should handle this

Optional: Add the body and subject, like this

intent.putExtra(Intent.EXTRA_SUBJECT, "Your Subject Here");
intent.putExtra(Intent.EXTRA_TEXT, "E-mail body" );

You already added this line in your question

intent.putExtra(Intent.EXTRA_EMAIL, new String[]{"hello@example.com"});

This will be the recipient's address, meaning the user will send you (the developer) an e-mail.

A P
  • 2,131
  • 2
  • 24
  • 36
  • @barnacle.m Thank you! It's also one of the more simple methods. The problem is that my answer doesn't get enough upvotes :( – A P Mar 01 '18 at 05:26
  • 1
    It's because there's a lot of similar answers, but this one points out the official Android documentation on the matter. – barnacle.m Mar 01 '18 at 11:01
  • 1
    I was unable to send email address. I fixed it like this intent.data = Uri.parse("mailto:somemail@xyz.com") – Hitesh Bisht Jan 11 '20 at 08:24
  • 1
    This didn't work until I changed `Intent.ACTION_SEND` to `Intent.ACTION_SENDTO`. – Westy92 Oct 07 '20 at 18:34
  • 1
    I always forget that the 'Intent.EXTRA_EMAIL' value needs to be an Array, otherwise it will not populate the "To" field in the mail client (at least the Gmail App client anyway, haven't tested others) – ProjectDelta Dec 05 '20 at 17:53
37

Try:

intent.setType("message/rfc822");
Magnus
  • 395
  • 2
  • 2
  • He's right, I tried it and offers [Drive, Email, Gmail, Skype], this should be the "Right answer" – gurbieta Nov 16 '12 at 22:47
  • 18
    Using the MIME type to perform a send operation is a bad idea, because you're basically instructing Android to provide a list of apps that support sending a file of type `message/rfc822`. That's **not** the same as sending an e-mail. Use the `mailto:` protocol instead, because that's what e-mail clients actually understand. – Paul Lammertsma May 28 '13 at 09:59
30

Finally come up with best way to do

String to = "test@gmail.com";
String subject= "Hi I am subject";
String body="Hi I am test body";
String mailTo = "mailto:" + to +
        "?&subject=" + Uri.encode(subject) +
        "&body=" + Uri.encode(body);
Intent emailIntent = new Intent(Intent.ACTION_VIEW);
emailIntent.setData(Uri.parse(mailTo));
startActivity(emailIntent);
Rahul Gaur
  • 1,661
  • 1
  • 13
  • 29
Ajay Shrestha
  • 2,433
  • 1
  • 21
  • 25
19

Works on all android Versions:

String[] to = {"email@server.com"};
Uri uri = Uri.parse("mailto:email@server.com")
  .buildUpon()
  .appendQueryParameter("subject", "subject")
  .appendQueryParameter("body", "body")
  .build();
Intent emailIntent = new Intent(ACTION_SENDTO, uri);
emailIntent.putExtra(EXTRA_EMAIL, TO);
startActivity(Intent.createChooser(emailIntent, "Send mail..."));

Updated for Android 10, now using Kotlin...

fun Context.sendEmail(
  address: String?,
  subject: String?,
  body: String?,
) {
  val recipients = arrayOf(address)
  val uri = address.toUri()
    .buildUpon()
    .appendQueryParameter("subject", subject)
    .appendQueryParameter("body", body)
    .build()
  val emailIntent = Intent(ACTION_SENDTO, uri).apply {
    setData("mailto:$address".toUri());
    putExtra(EXTRA_SUBJECT, subject);
    putExtra(EXTRA_TEXT, body);
    putExtra(EXTRA_EMAIL, recipients)
  }
  val pickerTitle = getString(R.string.some_title)
  ContextCompat.startActivity(this, Intent.createChooser(emailIntent, pickerTitle, null)
}

...after updating to API 30, the code did not fill the subject and body of the email client (e.g Gmail). But I found an answer here:

fun Context.sendEmail(
  address: String?,
  subject: String?,
  body: String?,
) {
  val selectorIntent = Intent(ACTION_SENDTO)
    .setData("mailto:$address".toUri())
  val emailIntent = Intent(ACTION_SEND).apply {
    putExtra(EXTRA_EMAIL, arrayOf(address))
    putExtra(EXTRA_SUBJECT, subject)
    putExtra(EXTRA_TEXT, body)
    selector = selectorIntent
  }
  startActivity(Intent.createChooser(emailIntent, getString(R.string.send_email))) 

}
afollestad
  • 2,929
  • 5
  • 30
  • 44
Usama Saeed US
  • 984
  • 11
  • 18
16

If you want only the email clients you should use android.content.Intent.EXTRA_EMAIL with an array. Here goes an example:

final Intent result = new Intent(android.content.Intent.ACTION_SEND);
result.setType("plain/text");
result.putExtra(android.content.Intent.EXTRA_EMAIL, new String[] { recipient });
result.putExtra(android.content.Intent.EXTRA_SUBJECT, subject);
result.putExtra(android.content.Intent.EXTRA_TEXT, body);
Addev
  • 31,819
  • 51
  • 183
  • 302
11

The following code works for me fine.

Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("message/rfc822");
intent.putExtra(Intent.EXTRA_SUBJECT, subject);
intent.putExtra(Intent.EXTRA_EMAIL, new String[]{"abc@gmailcom"});
Intent mailer = Intent.createChooser(intent, null);
startActivity(mailer);
Anam Ansari
  • 849
  • 9
  • 14
10

Edit: Not working anymore with new versions of Gmail

This was the only way I found at the time to get it to work with any characters.

doreamon's answer is the correct way to go now, as it works with all characters in new versions of Gmail.

Old answer:


Here is mine. It seems to works on all Android versions, with subject and message body support, and full utf-8 characters support:

public static void email(Context context, String to, String subject, String body) {
    StringBuilder builder = new StringBuilder("mailto:" + Uri.encode(to));
    if (subject != null) {
        builder.append("?subject=" + Uri.encode(Uri.encode(subject)));
        if (body != null) {
            builder.append("&body=" + Uri.encode(Uri.encode(body)));
        }
    }
    String uri = builder.toString();
    Intent intent = new Intent(Intent.ACTION_SENDTO, Uri.parse(uri));
    context.startActivity(intent);
}
minipif
  • 4,756
  • 3
  • 30
  • 39
  • 1
    +1 `Uri.encode` is the correct way to go. But why calling it two times for subject and body? – Giulio Piancastelli Aug 02 '13 at 15:08
  • So, doing the encoding yourself is just a bad idea. Better use a proper Intent with the necessary extras, see e.g. http://stackoverflow.com/a/15022222 – Giulio Piancastelli Aug 02 '13 at 16:32
  • For me this is the best answer because other solutions work correctly only with some of the email apps. This one works with every email app that I tested. – Egis Apr 20 '20 at 08:02
9

None of these solutions were working for me. Here's a minimal solution that works on Lollipop. On my device, only Gmail and the native email apps appear in the resulting chooser list.

Intent emailIntent = new Intent(Intent.ACTION_SENDTO,
                                Uri.parse("mailto:" + Uri.encode(address)));

emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
emailIntent.putExtra(Intent.EXTRA_TEXT, body);
startActivity(Intent.createChooser(emailIntent, "Send email via..."));
scottt
  • 8,301
  • 1
  • 31
  • 41
9

Most of these answers work only for a simple case when you are not sending attachment. In my case I need sometimes to send attachment (ACTION_SEND) or two attachments (ACTION_SEND_MULTIPLE).

So I took best approaches from this thread and combined them. It's using support library's ShareCompat.IntentBuilder but I show only apps which match the ACTION_SENDTO with "mailto:" uri. This way I get only list of email apps with attachment support:

fun Activity.sendEmail(recipients: List<String>, subject: String, file: Uri, text: String? = null, secondFile: Uri? = null) {
    val originalIntent = createEmailShareIntent(recipients, subject, file, text, secondFile)
    val emailFilterIntent = Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:"))
    val originalIntentResults = packageManager.queryIntentActivities(originalIntent, 0)
    val emailFilterIntentResults = packageManager.queryIntentActivities(emailFilterIntent, 0)
    val targetedIntents = originalIntentResults
            .filter { originalResult -> emailFilterIntentResults.any { originalResult.activityInfo.packageName == it.activityInfo.packageName } }
            .map {
                createEmailShareIntent(recipients, subject, file, text, secondFile).apply { `package` = it.activityInfo.packageName }
            }
            .toMutableList()
    val finalIntent = Intent.createChooser(targetedIntents.removeAt(0), R.string.choose_email_app.toText())
    finalIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedIntents.toTypedArray())
    startActivity(finalIntent)
}

private fun Activity.createEmailShareIntent(recipients: List<String>, subject: String, file: Uri, text: String? = null, secondFile: Uri? = null): Intent {
    val builder = ShareCompat.IntentBuilder.from(this)
            .setType("message/rfc822")
            .setEmailTo(recipients.toTypedArray())
            .setStream(file)
            .setSubject(subject)
    if (secondFile != null) {
        builder.addStream(secondFile)
    }
    if (text != null) {
        builder.setText(text)
    }
    return builder.intent
}
David Vávra
  • 18,446
  • 7
  • 48
  • 56
  • This looks like it could be useful; any chance of getting it in Java? – Kyle Humfeld Mar 06 '18 at 00:55
  • 1
    Kotlin is very similar to Java, you should be able to copy paste and just change few things. – David Vávra Mar 07 '18 at 02:54
  • 2
    wont work on android 11 due to query package limitation – Omkar T Sep 08 '21 at 11:05
  • @Omkar T It did work for me on Android 11, with a provider tag in my Android Manifest. There is good info in the [docs](https://developer.android.com/reference/androidx/core/content/FileProvider). – Carl Smith Apr 18 '22 at 03:00
  • A huge benefit to this strategy is that it not only works with multiple attachments, but it is an extension on Activity which can easily be used in multiple projects. – Carl Smith Apr 18 '22 at 03:09
9

From Android developers docs:

public void composeEmail(String[] addresses, String subject) {
    Intent intent = new Intent(Intent.ACTION_SENDTO);
    intent.setData(Uri.parse("mailto:")); // only email apps should handle this
    intent.putExtra(Intent.EXTRA_EMAIL, addresses);
    intent.putExtra(Intent.EXTRA_SUBJECT, subject);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}
marvatron
  • 311
  • 3
  • 3
6

in Kotlin if anyone is looking

val emailArrray:Array<String> = arrayOf("travelagentsupport@kkk.com")
val intent = Intent(Intent.ACTION_SENDTO)
intent.data = Uri.parse("mailto:") // only email apps should handle this
intent.putExtra(Intent.EXTRA_EMAIL, emailArrray)
intent.putExtra(Intent.EXTRA_SUBJECT, "Inquire about travel agent")
if (intent.resolveActivity(getPackageManager()) != null) {
    startActivity(intent);
}
Rahul Gaur
  • 1,661
  • 1
  • 13
  • 29
Mughil
  • 705
  • 7
  • 8
5

Following Code worked for me!!

import android.support.v4.app.ShareCompat;
    .
    .
    .
    .
final Intent intent = ShareCompat.IntentBuilder
                        .from(activity)
                        .setType("application/txt")
                        .setSubject(subject)
                        .setText("Hii")
                        .setChooserTitle("Select One")
                        .createChooserIntent()
                        .addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET)
                        .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

activity.startActivity(intent);
Nima Derakhshanjan
  • 1,380
  • 9
  • 24
  • 37
Suyog Gunjal
  • 287
  • 4
  • 7
5

This works for me perfectly fine:

    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setData(Uri.parse("mailto:" + address));
    startActivity(Intent.createChooser(intent, "E-mail"));
EpicPandaForce
  • 79,669
  • 27
  • 256
  • 428
5

If you want to ensure that your intent is handled only by an email app (and not other text messaging or social apps), then use the ACTION_SENDTO action and include the "mailto:" data scheme. For example:

public void composeEmail(String[] addresses, String subject) {
    Intent intent = new Intent(Intent.ACTION_SENDTO);
    intent.setData(Uri.parse("mailto:")); // only email apps should handle this
    intent.putExtra(Intent.EXTRA_EMAIL, addresses);
    intent.putExtra(Intent.EXTRA_SUBJECT, subject);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

I found this in https://developer.android.com/guide/components/intents-common.html#Email

juunas
  • 54,244
  • 13
  • 113
  • 149
  • For me the test if (intent.resolveActivity(getPackageManager()) != null) is always null, any idéea why ? – Christian Oct 20 '22 at 06:44
3

Using intent.setType("message/rfc822"); does work but it shows extra apps that not necessarily handling emails (e.g. GDrive). Using Intent.ACTION_SENDTO with setType("text/plain") is the best but you have to add setData(Uri.parse("mailto:")) to get the best results (only email apps). The full code is as follows:

Intent intent = new Intent(Intent.ACTION_SENDTO);
intent.setType("text/plain");
intent.setData(Uri.parse("mailto:IT@RMAsoft.NET"));
intent.putExtra(Intent.EXTRA_SUBJECT, "Email from My app");
intent.putExtra(Intent.EXTRA_TEXT, "Place your email message here ...");
startActivity(Intent.createChooser(intent, "Send Email"));
Bruno Bieri
  • 9,724
  • 11
  • 63
  • 92
Rami Alloush
  • 2,308
  • 2
  • 27
  • 33
2

If you want to target Gmail then you could do the following. Note that the intent is "ACTION_SENDTO" and not "ACTION_SEND" and the extra intent fields are not necessary for Gmail.

String uriText =
    "mailto:youremail@gmail.com" + 
    "?subject=" + Uri.encode("your subject line here") + 
    "&body=" + Uri.encode("message body here");

Uri uri = Uri.parse(uriText);

Intent sendIntent = new Intent(Intent.ACTION_SENDTO);
sendIntent.setData(uri);
if (sendIntent.resolveActivity(getPackageManager()) != null) {
   startActivity(Intent.createChooser(sendIntent, "Send message")); 
}
pcodex
  • 1,812
  • 15
  • 16
2

I am updating Adil's answer in Kotlin,

val intent = Intent(Intent.ACTION_SENDTO)
intent.data = Uri.parse("mailto:") // only email apps should handle this
intent.putExtra(Intent.EXTRA_EMAIL, Array(1) { "test@email.com" })
intent.putExtra(Intent.EXTRA_SUBJECT, "subject")
if (intent.resolveActivity(packageManager) != null) {
    startActivity(intent)
} else {
    showSnackBar(getString(R.string.no_apps_found_to_send_mail), this)
}
Kishan Solanki
  • 13,761
  • 4
  • 85
  • 82
2

Please use the below code :

try {
    String uriText =
            "mailto:emailid" +
                    "?subject=" + Uri.encode("Feedback for app") +
                    "&body=" + Uri.encode(deviceInfo);
    Uri uri = Uri.parse(uriText);
    Intent emailIntent = new Intent(Intent.ACTION_SENDTO);
    emailIntent.setData(uri);
    startActivity(Intent.createChooser(emailIntent, "Send email using..."));
} catch (android.content.ActivityNotFoundException ex) {
    Toast.makeText(ContactUsActivity.this, "No email clients installed.", Toast.LENGTH_SHORT).show();
}            
Ramesh R
  • 7,009
  • 4
  • 25
  • 38
Tushar Bapte
  • 121
  • 1
  • 4
2

Kotlin:

val email: String = getEmail()
val intent = Intent(Intent.ACTION_SENDTO)
intent.data = Uri.parse("mailto:$email" )
startActivity(intent)
2
String sendEmailTo = "abc@xyz.com";
String subject = "Subject";
String body = "Body";
            
Uri uri = Uri.parse("mailto:"+sendEmailTo+"?subject="+subject+"&body="+body);
    
startActivity(new Intent(Intent.ACTION_VIEW, uri);

This worked for me. This will only show the mailing application in the intent chooser.

Additionally: One problem that i faced with this method is I was unable to add space in the suggestions and body text. So, to put spaces in the suggestion or body text then replace the space with %20

Priyankchoudhary
  • 786
  • 9
  • 12
1

Compose an email in the phone email client:

Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("plain/text");
intent.putExtra(Intent.EXTRA_EMAIL, new String[] { "some@email.address" });
intent.putExtra(Intent.EXTRA_SUBJECT, "subject");
intent.putExtra(Intent.EXTRA_TEXT, "mail body");
startActivity(Intent.createChooser(intent, ""));
1

Use this:

boolean success = EmailIntentBuilder.from(activity)
        .to("support@example.org")
        .cc("developer@example.org")
        .subject("Error report")
        .body(buildErrorReport())
        .start();

use build gradle :

compile 'de.cketti.mailto:email-intent-builder:1.0.0'
Manish
  • 234
  • 2
  • 13
1

This is what I use, and it works for me:

//variables
String subject = "Whatever subject you want";
String body = "Whatever text you want to put in the body";
String intentType = "text/html";
String mailToParse = "mailto:";

//start Intent
Intent variableName = new Intent(Intent.ACTION_SENDTO);
variableName.setType(intentType);
variableName.setData(Uri.parse(mailToParse));
variableName.putExtra(Intent.EXTRA_SUBJECT, subject);
variableName.putExtra(Intent.EXTRA_TEXT, body);

startActivity(variableName);

This will also let the user choose their preferred email app. The only thing this does not allow you to do is to set the recipient's email address.

grasshopper
  • 21
  • 1
  • 4
1

This code is working in my device

Intent mIntent = new Intent(Intent.ACTION_SENDTO);
mIntent.setData(Uri.parse("mailto:"));
mIntent.putExtra(Intent.EXTRA_EMAIL  , new String[] {"mahendrarajdhami@gmail.com"});
mIntent.putExtra(Intent.EXTRA_SUBJECT, "");
startActivity(Intent.createChooser(mIntent, "Send Email Using..."));
Mahen
  • 760
  • 9
  • 12
1
Intent emailIntent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts("mailto", email, null));
if (emailIntent.resolveActivity(context.getPackageManager()) != null) {
    context.startActivity(Intent.createChooser(emailIntent, "Send Email..."));
} else {
    Toast.makeText(context, "No apps can perform this action.", Toast.LENGTH_SHORT).show();
}
Bruno Bieri
  • 9,724
  • 11
  • 63
  • 92
Ahamadullah Saikat
  • 4,437
  • 42
  • 39
1

SEND TO EMAIL CLIENTS ONLY - WITH MULTIPLE ATTACHMENTS

There are many solutions but all work partially.

mailto properly filters email apps but it has the inability of not sending streams/files.

message/rfc822 opens up hell of apps along with email clients

so, the solution for this is to use both.

  1. First resolve intent activities using mailto intent
  2. Then set the data to each activity resolved to send the required data
private void share()
{
     Intent queryIntent = new Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:"));
     Intent dataIntent  = getDataIntent();

     Intent targetIntent = getSelectiveIntentChooser(context, queryIntent, dataIntent);
     startActivityForResult(targetIntent);
}

Build the required data intent which is filled with required data to share

private Intent getDataIntent()
{
        Intent dataIntent = buildIntent(Intent.ACTION_SEND, null, "message/rfc822", null);

        // Set subject
        dataIntent.putExtra(Intent.EXTRA_SUBJECT, title);

        //Set receipient list.
        dataIntent.putExtra(Intent.EXTRA_EMAIL, toRecipients);
        dataIntent.putExtra(Intent.EXTRA_CC, ccRecipients);
        dataIntent.putExtra(Intent.EXTRA_BCC, bccRecipients);
        if (hasAttachments())
        {
            ArrayList<Uri> uris = getAttachmentUriList();

            if (uris.size() > 1)
            {
                intent.setAction(Intent.ACTION_SEND_MULTIPLE);
                dataIntent.putExtra(Intent.EXTRA_STREAM, uris);
            }
            else
            {
                dataIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris.get(0));
            }
        }

        return dataIntent;
}

protected ArrayList<Uri> getAttachmentUriList()
{
        ArrayList<Uri> uris = new ArrayList();
        for (AttachmentInfo eachAttachment : attachments)
        {
            uris.add(eachAttachment.uri);
        }

        return uris;
}

Utitlity class for filtering required intents based on query intent

// Placed in IntentUtil.java
public static Intent getSelectiveIntentChooser(Context context, Intent queryIntent, Intent dataIntent)
{
        List<ResolveInfo> appList = context.getPackageManager().queryIntentActivities(queryIntent, PackageManager.MATCH_DEFAULT_ONLY);

        Intent finalIntent = null;

        if (!appList.isEmpty())
        {
            List<android.content.Intent> targetedIntents = new ArrayList<android.content.Intent>();

            for (ResolveInfo resolveInfo : appList)
            {
                String packageName = resolveInfo.activityInfo != null ? resolveInfo.activityInfo.packageName : null;

                Intent allowedIntent = new Intent(dataIntent);
                allowedIntent.setComponent(new ComponentName(packageName, resolveInfo.activityInfo.name));
                allowedIntent.setPackage(packageName);

                targetedIntents.add(allowedIntent);
            }

            if (!targetedIntents.isEmpty())
            {
                //Share Intent
                Intent startIntent = targetedIntents.remove(0);

                Intent chooserIntent = android.content.Intent.createChooser(startIntent, "");
                chooserIntent.putExtra(android.content.Intent.EXTRA_INITIAL_INTENTS, targetedIntents.toArray(new Parcelable[]{}));
                chooserIntent.addFlags(android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION);

                finalIntent = chooserIntent;
            }

        }

        if (finalIntent == null) //As a fallback, we are using the sent data intent
        {
            finalIntent = dataIntent;
        }

        return finalIntent;
}
Ayyappa
  • 1,876
  • 1
  • 21
  • 41
  • 1
    Many thanks for this answer, this is the only one which works for me to also include attachments.. Don't know why this case a down vote co I'm putting one up vote here.. – Petr Nalevka May 05 '20 at 09:16
1

There is an easy solution also with ACTION_VIEW:

  Intent intent = new Intent(Intent.ACTION_VIEW);
        Uri data = Uri.parse("mailto:customer@something.com?subject=Feedback");
        intent.setData(data);
        startActivity(intent);
Darksymphony
  • 2,155
  • 30
  • 54
1

I almost used all of the answers here on android 11 but they did not work properly. some of them does not place the mailto on its required field and some other don't even work at all. so I did read the new documentation and found that mailto emails should be in an array so what worked for me finally is here. Anyways thanks for all the answers, they did help after all.

//mail me
findViewById<TextView>(R.id.mailme).setOnTouchListener { _, _ ->
    try {
        val mail: Array<String> = arrayOf("somemail@cc.com")
        val mailme = Intent(Intent.ACTION_SENDTO).apply {
            data = Uri.parse("mailto:")
            putExtra(Intent.EXTRA_EMAIL, mail)
            putExtra(Intent.EXTRA_TEXT, "Hey We Need Your Help With This Issue.")
            putExtra(Intent.EXTRA_SUBJECT, "At Logs Calculator, We Need Your Help !")
        }
        startActivity(mailme)
    } catch (e: Exception) {
        e.printStackTrace()
    }
    true
}
Ramesh R
  • 7,009
  • 4
  • 25
  • 38
Haris
  • 372
  • 3
  • 16
1

This is how i manage to do it in kotlin :

val intent = Intent(Intent.ACTION_SENDTO)
intent.data = Uri.parse("mailto:")

intent.putExtra(Intent.EXTRA_EMAIL, emailAddress)
intent.putExtra(Intent.EXTRA_SUBJECT, emailSubject)
intent.putExtra(Intent.EXTRA_TEXT, emailBody)
context.startActivity(intent)

Hope it can help

XCarb
  • 735
  • 10
  • 31
1

Maybe you should try this: intent.setType("plain/text");

I found it here. I've used it in my app and it shows only E-Mail and Gmail options.

sianis
  • 598
  • 4
  • 13
  • 2
    "plain/text" shows Bluetooth, Skype etc. Checkout the desired output in Android Market app. Steps are listed in the question. – dira Jan 02 '12 at 15:16
  • 1
    Using the MIME type to perform a send operation is a bad idea, because you're basically instructing Android to provide a list of apps that support sending a file of type `plain/text`, and that isn't even a valid MIME type. That's **not** the same as sending an e-mail. Use the `mailto:` protocol instead, because that's what e-mail clients actually understand. – Paul Lammertsma May 28 '13 at 10:00
0

use Anko - kotlin

context.email(email, subject, body)
Ali Hasan
  • 653
  • 9
  • 8
0

With Kotlin, works with Gmail :

val i = Intent(Intent.ACTION_SENDTO).apply {
    type = "text/html"
    data = Uri.parse("mailto:")
    putExtra(Intent.EXTRA_EMAIL, arrayOf(email))
    putExtra(Intent.EXTRA_SUBJECT, subject)
    putExtra(Intent.EXTRA_TITLE, subject)
}
if (packageManager != null && i.resolveActivity(packageManager) != null) {
    startActivity(i)
}

If anyone find a solution to display the message too...

A. Ferrand
  • 618
  • 6
  • 19
0

Sometimes you need to open default email app to view the inbox without creating a new letter, in this case it will help:

Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_APP_EMAIL);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (intent.resolveActivity(getPackageManager()) != null) {
    startActivity(intent);
}
remain4life
  • 1,201
  • 2
  • 12
  • 11
0

follow this to the letter and you should have no issues

https://developer.android.com/guide/components/intents-common#ComposeEmail

make sure you pass an array in the EXTRA_EMAIL field while using ACTION_SENDTO