Attachment is not coming in mail programmatically
Asked Answered
C

6

29

I am attaching a TEXT file to Email with code :

Intent emailIntent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts("mailto",
                                    "[email protected]", null));

    emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Report");

    emailIntent.putExtra(Intent.EXTRA_TEXT, prepareBodyMail());
    File root = Environment.getExternalStorageDirectory();
    File file = new File(root, "/MyFolder/report.txt");

    Uri uri = Uri.fromFile(file);
    emailIntent.putExtra(Intent.EXTRA_STREAM, uri);
    startActivity(Intent.createChooser(emailIntent, "Pick an Email provider"));

This code works perfectly with Gmail, Email and other apps

But this is not attaching file with INBOX application by Google

Only Body and subject are coming without any attachment

I have reported this problem to Google Groups at Inbox Problem

Can anybody help what I am missing in code?

Capricorn answered 7/7, 2015 at 7:23 Comment(8)
hey did you fixed your issue or you still searching. please try my provided solution hope this will work for youStirring
I am still searching for solution.. I have reported the issue to Google groups also.. hopefully that will be resolved..Capricorn
Same issue for me, have not been able to find a solution anywhere.Hebel
Having the same issue :(Weirdo
@Capricorn Did you find a solution?Provocative
@Provocative No, Unfortunately i could not find solution yet...Capricorn
@Capricorn I see. It is very strange, it does not work on the outlook mail app either.Provocative
@Provocative Yes, rightCapricorn
A
1

In Kotlin

fun Context.shareAttachmentsToMail(mailId: String?, uri: Uri, subject: String, bodyMessage: String){
  
    val selectorIntent = Intent(ACTION_SENDTO).apply {
        data = Uri.parse("mailto:")
    }
    val emailIntent = Intent(ACTION_SEND).apply {
        putExtra(Intent.EXTRA_EMAIL, arrayOf(mailId))
        putExtra(Intent.EXTRA_SUBJECT, subject)
        putExtra(Intent.EXTRA_TEXT, bodyMsg)
        putExtra(Intent.EXTRA_STREAM, uri)
        selector = selectorIntent
    }
    try {
        startActivity(Intent.createChooser(emailIntent, ""))
    } catch (e: ActivityNotFoundException) {
        // Application not found
    }
}

Call this extension function like this:

requireContext().shareAttachmentsToMail(mailId = mailId, uri = uri, subject = "your subject", bodyMessage = "your body message")
Antinucleon answered 27/4, 2023 at 12:35 Comment(0)
B
0
String fileLocation = Environment.getExternalStorageDirectory() + "/MyFolder/report.txt";    
String to[] = {"[email protected]"};

Intent intentEmail = new Intent(Intent.ACTION_SEND);
intentEmail.setType("vnd.android.cursor.dir/email");
intentEmail.putExtra(Intent.EXTRA_EMAIL, to);
intentEmail.putExtra(Intent.EXTRA_STREAM, fileLocation);
intentEmail.putExtra(Intent.EXTRA_SUBJECT, "Subject");

startActivity(Intent.createChooser(intentEmail , "Pick an Email provider"));
Brethren answered 7/7, 2015 at 7:28 Comment(1)
This is also not working with Inbox application.. I think we should give Uri type parameter wirh Intent.EXTRA_STREAM kay in intent.. This is problem in your codeCapricorn
P
0

Try this

     Uri myUri = Uri.parse("file://" + path);
     emailIntent.putExtra(Intent.EXTRA_STREAM, myUri);
Parmentier answered 7/7, 2015 at 7:55 Comment(0)
S
0
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_EMAIL, new String[] {"[email protected]"});
intent.putExtra(Intent.EXTRA_SUBJECT, "subject here");
intent.putExtra(Intent.EXTRA_TEXT, "body text");
File root = Environment.getExternalStorageDirectory();
File file = new File(root, xmlFilename);
if (!file.exists() || !file.canRead()) {
    Toast.makeText(this, "Attachment Error", Toast.LENGTH_SHORT).show();
    finish();
    return;
}
Uri uri = Uri.fromFile("file://" + file);
intent.putExtra(Intent.EXTRA_STREAM, uri);
startActivity(Intent.createChooser(intent, "Send email..."));
Stirring answered 7/7, 2015 at 9:29 Comment(2)
This is working for Gmail, Email applications but it is not working with Inbox application..Capricorn
I have already mentioned that my code is working with Gmail and Email but not with Inbox..Capricorn
G
0
  public void sendMailWithIntent(String emailTo,
                                   String subject, String emailText, List<String> filePaths) {
        try {
            //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,
                    Util.extractEmails(emailTo));
//            emailIntent.putExtra(android.content.Intent.EXTRA_CC,
//                    new String[]{emailCC});
            emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
            emailIntent.putExtra(Intent.EXTRA_TEXT, emailText);
            ArrayList<Uri> uris = new ArrayList<Uri>();
            //has to be an ArrayList
            if (filePaths != null) {
                //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);
            Intent chooser = Intent.createChooser(emailIntent, "Send mail...");
            activity.startActivityForResult(chooser, 1);
        } catch (Exception e) {
            new ShowToast(context, e.getMessage());
        }

    }

Call method

    List<String> list = new ArrayList<>();
    list.add(TO_ATTACH_ONE);
    list.add(TO_ATTACH_TWO);
    sendMailWithIntent(toAddresses, subject, body, list);
Godbey answered 7/7, 2015 at 12:4 Comment(0)
P
0

It looks like that ACTION_SENDTO doesn't support attachments officially. It works only for Gmail and default email client because they use "undocumented" feature. The only way I found to send emails with attachments is to use ACTION_SEND instead.

My solution:

public class EmailSender {

private static final String INTENT_DATA_SCHEME_EMAIL = "mailto:";
private static final String FILE_PROVIDER_AUTHORIZER = "com.smartinhalerlive.app.fileprovider";

private String subject;
private String body;
private File attachment;

public EmailSender(String subject, String body, File attachment) {
    this.subject = subject;
    this.body = body;
    this.attachment = attachment;
}

public void sendEmail(Context context, EmailSenderListener listener) {
    List<ResolveInfo> emailClients = getEmailClients(context);

    if (null != emailClients) {
        ResolveInfo defaultEmailClient = getDefaultEmailClient(emailClients);

        if (null != defaultEmailClient) {
            sendEmailUsingSelectedEmailClient(context, defaultEmailClient, listener);
        } else {
            showSelectEmailClientsDialog(context, emailClients, listener);
        }
    }
}

private void showSelectEmailClientsDialog(Context context,
                                          List<ResolveInfo> emailClients,
                                          EmailSenderListener listener) {
    String[] emailClientNames = getEmailClientNames(context, emailClients);

    AlertDialog.Builder builder = new AlertDialog.Builder(context);
    builder.setTitle(R.string.email_dialog_title);
    builder.setItems(emailClientNames, (dialog, which) -> {
                sendEmailUsingSelectedEmailClient(context, emailClients.get(which), listener);
            }
        );

    builder.create().show();
}

@NonNull
private static String[] getEmailClientNames(Context context, List<ResolveInfo> emailClients) {
    PackageManager packageManager = context.getPackageManager();
    String[] emailClientNames = new String[emailClients.size()];
    for (int i = 0; i < emailClients.size(); i++) {
        emailClientNames[i] = emailClients.get(i).activityInfo.applicationInfo.loadLabel(packageManager).toString();
    }
    return emailClientNames;
}

@Nullable
private static ResolveInfo getDefaultEmailClient(List<ResolveInfo> emailClients) {
    ResolveInfo defaultEmailClient = null;
    if (emailClients.size() == 1) {
        defaultEmailClient = emailClients.get(0);
    } else {
        for (ResolveInfo emailClient : emailClients) {
            if (emailClient.isDefault) {
                defaultEmailClient = emailClient;
                break;
            }
        }
    }
    return defaultEmailClient;
}

private static List<ResolveInfo> getEmailClients(Context context) {
    PackageManager pm = context.getPackageManager();
    Intent emailDummyIntent = getEmptyEmailIntent();
    return pm.queryIntentActivities(emailDummyIntent, 0);
}

public static Intent getEmptyEmailIntent() {
    Intent emailIntent = new Intent(Intent.ACTION_SENDTO);
    emailIntent.setData(Uri.parse(INTENT_DATA_SCHEME_EMAIL));
    return emailIntent;
}

private static void grantReadPermissionForAttachmentUri(Context context,
                                                        Intent emailIntent,
                                                        Uri attachmentUri) {
    if (emailIntent == null || attachmentUri == null) {
        return;
    }
    context.grantUriPermission(emailIntent.getComponent().getPackageName(),
            attachmentUri,
            Intent.FLAG_GRANT_READ_URI_PERMISSION);
}

private void sendEmailUsingSelectedEmailClient(Context context,
                                               ResolveInfo emailClient,
                                               EmailSenderListener listener) {
    try {
        Intent emailIntent = new Intent(Intent.ACTION_SEND);

        emailIntent.putExtra(Intent.EXTRA_SUBJECT, null != subject ? subject : "");
        emailIntent.putExtra(Intent.EXTRA_TEXT, null != body ? body : "");
        emailIntent.setComponent(new ComponentName(emailClient.activityInfo.packageName, emailClient.activityInfo.name));
        addAttachment(context, attachment, emailIntent);

        listener.onEmailIntentReady(emailIntent);
    } catch (Exception ex) {
        Timber.e("Error sending email", ex);
    }
}

private static void addAttachment(Context context, File attachment, Intent emailIntent) {
    if (attachment != null) {
        Uri contentUri = FileProvider.getUriForFile(context, FILE_PROVIDER_AUTHORIZER, attachment);
        grantReadPermissionForAttachmentUri(context, emailIntent, contentUri);
        emailIntent.putExtra(Intent.EXTRA_STREAM, contentUri);
    }
}

public interface EmailSenderListener {
    void onEmailIntentReady(Intent emailIntent);
}

}

Palacio answered 9/7, 2018 at 5:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.