How to send an email with a file attachment in Android

94,224

Solution 1

Use the below code to send a file within a email.

String filename="contacts_sid.vcf"; 
File filelocation = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), filename);
Uri path = Uri.fromFile(filelocation); 
Intent emailIntent = new Intent(Intent.ACTION_SEND);
// set the type to 'email'
emailIntent .setType("vnd.android.cursor.dir/email");
String to[] = {"[email protected]"};
emailIntent .putExtra(Intent.EXTRA_EMAIL, to);
// the attachment
emailIntent .putExtra(Intent.EXTRA_STREAM, path);
// the mail subject
emailIntent .putExtra(Intent.EXTRA_SUBJECT, "Subject");
startActivity(Intent.createChooser(emailIntent , "Send email..."));

Solution 2

Folder_name is the name of the file in the Internal Storage of your phone. (ACTUALLY EXTERNAL_STORAGE). file_name is the name of the file you want to send.

private void ShareViaEmail(String folder_name, String file_name) {
    try {
        File root= Environment.getExternalStorageDirectory();
        String filelocation= root.getAbsolutePath() + folder_name + "/" + file_name;
        Intent intent = new Intent(Intent.ACTION_SENDTO);
        intent.setType("text/plain");
        String message="File to be shared is " + file_name + ".";
        intent.putExtra(Intent.EXTRA_SUBJECT, "Subject");
        intent.putExtra(Intent.EXTRA_STREAM, Uri.parse( "file://"+filelocation));
        intent.putExtra(Intent.EXTRA_TEXT, message);
        intent.setData(Uri.parse("mailto:[email protected]"));
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

        startActivity(intent);
    } catch(Exception e)  {
        System.out.println("is exception raises during sending mail"+e);
    }
}

Solution 3

The example on the official Android site worked for me. All what is need it to add the

startActivity(Intent.createChooser(emailIntent , "Send email..."));

as done in Agarwal's answer

Solution 4

SENDTO doesnt support attachment. I have added my answer using Provider to read the file information. Its in Kotlin.

fun shareFile(context: Context, filePath: File?, fileShareInfo: FileShareInfo) {

    val intentFileShare = Intent(Intent.ACTION_SEND)

    if (filePath!!.exists()) {
        intentFileShare.type = fileShareInfo.fileType
        val uri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".provider", filePath)
        intentFileShare.putExtra(Intent.EXTRA_STREAM, uri)
        fileShareInfo.recipients?.let {
            intentFileShare.putExtra(Intent.EXTRA_EMAIL, fileShareInfo.recipients)
        }
        intentFileShare.putExtra(Intent.EXTRA_SUBJECT, fileShareInfo.shareSubjectText)
        fileShareInfo.shareExtraText?.let {
            intentFileShare.putExtra(Intent.EXTRA_TEXT, AppViewUtil.fromHtml(fileShareInfo.shareExtraText!!))
        }
        try {
            ContextCompat.startActivity(context, Intent.createChooser(intentFileShare, fileShareInfo.shareTitle), null)
        } catch (e: ActivityNotFoundException) {
            Toast.makeText(context, context.getString(R.string.sharing_no_app_found), Toast.LENGTH_LONG).show()
        }

    }
}

Solution 5

I have written an extension in Kotlin for sending emails with multiple attachments. I hope it is useful for someone.

fun AppCompatActivity.sendEmail(subject: String, content: String, email: String, fileAttachments: List<String> = emptyList()) {

    val emailIntent = Intent(Intent.ACTION_SEND_MULTIPLE).apply {
        type = "text/html"
        putExtra(Intent.EXTRA_SUBJECT, subject)
        addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        putExtra(Intent.EXTRA_TEXT, content)
        putExtra(Intent.EXTRA_EMAIL, arrayOf(email))

        // Configure attachments
        val attachments = fileAttachments.map { File(it) }.filter { it.exists() && !it.isDirectory }.map {
            FileProvider.getUriForFile(baseContext, "${BuildConfig.APPLICATION_ID}.fileprovider", it)
        }.toList()

        if(attachments.isNotEmpty())
            putParcelableArrayListExtra(Intent.EXTRA_STREAM, ArrayList(attachments))
    }

    if (emailIntent.resolveActivity(packageManager) != null)
        startActivity(Intent.createChooser(emailIntent, "Chooser Mail Client"))
}
Share:
94,224
Naresh Sharma
Author by

Naresh Sharma

I am a fun loving and lazy person who want to learn new things. We are here to help each other, So always share your knowledge with others it also helps you too. My twitter - https://twitter.com/snaresh22 My LinkedIn - http://www.linkedin.com/pub/naresh-sharma/50/44b/40a

Updated on July 09, 2022

Comments

  • Naresh Sharma
    Naresh Sharma almost 2 years

    I want to attach .vcf file with my mail and send through the mail. But the mail is received on the address without the attachment.I have used the below code but the code for this and i don't know where i am wrong.

    try {      
      String filelocation="/mnt/sdcard/contacts_sid.vcf";      
      Intent intent = new Intent(Intent.ACTION_SENDTO);    
      intent.setType("text/plain");      
      intent.putExtra(Intent.EXTRA_SUBJECT, "");      
      intent.putExtra(Intent.EXTRA_STREAM, Uri.parse( "file://"+filelocation));      
      intent.putExtra(Intent.EXTRA_TEXT, message);         
      intent.setData(Uri.parse("mailto:"));         
      intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
    
      activity.startActivity(intent);
      activity.finish();
      } catch(Exception e)  {
         System.out.println("is exception raises during sending mail"+e);
    }
    
  • NagarjunaReddy
    NagarjunaReddy over 11 years
    one look at my question...stackoverflow.com/questions/12798001/…
  • kAmol
    kAmol over 8 years
    In my case, its going to mail client but without attachment. toast displayed is "cant send empty file". my file is stored at /data/data/com.example.app/files/temp.txt and I'm passing it using emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("content:/"+filePath)); // filePath is /data/com.example.app/files/temp.txt
  • Borzh
    Borzh over 8 years
    You can't send file because it is in your app's cache directory, and only your app can read from that directory. You should use another directory, like Environment.getExternalStorageDirectory().
  • Carlos Borau
    Carlos Borau over 8 years
    You should not use "hard-coded" paths because they may change depending on the device. I suggest you changing the definition of filelocation to: File filelocation = new File(Environment.getExternalStorageDirectory().getAbsolutePa‌​th(), filename); Then define: Uri path = Uri.fromFile(filelocation); and put it in your intent: emailIntent .putExtra(Intent.EXTRA_STREAM, path);
  • andytrombone
    andytrombone over 8 years
    emailIntent.putExtra(Intent.EXTRA_STREAM, filelocation) wouldn't attach the file for me, but using emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse( "file://"+filelocation)) as did Phillip worked fine.
  • CESDewar
    CESDewar about 8 years
    Used Environment.getExternalStorageDirectory(), verified that path was valid and that file had good data.... but still get the same error message (?).
  • Alan Nelson
    Alan Nelson almost 4 years
    How does this work if the file is not-yet saved? I have the image data as a Bitmap, but not a file. Can you provide the code to save the Bitmap first before we load it from file?