37

I have a problem .. I want only email activities to resolve intent ACTION.SEND but beside email I get other apps as well (e.g TubeMate) even though I have set the mime type as 'message/rfc822' ... Any idea how can I get Email applications to resolve it ..

Waheed Khan
  • 1,323
  • 6
  • 18
  • 28
  • 1
    Please leave your code as-is. If your data is truly in `message/rfc822` format, then the decision on whether or not to use TubeMate is up to the user, not you. – CommonsWare Jun 28 '11 at 13:09
  • 2
    @CommonsWare Not really... I have an activity to send emails to the support team, I don't want the user to have any other option other than sending an email. PS: I am a big fan, bought your book last month :D – GabrielOshiro Jun 01 '16 at 18:34
  • This is duplicated question. I answered a way to do that from API 15 [here](http://stackoverflow.com/a/42856167/3257025) – ARLabs Mar 17 '17 at 14:06
  • this is the working solution https://stackoverflow.com/questions/8701634/send-email-intent/16217921#16217921 – chezi shem tov Apr 26 '21 at 14:25
  • @ARLabs This is not the duplicate, as it was posted two years prior to the question you cited and 6 years prior to your answer. API 15 released in December of the year this was posted, but it was posted in June. It's probably not the best idea to retrieve the intent you intend to use under false pretenses, even if it *usually* works out. That's how you create unexplained bugs. – Abandoned Cart Nov 19 '22 at 13:09

14 Answers14

77
String recepientEmail = ""; // either set to destination email or leave empty
Intent intent = new Intent(Intent.ACTION_SENDTO);
intent.setData(Uri.parse("mailto:" + recepientEmail));
startActivity(intent);

The point is to use ACTION_SENDTO as action and mailto: as data. If you want to let the user specify the destination email, use just mailto:; if you specify email yourself, use mailto:name@example.com

Suggested method filters all the application, that can send email(such as default email app or gmail)

Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
Mykhailo Gaidai
  • 3,130
  • 1
  • 21
  • 23
15

Here is how I send email with attachments (proved to work with attachments of various MIME types, even in the same email) and only allow email apps (it also has a solution for cases that no app support "mailto"). At first, we try and get activities that support mailto: format. If none are found then we get all activities that supports the message/rfc822 MIME type. We select the default app (if there is a default) or allow the user to select from the available apps. If no app supports mailto: and message/rfc822, then we use the default chooser.

public static void sendEmail(final Context p_context, final String p_subject, final String p_body, final ArrayList<String> p_attachments)
{
    try
    {
        PackageManager pm = p_context.getPackageManager();
        ResolveInfo selectedEmailActivity = null;

        Intent emailDummyIntent = new Intent(Intent.ACTION_SENDTO);
        emailDummyIntent.setData(Uri.parse("mailto:some@example.com"));

        List<ResolveInfo> emailActivities = pm.queryIntentActivities(emailDummyIntent, 0);

        if (null == emailActivities || emailActivities.size() == 0)
        {
            Intent emailDummyIntentRFC822 = new Intent(Intent.ACTION_SEND_MULTIPLE);
            emailDummyIntentRFC822.setType("message/rfc822");

            emailActivities = pm.queryIntentActivities(emailDummyIntentRFC822, 0);
        }

        if (null != emailActivities)
        {
            if (emailActivities.size() == 1)
            {
                selectedEmailActivity = emailActivities.get(0);
            }
            else
            {
                for (ResolveInfo currAvailableEmailActivity : emailActivities)
                {
                    if (true == currAvailableEmailActivity.isDefault)
                    {
                        selectedEmailActivity = currAvailableEmailActivity;
                    }
                }
            }

            if (null != selectedEmailActivity)
            {
                // Send email using the only/default email activity
                sendEmailUsingSelectedEmailApp(p_context, p_subject, p_body, p_attachments, selectedEmailActivity);
            }
            else
            {
                final List<ResolveInfo> emailActivitiesForDialog = emailActivities;

                String[] availableEmailAppsName = new String[emailActivitiesForDialog.size()];
                for (int i = 0; i < emailActivitiesForDialog.size(); i++)
                {
                    availableEmailAppsName[i] = emailActivitiesForDialog.get(i).activityInfo.applicationInfo.loadLabel(pm).toString();
                }

                AlertDialog.Builder builder = new AlertDialog.Builder(p_context);
                builder.setTitle(R.string.select_mail_application_title);
                builder.setItems(availableEmailAppsName, new DialogInterface.OnClickListener()
                {
                    @Override
                    public void onClick(DialogInterface dialog, int which)
                    {
                        sendEmailUsingSelectedEmailApp(p_context, p_subject, p_body, p_attachments, emailActivitiesForDialog.get(which));
                    }
                });

                builder.create().show();
            }
        }
        else
        {
            sendEmailUsingSelectedEmailApp(p_context, p_subject, p_body, p_attachments, null);
        }
    }
    catch (Exception ex)
    {
        Log.e(TAG, "Can't send email", ex);
    }
}

protected static void sendEmailUsingSelectedEmailApp(Context p_context, String p_subject, String p_body, ArrayList<String> p_attachments, ResolveInfo p_selectedEmailApp)
{
    try
    {
        Intent emailIntent = new Intent(Intent.ACTION_SEND_MULTIPLE);

        String aEmailList[] = { "some@example.com"};

        emailIntent.putExtra(Intent.EXTRA_EMAIL, aEmailList);
        emailIntent.putExtra(Intent.EXTRA_SUBJECT, null != p_subject ? p_subject : "");
        emailIntent.putExtra(Intent.EXTRA_TEXT, null != p_body ? p_body : "");

        if (null != p_attachments && p_attachments.size() > 0)
        {
            ArrayList<Uri> attachmentsUris = new ArrayList<Uri>();

            // Convert from paths to Android friendly Parcelable Uri's
            for (String currAttachemntPath : p_attachments)
            {
                File fileIn = new File(currAttachemntPath);
                Uri currAttachemntUri = Uri.fromFile(fileIn);
                attachmentsUris.add(currAttachemntUri);
            }
            emailIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, attachmentsUris);
        }

        if (null != p_selectedEmailApp)
        {
            Log.d(TAG, "Sending email using " + p_selectedEmailApp);
            emailIntent.setComponent(new ComponentName(p_selectedEmailApp.activityInfo.packageName, p_selectedEmailApp.activityInfo.name));

            p_context.startActivity(emailIntent);
        }
        else
        {
            Intent emailAppChooser = Intent.createChooser(emailIntent, "Select Email app");

            p_context.startActivity(emailAppChooser);
        }
    }
    catch (Exception ex)
    {
        Log.e(TAG, "Error sending email", ex);
    }
}
Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
Muzikant
  • 8,070
  • 5
  • 54
  • 88
  • 2
    Awesome fix! The rfc822 thing doesn't even work, I don't know why everyone is recommending it... maybe it used to work on older Androids – Soroush Apr 13 '15 at 22:02
11
 private void sendEmail(Connect connect) {
    Intent email = new Intent(Intent.ACTION_SENDTO);
    email.setData(Uri.parse("mailto:"));
    email.putExtra(Intent.EXTRA_EMAIL, new String[]{connect.getEmail()});
    email.putExtra(Intent.EXTRA_SUBJECT, "");
    email.putExtra(Intent.EXTRA_TEXT, "");
    try {
        startActivity(Intent.createChooser(email, getString(R.string.choose_email_client)));
    } catch (ActivityNotFoundException activityNotFoundException) {
        UIUtils.showShortSnackBar(fragmentConnectLayout, getString(R.string.no_email_client));
    }
}

Refer https://developer.android.com/guide/components/intents-common.html#Email

Ganesh Kanna
  • 2,269
  • 1
  • 19
  • 29
  • As the documentation says Intent.ACTION_SENDTO works for not attachments event if you set an attachment It won't be attached. That's the problem. – dicarlomagnus Oct 16 '20 at 20:58
5

In Android, there's no such thing as an email activity. There's also no intent filter that can be created to include only email applications. Each application (or activity) can define its own intent filters.

So when using intent ACTION_SEND, you'll have to rely on the users intelligence to pickhis favorite email app from the chooser (and not TubeMate).

ddewaele
  • 22,363
  • 10
  • 69
  • 82
  • 3
    Agreed. In fact, I just blogged about this: http://commonsware.com/blog/2011/06/28/share-where-the-user-wants.html – CommonsWare Jun 28 '11 at 14:18
4

u can also use:

//writes messages only to email clients
public void setWriteEmailButton() {
    btnWriteMail.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View arg0) {
            Intent i = new Intent(Intent.ACTION_SENDTO);
            i.setData(Uri.parse("mailto:"));
            i.putExtra(Intent.EXTRA_EMAIL  , new String[]{mConsultantInfos.getConsultantEMail()});
            i.putExtra(Intent.EXTRA_SUBJECT, mContext.getString(R.string.txtSubjectConsultantMail));
            i.putExtra(Intent.EXTRA_TEXT   , "");
            try {
                startActivity(Intent.createChooser(i, mContext.getString(R.string.txtWriteMailDialogTitle)));
            } catch (android.content.ActivityNotFoundException ex) {
                UI.showShortToastMessage(mContext, R.string.msgNoMailClientsInstalled);
            }
        }
    });
}

have fun (combination of both ;))

cV2
  • 5,229
  • 3
  • 43
  • 53
  • This happens to work with some e-maill apps, while it doesn't work with others. Amongst these "others" is K-9 (unless you have the latest version as of writing this, I believe). I highly recommend against using this hybrid approach. – class stacker Feb 22 '13 at 12:49
4

This work for me to open only email apps:

Intent intent = new Intent(Intent.ACTION_SENDTO);
intent.setData(Uri.parse("mailto:jorgesys12@gmail.com"));
startActivity(intent);
Jorgesys
  • 124,308
  • 23
  • 334
  • 268
4

Try this

String subject = "Feedback";
            String bodyText = "Enter text email";
            String mailto = "mailto:bob@example.org" +
                    "?cc=" + "" +
                    "&subject=" + Uri.encode(subject) +
                    "&body=" + Uri.encode(bodyText);

            Intent emailIntent = new Intent(Intent.ACTION_SENDTO);
            emailIntent.setData(Uri.parse(mailto));

            try {
                startActivity(emailIntent);
            } catch (ActivityNotFoundException e) {
                //TODO: Handle case where no email app is available
            }

Credit: https://medium.com/@cketti/android-sending-email-using-intents-3da63662c58f

Malik
  • 51
  • 2
1

When I use intent android.content.Intent.ACTION_SENDTO doesn't work for me because it shows many apps, some apps are not email clients. I found this way and it works perfectly for me.

Intent testIntent = new Intent(Intent.ACTION_VIEW);  
Uri data = Uri.parse("mailto:?subject=" + "blah blah subject" + "&body=" + "blah blah body" + "&to=" + "sendme@me.com");  
testIntent.setData(data);  
startActivity(testIntent);
1

This works for me

Intent intent = new Intent("android.intent.action.SENDTO", Uri.fromParts("mailto", "yourmail@gmail.com", null));
intent.putExtra("android.intent.extra.SUBJECT", "Enter Subject Here");
startActivity(Intent.createChooser(intent, "Select an email client")); 
Ashish
  • 75
  • 7
1

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

 String[] sendTo = {}; // people who will receive the email
    String subject = "implicit intent | sending email";
    String message = "Hi, this is just a test to check implicit intent.";
    Intent email = new Intent(Intent.ACTION_SENDTO);
    email.setData(Uri.parse("mailto:")); // only email apps should handle this
    email.putExtra(Intent.EXTRA_EMAIL, sendTo);
    email.putExtra(Intent.EXTRA_SUBJECT, subject);// email subject / title
    email.putExtra(Intent.EXTRA_TEXT, message);//message that you want to send

    // Create intent to show the chooser dialog
    Intent chooser = Intent.createChooser(email, "Choose an Email client :");
    // Verify the original intent will resolve to at least one activity
    if (chooser.resolveActivity(getPackageManager()) != null) {
        startActivity(chooser);
    }
Joseph Ali
  • 345
  • 1
  • 5
  • 11
0

This is an absolutely simple and 100% working approach. Thanks to the Open source developer, cketti for sharing this concise and neat solution.

String mailto = "mailto:bob@example.org" +
    "?cc=" + "alice@example.com" +
    "&subject=" + Uri.encode(subject) +
    "&body=" + Uri.encode(bodyText);

Intent emailIntent = new Intent(Intent.ACTION_SENDTO);
emailIntent.setData(Uri.parse(mailto));

try {
  startActivity(emailIntent);
} catch (ActivityNotFoundException e) {
  //TODO: Handle case where no email app is available
}

And this is the link to his/her gist.

user10496632
  • 463
  • 4
  • 13
0

Here's a code snippet that launches ONLY email apps.

Intent intent = new Intent(Intent.ACTION_SENDTO);
intent.setData(Uri.parse("mailto:example@example.com"));
intent.putExtra(Intent.EXTRA_SUBJECT, "This is the subject"));
intent.putExtra(Intent.EXTRA_TEXT, "Hi, how're you doing?"));

if (intent.resolveActivity(getActivity().getPackageManager()) != null) {
    startActivity(intent);
}

I hope this helps.

Taslim Oseni
  • 6,086
  • 10
  • 44
  • 69
0

Following three lines of code is sufficient to finish your task, nothing EXTRAS needed. Hope it helps.

Intent intent = new Intent(Intent.ACTION_SENDTO);
intent.setData(Uri.parse("mailto:destination_gmail@gmail.com"));
startActivity(Intent.createChooser(intent, "Send email using.."));
Matt Ke
  • 3,599
  • 12
  • 30
  • 49
-2

You can also use this. It's more efficient

Intent mailIntent = new Intent(Intent.ACTION_SEND);

  String mailTo[] = new String[] { "MAIL_TO_1", "MAIL_TO_2" };
  mailIntent.putExtra(Intent.EXTRA_EMAIL, mailTo);
  mailIntent.putExtra(Intent.EXTRA_SUBJECT, "Your subject");
  mailIntent.putExtra(Intent.EXTRA_TEXT, "MailsBody");
  mailIntent.setType("plain/text");

  startActivity(Intent.createChooser(mailIntent, "only email client"));

This code sample show only email client which are currently installed on your device

Festus Tamakloe
  • 11,231
  • 9
  • 53
  • 65
  • 2
    This answer is plain wrong in the context of this question. This will bring up a dozen or so apps to choose from on one of my devices, two of them being e-mail apps. Also, please elaborate on what you mean by _more efficient_. – class stacker Feb 22 '13 at 12:47
  • The MIME type is "text/plain" not "plain/text" – Sean Owen Mar 06 '13 at 12:22