Send Email Intent
Asked Answered
C

41

686
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/html");
intent.putExtra(Intent.EXTRA_EMAIL, "[email protected]");
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?

Contravene answered 2/1, 2012 at 13:50 Comment(7)
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.Tisatisane
In case anyone happens to learn here about email intents, EXTRA_MAIL should correspond to a String[], not just a String as shown here.Loyalty
possible duplicate of Send email via gmailUmbria
Possible duplicate of Using Android Intent.ACTION_SEND for sending emailExist
See here for some good advice: medium.com/@cketti/…Jerrodjerrol
Does this answer your question? How to send emails from my Android application?Exist
This did not work for me in 2020. here if my working solution: https://mcmap.net/q/52901/-opening-an-email-client-on-clicking-a-buttonChaeta
M
237

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

Morgenthaler answered 2/1, 2012 at 13:58 Comment(9)
Can you please provide some code to produce the desired output?Contravene
@becomputer06 refer this: https://mcmap.net/q/52898/-send-email-via-gmailMorgenthaler
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...Burin
@Burin did you login the email app with your credentials.Morgenthaler
The 'correct' way is the answer from Magnus. I recommend original poster to change the accepted answer.Peptize
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.Phidias
Answer https://mcmap.net/q/52867/-send-email-intent below is much much better and the correct answer.Preposterous
worked but also need to add intent.setData(Uri.parse("mailto:"));Blip
This did not work for me in 2020, here is my working solution: https://mcmap.net/q/52901/-opening-an-email-client-on-clicking-a-buttonChaeta
O
984

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","[email protected]", 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
Ozonize answered 22/2, 2013 at 10:36 Comment(20)
You are right, and it doesn't either on 4.2. So this is actually the only correct answer, thanks!Aggie
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.Along
is there a way to set the body with this?Hewett
Try this emailIntent.putExtra(Intent.EXTRA_TEXT, "I'm email body.");Ozonize
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);Fryer
If you don't have a specific recipient, this also works: Uri.fromParts("mailto", "", null)Oster
Is it possible to attach image?Swag
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 othersOzonize
Why it doesn't work for me? I have installed email apps.Combine
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: developer.android.com/guide/components/…Mauretania
Keep in mind that the EXTRA_EMAIL should allways be a String array, not a String with one address because that will be ignored.Switchman
You shouldn't create a chooser if you want the user to send the email directly to an email address of your choice. Ref Instead you should just do startActivity(emailIntent)Mcguire
This solution doesn't work with GMX Mail app. This one worked with every app I tested https://mcmap.net/q/52867/-send-email-intentCircumnavigate
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: medium.com/better-programming/…Fryer
intent.resolveActivity() gives warning see here: developer.android.com/training/package-visibilityBinoculars
Why MailTo doesn't appear in the Gmail in updated answer ?Edytheee
this will work in all android os except android 12 os.Pilgrim
is there any changes in android 12 os for direct jump to email applications?Pilgrim
For API 30 or higher intent.resolveActivity(activity.getPackageManager()) == null. You can remove that check in the if statement. Checkout this answerSissel
Attention: while the updated code is still valid, starting from Android 11 (API30) you will need to declare a query in the manifest, so that it functions correctly. Please see: developer.android.com/training/package-visibility/declaring and #62536356 for details.Horacehoracio
C
283

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();
Contravene answered 25/4, 2013 at 14:46 Comment(16)
This worked much better for me - the other options popped up some straight things (Skype, for example) as possible handlers.Spohr
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.Kearns
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 @becomputer06Bristling
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"Hargett
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.Tatter
Beautiful answer. I knew the first two well but learned something new Specially the last one; about ShareCompat! Thank youSilvanus
ShareCompat results in almost all the apps, not just email clients!Fuel
@Zelphir - that happened to me, too. And none of these answers handle attachments.Paramilitary
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: developer.android.com/guide/components/…Digression
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!Omnivore
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.Felisafelise
In the latest android(i.e 10) versions, only the custom URI method is working.Alphabetical
First approach will not work well, as appendQueryParameter will remove the recipient part. More info here: https://mcmap.net/q/52903/-is-it-possible-to-use-uri-builder-and-not-have-the-quot-quot-partSemifinalist
ShareCompat.IntentBuilder.from(activity)... is now deprecated. Use new ShareCompat.IntentBuilder(activity)... instead.Alicyclic
ShareCompat can handle attachments well: addStream() for every attachment UriAlicyclic
option 1 does not work for me. It opens the mail client but doesn't show any mail id in the to field. but show the subject and body.Ernestinaernestine
M
237

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

Morgenthaler answered 2/1, 2012 at 13:58 Comment(9)
Can you please provide some code to produce the desired output?Contravene
@becomputer06 refer this: https://mcmap.net/q/52898/-send-email-via-gmailMorgenthaler
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...Burin
@Burin did you login the email app with your credentials.Morgenthaler
The 'correct' way is the answer from Magnus. I recommend original poster to change the accepted answer.Peptize
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.Phidias
Answer https://mcmap.net/q/52867/-send-email-intent below is much much better and the correct answer.Preposterous
worked but also need to add intent.setData(Uri.parse("mailto:"));Blip
This did not work for me in 2020, here is my working solution: https://mcmap.net/q/52901/-opening-an-email-client-on-clicking-a-buttonChaeta
M
121

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);
    }
}
Mauretania answered 13/4, 2015 at 20:59 Comment(9)
Agreed! I'm surprised an answer like this is so far down the list. I guess it must have been a relatively recent change in the Android Docs.Noetic
Great! dependable one, it referred the 'Bible' of Android app developers.Astigmia
The colon after mailto did the trick for me! I was using "mailto" instead of "mailto:"Urogenital
Working on 5.1.1. The other options doesn't work for me.Squirrel
nice solution :)Zellazelle
diddnt work correctly, both the email and subject data doesnt get populated in the gmail appClout
This is the only working answer. Be careful to set Intent.ACTION_SENDTO, Intent.ACTION_SEND won't work with "mailto:"Renowned
According to the docs, only ACTION_SENDTO is supposed to show just email apps, but it also doesn't allow to have attachments. How come? What if I do want to send attachments, and I wish to send only to email apps?Bracketing
EXTRA_EMAIL not working for me so I used Uri.parse("mailto: " + myEmail)Catechetical
T
111

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:[email protected]"));
startActivity(Intent.createChooser(emailIntent, "Send feedback"));

Kotlin version

val emailIntent = Intent(Intent.ACTION_SENDTO).apply { 
    data = Uri.parse("mailto:[email protected]")
}
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.

Topmost answered 3/2, 2016 at 8:24 Comment(3)
For me it was important that there is no space between mailto and the email: mailto:[email protected]Workbench
Great Solution , i had the same requirement, thanks a lot.!!!!Bestial
Excellent solution. Would you be great if you could show how to add Subject and Body as well.Herder
T
48

This works for me:

Intent intent = new Intent(Intent.ACTION_SENDTO);
intent.setData(Uri.parse("mailto:"));
intent.putExtra(Intent.EXTRA_EMAIL, new String[] { "[email protected]" });
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.
Twandatwang answered 24/1, 2015 at 9:21 Comment(0)
E
37

Try:

intent.setType("message/rfc822");
Elexa answered 3/1, 2012 at 23:12 Comment(2)
He's right, I tried it and offers [Drive, Email, Gmail, Skype], this should be the "Right answer"Fusionism
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.Phidias
E
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[]{"[email protected]"});

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

Exist answered 5/6, 2015 at 2:27 Comment(5)
@barnacle.m Thank you! It's also one of the more simple methods. The problem is that my answer doesn't get enough upvotes :(Exist
It's because there's a lot of similar answers, but this one points out the official Android documentation on the matter.Drier
I was unable to send email address. I fixed it like this intent.data = Uri.parse("mailto:[email protected]")Baseler
This didn't work until I changed Intent.ACTION_SEND to Intent.ACTION_SENDTO.Hair
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)Adorn
C
30

Finally come up with best way to do

String to = "[email protected]";
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);
Camey answered 19/6, 2017 at 19:22 Comment(1)
This is the only answer that worked out of all to get: To, From, Subject, Body.Integrant
W
19

Works on all android Versions:

String[] to = {"[email protected]"};
Uri uri = Uri.parse("mailto:[email protected]")
  .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))) 

}
Welford answered 21/3, 2016 at 23:54 Comment(3)
Your answer helped me. ThanksKira
the damn mail is not accepted / empty from gmail in the java version.Sod
dont use java version that is outdated. added new to support all android versions.Welford
S
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);
System answered 17/2, 2014 at 10:47 Comment(1)
nope, Still brings up lots of other apps - a lot more than ACTION_SENDTOHeyde
K
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);
Kalmia answered 23/10, 2013 at 9:51 Comment(0)
K
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);
}
Knavish answered 26/7, 2013 at 16:2 Comment(3)
+1 Uri.encode is the correct way to go. But why calling it two times for subject and body?Kearns
So, doing the encoding yourself is just a bad idea. Better use a proper Intent with the necessary extras, see e.g. stackoverflow.com/a/15022222Kearns
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.Circumnavigate
S
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..."));
Scourge answered 20/3, 2015 at 11:37 Comment(0)
G
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
}
Grow answered 6/1, 2018 at 17:31 Comment(5)
This looks like it could be useful; any chance of getting it in Java?Creath
Kotlin is very similar to Java, you should be able to copy paste and just change few things.Emmalynne
wont work on android 11 due to query package limitationYehudi
@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.Andyane
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.Andyane
G
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);
    }
}
Gilbertine answered 8/1, 2019 at 12:59 Comment(0)
A
6

in Kotlin if anyone is looking

val emailArrray:Array<String> = arrayOf("[email protected]")
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);
}
Alcmene answered 16/4, 2019 at 6:7 Comment(0)
B
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);
Bud answered 4/12, 2015 at 10:37 Comment(0)
D
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"));
Dope answered 22/12, 2015 at 8:59 Comment(0)
L
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

Lipkin answered 19/2, 2017 at 16:21 Comment(1)
For me the test if (intent.resolveActivity(getPackageManager()) != null) is always null, any idéea why ?Ariew
M
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:[email protected]"));
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"));
Magree answered 10/8, 2018 at 22:44 Comment(1)
Perfect soultionMartyry
A
3

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();
}            
Alphabetical answered 21/12, 2019 at 7:35 Comment(0)
P
3

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

Parole answered 10/2, 2023 at 14:33 Comment(0)
H
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:[email protected]" + 
    "?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")); 
}
Hardpressed answered 3/2, 2018 at 7:16 Comment(0)
B
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) { "[email protected]" })
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)
}
Brittanybritte answered 19/9, 2018 at 6:57 Comment(2)
This fails even when Gmail is on the app.Bundy
@AndroidDev in which device you are facing the issue?Brittanybritte
M
2

Kotlin:

val email: String = getEmail()
val intent = Intent(Intent.ACTION_SENDTO)
intent.data = Uri.parse("mailto:$email" )
startActivity(intent)
Manoeuvre answered 13/10, 2021 at 7:20 Comment(0)
M
2
String sendEmailTo = "[email protected]";
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

Moth answered 27/11, 2021 at 13:16 Comment(0)
F
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.

Frankish answered 2/1, 2012 at 13:54 Comment(2)
"plain/text" shows Bluetooth, Skype etc. Checkout the desired output in Android Market app. Steps are listed in the question.Contravene
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.Phidias
L
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[] { "[email protected]" });
intent.putExtra(Intent.EXTRA_SUBJECT, "subject");
intent.putExtra(Intent.EXTRA_TEXT, "mail body");
startActivity(Intent.createChooser(intent, ""));
Lemkul answered 26/5, 2015 at 13:10 Comment(0)
C
1

Use this:

boolean success = EmailIntentBuilder.from(activity)
        .to("[email protected]")
        .cc("[email protected]")
        .subject("Error report")
        .body(buildErrorReport())
        .start();

use build gradle :

compile 'de.cketti.mailto:email-intent-builder:1.0.0'
Consonantal answered 24/10, 2016 at 11:33 Comment(0)
W
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.

Weissman answered 30/12, 2016 at 17:44 Comment(1)
You are missing a " on the 2nd line.Eclogite
M
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[] {"[email protected]"});
mIntent.putExtra(Intent.EXTRA_SUBJECT, "");
startActivity(Intent.createChooser(mIntent, "Send Email Using..."));
Mays answered 1/6, 2017 at 3:28 Comment(1)
it only opens Gmail and Email in my deviceMays
S
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();
}
Stere answered 9/12, 2017 at 16:48 Comment(0)
C
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;
}
Camphorate answered 9/2, 2019 at 1:49 Comment(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..Dorty
U
1

There is an easy solution also with ACTION_VIEW:

  Intent intent = new Intent(Intent.ACTION_VIEW);
        Uri data = Uri.parse("mailto:[email protected]?subject=Feedback");
        intent.setData(data);
        startActivity(intent);
Ubald answered 23/11, 2020 at 11:19 Comment(0)
C
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("[email protected]")
        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
}
Clumsy answered 30/3, 2021 at 6:26 Comment(0)
M
1
private void sendEmail() {
        String version = getString(R.string.android_version_not_found);
        String appVersion;

        try {
            version = "Version Android: " + Build.VERSION.RELEASE + " (API " + Build.VERSION.SDK_INT + ")";
            PackageInfo packageInfo = requireActivity().getPackageManager().getPackageInfo(requireActivity().getPackageName(), 0);
            appVersion = "Version App: " + packageInfo.versionName;
        } catch (PackageManager.NameNotFoundException e) {
            appVersion = getString(R.string.app_version_not_found);
        }

        String deviceName = Build.MODEL; // Get the device name
        String subjectTemplate = getString(R.string.contact_us_subject_template);
        String subject = getString(R.string.contact_us_subject_template);

        String bodyTemplate = getString(R.string.contact_us_body_template);
        String topic = getString(R.string.problem_description) + "\n\n" + version + "\n" + appVersion + "\nDevice: " + deviceName;
        String body = String.format(bodyTemplate, topic);

        String email = getString(R.string.contact_us_email);
        String mailtoUrl = "mailto:" + email + "?subject=" + Uri.encode(subject) +
                "&body=" + Uri.encode(body);

        Intent emailIntent = new Intent(Intent.ACTION_VIEW);
        emailIntent.setData(Uri.parse(mailtoUrl));

        try {
            startActivity(Intent.createChooser(emailIntent, getString(R.string.choose_email_client)));
        } catch (ActivityNotFoundException e) {
            Toast.makeText(requireContext(), getString(R.string.install_email_client_before_sending), Toast.LENGTH_LONG).show();
        }
    }
<TextView
        android:id="@+id/txt_EmailInfor"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:autoLink="web|email"
        android:linksClickable="true"
        android:text="@string/support_emailt"
        android:textColor="@color/appBlue"
        android:textSize="@dimen/_14sdp"
        android:clickable="true"
        android:focusable="true"
        android:background="?android:attr/selectableItemBackground" />
Madonia answered 17/9, 2023 at 9:32 Comment(0)
F
0

use Anko - kotlin

context.email(email, subject, body)
Fibrovascular answered 22/9, 2018 at 13:10 Comment(0)
S
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...

Sicklebill answered 24/2, 2020 at 20:52 Comment(0)
G
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);
}
Googins answered 21/6, 2020 at 21:49 Comment(0)
W
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

Wingspan answered 26/4, 2021 at 23:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.