102

I've been working on Android program to send email with an attachment (image file, audio file, etc) using Intent with ACTION_SEND. The program is working when email has a single attachment. I used Intent.putExtra(android.content.Intent.EXTRA_STREAM, uri) to attach the designated image file to the mail and it is working fine, the mail can be delivered through the Gmail. However, when I tried to have multiple images attached to the same mail by calling Intent.putExtra(android.content.Intent.EXTRA_STREAM, uri) multiple times, it failed to work. None of the attachment show up in the email.

I searched the SDK documentation and Android programming user group about email attachment but cannot find any related info. However, I've discovered that there's another intent constant ACTION_SEND_MULTIPLE (available since API level 4) which might meet my requirement. Based on SDK documentation, it simply states that it deliver multiple data to someone else, it works like ACTION_SEND, except the data is multiple. But I still could not figure out the correct usage for this command. I tried to declare intent with ACTION_SEND_MULTIPLE, then call putExtra(EXTRA_STREAM, uri) multiple times to attach multiple images, but I got the same erroneous result just like before, none of the attachment show up in the email.

Has anyone tried with ACTION_SEND_MULTIPLE and got it working with multiple email attachment?

Volo
  • 28,673
  • 12
  • 97
  • 125
yyyy1234
  • 1,021
  • 2
  • 8
  • 4
  • I have the same problem. It is not working code. The same problem exists during sending MMS, there is possibility to add only one file. Do you have the some ideas to it in the another way ?? –  Nov 08 '10 at 16:24

5 Answers5

189

Here is the code you need to create an emailIntent that contains multiple attachments.

public static void email(Context context, String emailTo, String emailCC,
    String subject, String emailText, List<String> filePaths)
{
    //need to "send multiple" to get more than one attachment
    final Intent emailIntent = new Intent(Intent.ACTION_SEND_MULTIPLE);
    emailIntent.setType("text/plain");
    emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, 
        new String[]{emailTo});
    emailIntent.putExtra(android.content.Intent.EXTRA_CC, 
        new String[]{emailCC});
    emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject); 
    emailIntent.putExtra(Intent.EXTRA_TEXT, emailText);
    //has to be an ArrayList
    ArrayList<Uri> uris = new ArrayList<Uri>();
    //convert from paths to Android friendly Parcelable Uri's
    for (String file : filePaths)
    {
        File fileIn = new File(file);
        Uri u = Uri.fromFile(fileIn);
        uris.add(u);
    }
    emailIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);
    context.startActivity(Intent.createChooser(emailIntent, "Send mail..."));
}
Jared Burrows
  • 54,294
  • 25
  • 151
  • 185
gregm
  • 12,019
  • 7
  • 56
  • 78
  • 2
    you forgot to put the subject and emailText to the intent. otherwise thanks for the code. – Bahadır Yağan Jul 09 '11 at 14:12
  • 5
    The correct MIME data type should be "text/plain" and not "plain/text": `emailIntent.setType("text/plain");`. If you use "plain/text" Android will force to use GMail as a sender, but if you use "text/plain" it will provide application chooser dialog with Gmail, Facebook, Bluetooth etc. If you would like to propose only mail programs use "text/xml" instead. – Volo Oct 10 '11 at 10:47
  • 4
    And if you change last line to `context.startActivity(emailIntent);` the checkbox "Use by default for this action" will appear in the application chooser dialog, thus user will be able to select the default application for sending the emails with multiple attachments. – Volo Oct 10 '11 at 10:57
  • 2
    This example is netting me an "AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?" I've tried passing both the Application and base context to this e-mail method, and both result in the same error. – ravemir Dec 29 '12 at 18:48
  • [This](http://stackoverflow.com/questions/3689581/calling-startactivity-from-outside-of-an-activity) solved it for me, but I'm not sure if I'm escaping an error in a weird way, so I'll leave the previous comment here for anyone who has any idea about it. – ravemir Dec 29 '12 at 18:52
  • Also, the Subject and Body components aren't being sent: `emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject); emailIntent.putExtra(Intent.EXTRA_TEXT, emailText);` – ravemir Dec 29 '12 at 19:12
  • I just pulled my hair on where did you get that generic `ArrayList` from when I realized this is Java... for those doing it in C#/Xamarin, it works just as well, get rid of the camel casing and write `var uris = new List();` – Cee McSharpface Sep 17 '17 at 17:22
31

ACTION_SEND_MULTIPLE should be the action

and then emailIntent.setType("text/plain");

followed by:

ArrayList<Uri> uris = new ArrayList<Uri>();
String[] filePaths = new String[] {"sdcard/sample.png", "sdcard/sample.png"};
for (String file : filePaths)
{
    File fileIn = new File(file);
    Uri u = Uri.fromFile(fileIn);
    uris.add(u);
}
emailIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);
startActivity(emailIntent);

This works for me.

Volo
  • 28,673
  • 12
  • 97
  • 125
santhana
  • 311
  • 3
  • 2
20

Although this is an old thread, but as it is shown on top on google searches i want to add a small hint to make it complete, hence I stumpled upon it.

It is necessary to make the attached files readable for the mail activity, otherwise they will not be attached. So you have to call somewhere

fileIn.setReadable(true, false)
thomas
  • 265
  • 2
  • 4
  • Thank you sir, the mail wasn't able to send the attachments only the mail. – Josejulio Mar 13 '14 at 00:11
  • Thank you, man! I couldn't make the pictures to be sent without this line – konunger Jun 28 '14 at 20:58
  • WOW! this answer totally saved my day. If anyone gets "one or more files not attached. limit 20mb" error from gmail app, this fix solves everything. Best tip ever! – belphegor Feb 15 '16 at 21:04
19

Here I found great example http://www.blackmoonit.com/2010/02/filebrowser-send-receive-intents/

you must use

final Intent aIntent = new Intent(Intent.ACTION_SEND_MULTIPLE);
aIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM,theUris);
aIntent.setType(theOverallMIMEtype);
Jared Burrows
  • 54,294
  • 25
  • 151
  • 185
printminion
  • 2,988
  • 1
  • 26
  • 30
4

For multiple attachments use PutParcelableArrayListExtra(Intent.ExtraStream, uris)where uris variable is a List<IParcelable>(). Here's an example:

var email = new Intent(Intent.ActionSendMultiple);
    email.SetType("text/plain");
    email.PutExtra(Intent.ExtraEmail, new string[]{emailTo});
    email.PutExtra(Intent.ExtraCc, new string[]{emailCC});

    var uris = new List<IParcelable>();
    filePaths.ForEach(file=> {
        var fileIn = new File(file);
        var uri = Android.Net.Uri.FromFile(fileIn);
        uris.Add(uri);
    });

    email.PutParcelableArrayListExtra(Intent.ExtraStream, uris);

    context.StartActivity(Intent.CreateChooser(email, "Send mail..."));

Hope this helps ;)