Sending an email with attachments programmatically on Android

Digital Da picture Digital Da · Mar 2, 2015 · Viewed 34.2k times · Source

I wish to implement a button that upon pressing it will open the default email client with an attachment file.

I am following this, but am getting an error message on the startActivity, saying it is expecting an activity param while I am giving it an intent. I am using API 21 and Android Studio 1.1.0, so perhaps it has something to do with the comment in the answer provided in the link?

This is my fourth day as Android developer so sorry if I am missing something really basic.

Here is my code:

    public void sendFileToEmail(File f){

    String subject = "Lap times";
    ArrayList<Uri> attachments = new ArrayList<Uri>();
    attachments.add(Uri.fromFile(f));
    Intent intent = new Intent(Intent.ACTION_SEND_MULTIPLE);
    intent.putExtra(Intent.EXTRA_SUBJECT, subject);
    intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, attachments);
    intent.setClassName("com.android.email", "com.android.mail.compose.ComposeActivity");

    try {
        startActivity(intent);
    } catch (ActivityNotFoundException e) {
        e.printStackTrace();
    }

Answer

King of Masses picture King of Masses · Mar 2, 2015

Official documentation with Kotlin snippets is here: https://developer.android.com/guide/components/intents-common#ComposeEmail

I think your problem is that you are not using the correct file path.

The following works for me:

Intent emailIntent = new Intent(Intent.ACTION_SEND);
emailIntent.setType("text/plain");
emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] {"[email protected]"});
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "subject here");
emailIntent.putExtra(Intent.EXTRA_TEXT, "body text");
File root = Environment.getExternalStorageDirectory();
String pathToMyAttachedFile = "temp/attachement.xml";
File file = new File(root, pathToMyAttachedFile);
if (!file.exists() || !file.canRead()) {
    return;
}
Uri uri = Uri.fromFile(file);
emailIntent.putExtra(Intent.EXTRA_STREAM, uri);
startActivity(Intent.createChooser(emailIntent, "Pick an Email provider"));

EDIT: Requesting access to storage just to share a file private to your app is probably not a good idea. Fortunately, after a little configuration, it's very easy to share a file from your app private storage. See this guide: https://developer.android.com/training/secure-file-sharing/setup-sharing

If you share a file that is on external storage, you also need to give the user permission via a manifest file like below

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>