Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to send emails with large attachments using gmail client API on Android

I've tried the following code to create multipart email with large attachments :

Properties props = new Properties();
Session session = Session.getDefaultInstance(props, null);

MimeBodyPart mimeBodyText = new MimeBodyPart();
mimeBodyText.setHeader("Content-Type", "text/html; charset=\"UTF-8\"");
mimeBodyText.setContent(body, "text/html");

Multipart mp = new MimeMultipart();
mp.addBodyPart(mimeBodyText);

if (attachments != null && attachments.size() > 0) {
    for (Uri uri : attachments) {
        MimeBodyPart mimeBodyAttachment = new MimeBodyPart();
        String fileName = UriUtils.getFileName(uri, context);
        String mimeType = UriUtils.getMimeType(uri, context);
        Log.d(TAG, "Generating file info, uri=" + uri.getPath() + ", mimeType=" + mimeType);
        FileInputStream is = UriUtils.generateFileInfo(context, uri, mimeType);
        if (is == null) {
            throw new MessagingException("Failed to get file for uri=" + uri.getPath());
        }
        try
        {
            mimeBodyAttachment.setFileName(fileName);
            mimeBodyAttachment.setHeader("Content-Type", mimeType + "; name=\"" + fileName + "\"");
            DataSource source = new ByteArrayDataSource(is, mimeType);
            mimeBodyAttachment.setDataHandler(new DataHandler(source));
            mimeBodyAttachment.setHeader("Content-Transfer-Encoding", "base64");
            mimeBodyAttachment.setDisposition(MimeBodyPart.ATTACHMENT);
            mp.addBodyPart(mimeBodyAttachment);
        } catch (IOException e) {
            throw new MessagingException(e.getMessage());
        }
    }
}

MimeMessage mimeMessage = new MimeMessage(session);
mimeMessage.setFrom(new InternetAddress(from));
mimeMessage.addRecipient(javax.mail.Message.RecipientType.TO, new InternetAddress(recipient));
mimeMessage.setSubject(subject);
mimeMessage.setContent(mp);

Message message = createMessageWithEmail(mimeMessage);

service.users().messages().send(from, message).execute();

Which is pretty similar to what is presented in this guide, however, when I try to add a file which is larger than ~5mb, the execute function hangs and doesn't return (I would expect an error or at least a timeout but this is another issue)

After some search, I've found I need to somehow do upload request (see here), the following API in the Gmail API looks right :

Send send(java.lang.String userId, com.google.api.services.gmail.model.Message content, com.google.api.client.http.AbstractInputStreamContent mediaContent)

Unfortunately I couldn't find any doc or instruction about its usage.
When I tried to put the attachment raw as mediaContent I got an error saying the only supported mime type is message/rfc822, so I've tried taking the MimeBodyPart I'm creating in the for loop above and use it, but it looks like the attachment is just ignored.

How should one use the Gmail client API and 'upload' attachments ?

like image 264
SagiLow Avatar asked Feb 12 '16 23:02

SagiLow


People also ask

How can I send more than 25MB in Gmail Android?

If you want to send a file larger than 25MB via email, than you can do so by using Google Drive. Once you're logged into Gmail, click “compose” to create an email. Then, you'll see a paperclip icon at the bottom of the email that indicates a file attachment.

How do I find my Gmail API attachment?

In order to retrieve the the ID of the attachments of a certain message, you would have to get the message resource via Users. messages. get, and from that response, retrieve the ID of the attachment.


1 Answers

I know this question is a couple of months old, but after running into the same problem, I was able to figure it out.

My implementation is very similar to yours, all I changed was the last two lines.

So instead of using:

Message message = createMessageWithEmail(mimeMessage);

service.users().messages().send(from, message).execute();

Use:

ByteArrayOutputStream bytes = new ByteArrayOutputStream();
mimeMessage.writeTo(bytes);

ByteArrayContent content = new ByteArrayContent("message/rfc822", bytes.toByteArray());
service.users().messages().send(from, null, content).execute();
like image 83
Francisco C. Avatar answered Oct 24 '22 19:10

Francisco C.