26

My app integrates e-mail where the user can submit a bug report, feedback, etc. from the app directly. I'm using the application/octet-stream as the SetType for the Intent. When you go to submit the e-mail you get the content chooser and it shows various items from Evernote, Facebook, E-mail, etc.

How can I get this chooser to only show E-mail so as not to confuse the user with all these other items that fit the content chooser type?

Thank you.

Neal
  • 8,849
  • 13
  • 54
  • 98
  • 1
    Did you add all the extras as shown here: http://stackoverflow.com/questions/2197741/how-to-send-email-from-my-android-application/2197841#2197841 ? – Aleadam Jun 06 '11 at 18:07
  • Yes, I sure did. It works, it sends the e-mail. I'm just trying to remove the clutter of everything that the content chooser shows. I just want to show "E-mail" or e-mail related programs. I'm not sure why all these others appear, I assume it's because they can handle the application/octet-stream type. – Neal Jun 06 '11 at 18:11
  • Presumably you run into the same problem with message/rfc822? – Jasoon Jun 06 '11 at 18:15
  • See this question http://stackoverflow.com/questions/8701634/send-email-intent – dira Jul 19 '13 at 11:24

9 Answers9

37

To solve this issue simply follow the official documentation. The most important consideration are:

  1. The flag is ACTION_SENDTO, and not ACTION_SEND.

  2. The setData of method of the intent,

    intent.setData(Uri.parse("mailto:")); // only email apps should handle this

If you send an empty Extra, the if() at the end won't work and the app won't launch the email client.

This works for me. According to Android documentation. 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);
    }
}

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

Pedro Varela
  • 2,099
  • 1
  • 21
  • 31
  • I am sorry about the attachment issue. I am not sure how to implement that. I suppose this features are only to share text only through intents. – Pedro Varela Sep 10 '15 at 15:18
13

I am presuming that you are using the ACTION_SEND Intent action, since you did not bother to actually state what you're using, but you agreed with @Aleadam's comment.

I'm using the application/octet-stream as the SetType for the Intent.

Nothing in that sentence limits things to email.

ACTION_SEND is a generic Intent action that can be supported by any application that wants to. All you do is indicate what data you are sharing and the MIME type of that data -- from there, it is up to the user to choose from available activities.

As @Jasoon indicates, you can try message/rfc822 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.

If you specifically want to send something by email, integrate JavaMail into your app, or write an email forwarding script on your Web server and invoke it, or something. If you use ACTION_SEND, you are implicitly stating that it is what the user wants that matters, and you want the user to be able to send such-and-so data by whatever means the user chooses.

CommonsWare
  • 910,778
  • 176
  • 2,215
  • 2,253
9

Just struggled with this problem while implementing a Magic Link feature, a chooser intent for all installed email apps:

Chooser Intent Screenshot

private void openEmailApp() {
  List<Intent> emailAppLauncherIntents = new ArrayList<>();

  //Intent that only email apps can handle:
  Intent emailAppIntent = new Intent(Intent.ACTION_SENDTO);
  emailAppIntent.setData(Uri.parse("mailto:"));
  emailAppIntent.putExtra(Intent.EXTRA_EMAIL, "");
  emailAppIntent.putExtra(Intent.EXTRA_SUBJECT, "");

  PackageManager packageManager = getPackageManager();

  //All installed apps that can handle email intent:
  List<ResolveInfo> emailApps = packageManager.queryIntentActivities(emailAppIntent, PackageManager.MATCH_ALL);

  for (ResolveInfo resolveInfo : emailApps) {
    String packageName = resolveInfo.activityInfo.packageName;
    Intent launchIntent = packageManager.getLaunchIntentForPackage(packageName);
    emailAppLauncherIntents.add(launchIntent);
  }

  //Create chooser
  Intent chooserIntent = Intent.createChooser(new Intent(), "Select email app:");
  chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, emailAppLauncherIntents.toArray(new Parcelable[emailAppLauncherIntents.size()]));
  startActivity(chooserIntent);
}
Fisk Debug
  • 126
  • 1
  • 4
  • I too am implementing magic link feature and I just wanted to show the chooser to show all email clients and then just view the inbox. Most of the solutions mentioned are to send an email. your solution works perfectly for my usecase thank you! – user2622786 Aug 14 '17 at 23:34
  • I have one issue when fire intent not getting any email launcher app. I have gmail app and outlook also – Pravin Fofariya Apr 27 '18 at 06:01
  • `PackageManager.MATCH_ALL` could be deceiving here. I believe this will disable any filtering of the results that is happening automatically by the OS (possibly through user settings). This may not be what you want. The standard `PackageManager.MATCH_DEFAULT_ONLY` might be appropriate in some situations. – Acadian_Ghost Jun 06 '19 at 18:28
  • I have been looking for a solution to this problem as all other answers I've seen on the topic only opened Gmail. This solution worked for getting Outlook to display too. Thank you, fellow interweb friend! – Poliziano May 29 '21 at 15:37
2

There is a way more generic to do that, working with any MIME type.

See this post: How to customize share intent in Android?

Community
  • 1
  • 1
Derzu
  • 6,253
  • 1
  • 49
  • 56
0

It is possible to limit the choices of an intent chooser to just a few options. The code in the answer to this question is a good example. In essence, you would have to create a List of LabeledIntents to provide to the intent chooser, that will then include it in its list. Note that this solution works not on exclusion (certain apps are excluded while the rest remain) but instead you have to pick which apps to display. Hope it helps!

Community
  • 1
  • 1
0

It works on all devices. It will show only Email Apps

public static void shareViaMail(Activity activity, String title, String body, String filePath) {

    Uri URI = Uri.parse("file://" + filePath);
    final Intent emailIntent = new Intent(Intent.ACTION_VIEW);

    emailIntent.setData(Uri.parse("mailto:"));

    emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[]{"contact@brightsociety.com"});

    if (URI != null) {
        emailIntent.putExtra(Intent.EXTRA_STREAM, URI);
    }
    try {
        activity.startActivity(emailIntent);
    } catch (Exception e) {
        ((BaseActivity) activity).showToast("Gmail App is not installed");
        e.printStackTrace();
    }
}
TofferJ
  • 4,216
  • 1
  • 31
  • 43
Sonia Rana
  • 107
  • 1
  • 4
-1

It works on all devices.It will show only Email Apps

public static void shareViaMail(Activity activity, String title, String body, String filePath) {
        Uri URI = Uri.parse("file://" + filePath);
        final Intent emailIntent = new Intent(Intent.ACTION_VIEW);
        emailIntent.setData(Uri.parse("mailto:"));
        emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[]{"xyz@gmail.com"});
        /*if you want to attach something*/
        if (URI != null) {
            emailIntent.putExtra(Intent.EXTRA_STREAM, URI);
        }
        try {
            activity.startActivity(emailIntent);
        } catch (Exception e) {
            ((BaseActivity) activity).showToast("Gmail App is not installed");
            e.printStackTrace();
        }
}
Community
  • 1
  • 1
Sonia Rana
  • 107
  • 1
  • 4
-1

Solution is very simple:

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);  

See: http://www.gaanza.com/blog/email-client-intent-android/

Volodymyr T
  • 118
  • 8
-1

After a lot of searching and testing, I finally found a perfect solution. Thanks to the Open source developer, cketti for sharing his/her 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
  • 363
  • 2
  • 13