69

I am trying to launch an Intent to send an email. All of that works, but when I try to actually send the email a couple 'weird' things happen.

here is code

Intent sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.setType("image/jpeg");
sendIntent.putExtra(Intent.EXTRA_SUBJECT, "Photo");
sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://sdcard/dcim/Camera/filename.jpg"));
sendIntent.putExtra(Intent.EXTRA_TEXT, "Enjoy the photo");
startActivity(Intent.createChooser(sendIntent, "Email:"));

So if I launch using the Gmail menu context It shows the attachment, lets me type who the email is to, and edit the body & subject. No big deal. I hit send, and it sends. The only thing is the attachment does NOT get sent.

So. I figured, why not try it w/ the Email menu context (for my backup email account on my phone). It shows the attachment, but no text at all in the body or subject. When I send it, the attachment sends correctly. That would lead me to believe something is quite wrong. Do I need a new permission in the Manifest launch an intent to send email w/ attachment? What am I doing wrong?

lopez.mikhael
  • 9,943
  • 19
  • 67
  • 110
Chrispix
  • 17,941
  • 20
  • 62
  • 70

13 Answers13

96

Also getting the same problem

Code:

Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND); 
    emailIntent.setType("image/jpeg");
    emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[] 
    {"me@gmail.com"}); 
    emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, 
    "Test Subject"); 
    emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, 
    "go on read the emails"); 
    Log.v(getClass().getSimpleName(), "sPhotoUri=" + Uri.parse("file:/"+ sPhotoFileName));
    emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file:/"+ sPhotoFileName));
    startActivity(Intent.createChooser(emailIntent, "Send mail..."));

From adb logcat:

V/DumbDumpersMain( 3972):   sPhotoUri=file://sdcard/DumbDumpers/DumbDumper.jpg
I/ActivityManager(   56):   Starting activity: Intent { action=android.intent.action.CHOOSER comp={android/com.android.internal.app.ChooserActivity} (has extras) }
I/ActivityManager(   56):   Starting activity: Intent { action=android.intent.action.SEND type=jpeg/image flags=0x3000000 comp={com.google.android.gm/com.google.android.gm.ComposeActivityGmail} (has extras) }
I/ActivityManager(   56):   Starting activity: Intent { action=android.intent.action.SEND type=jpeg/image flags=0x2800000 comp={com.google.android.gm/com.google.android.gm.ComposeActivity} (has extras) }
D/gmail-ls(  120):      MailProvider.query: content://gmail-ls/labels/me@gmail.com(null, null)
D/Gmail   ( 2507):      URI FOUND:file://sdcard/DumbDumpers/DumbDumper.jpg

Looks like the email provider is attaching a 0 length file. When I check the filesystem the file is there and correct. The code which creates the image file is well finished prior to the attempt to email it.

Anyone fixed this without magic reboots (I've already tried that)?

Update

Path for me should have been

file:///sdcard/DumbDumpers/DumbDumper.jpg

you need the extra / as this points to the root directory, i.e.:

file:// + /sdcard/DumbDumpers/DumbDumper.jpg

combined as

file:///sdcard/DumbDumpers/DumbDumper.jpg

In the above snippet you need:

emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://"+ sPhotoFileName));
starball
  • 20,030
  • 7
  • 43
  • 238
Finlay
  • 161
  • 1
  • 4
  • 7
  • 6
    I upvoted, but it would be even better if you reworked this so the final solution is worked into the code. The solution is more important than the story here. – Patrick O'Leary Jan 24 '10 at 05:47
  • 3
    I changed the answer to reflect the fact that it needs 3 slashes. I also up voted this. – Chrispix Nov 04 '10 at 13:04
  • upvote, i would not rework this because people should actually know where the error was. thanks for the solution. – mad Dec 13 '10 at 10:42
  • upvote, but EXTRA_TEXT not working in case of facebook, only image appears on my wall after post. any idea how do i resolve this. – varun bhardwaj Jan 23 '12 at 10:41
  • You should not use "hard-coded" paths because they may change depending on the device. Hence I suggest you a slight change in your code: File filelocation = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), filename); Then define: Uri path = Uri.fromFile(filelocation); and put it in your intent: emailIntent .putExtra(Intent.EXTRA_STREAM, path); – Carlos Borau Nov 24 '15 at 07:57
21

Just a little remark from my side. I've been having the same issues with GMail, but somehow it seems to work when I store the file in question on the SD card first and retrieve it from there, rather than from the assets. So my code is the following:

Intent i = new Intent(Intent.ACTION_SEND);
i.putExtra(Intent.EXTRA_SUBJECT, "Title");
i.putExtra(Intent.EXTRA_TEXT, "Content");
i.putExtra(Intent.EXTRA_STREAM, uri);
i.setType("text/plain");
startActivity(Intent.createChooser(i, "Send mail"));

and here,

uri = Uri.fromFile(new File(context.getFilesDir(), FILENAME));

does not work, whereas

uri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(), FILENAME));

does.

Regards, Michael

Michael F
  • 333
  • 3
  • 7
  • I found the same thing. I wonder if it's a permissions issue with Gmail (or other mail program) reading the file? One thing that helped me is that when I used the built-in "Mail" program (not Gmail), it showed that the attachment was 0 bytes. It was nice to know the problem existed without having to send and check my email. :-) – Tyler Collier Nov 24 '10 at 02:48
  • 1
    I would suggest replacing `startActivity()` with `startActivityForResult()` and removing the file from the root of the SD card in `onActivityResult()`. – Paul Lammertsma Nov 20 '11 at 20:53
  • I think it is not a permission issue. It is an issue with Android, that got corrected somewhere between 2.3 and 4.2. On 2.3, if I make a file on internal storage readable then other apps can open it, but gmail still can't attach it. Needs to be on external storage. On 4.2 I don't have this issue. – Tom May 30 '13 at 21:59
7

instead of "Uri.parse" use "Uri.fromFile(new File(Environment.getExternalStorageDirectory(),"file name"))"

Environment.getExternalStorageDirectory() - path to SDcard or any other external storage

Snigdha
  • 103
  • 2
  • 5
4
    Intent i = new Intent(Intent.ACTION_SEND);
    i.setType("message/rfc822");
    i.putExtra(Intent.EXTRA_EMAIL  , new String[]{"example@mail.com"});
    i.putExtra(Intent.EXTRA_SUBJECT, "Data from app");
    i.putExtra(Intent.EXTRA_TEXT   , "experience number x");
    i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 

    Uri uri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(), "filename.txt"));
    i.putExtra(Intent.EXTRA_STREAM, uri);
    startActivity(Intent.createChooser(i, "Send email..."));
4

It appears that this is actually correct, not sure what was happening, but after a reboot it started working :/

Chrispix
  • 17,941
  • 20
  • 62
  • 70
3

I got the same problem and looked everywhere for a solution. Finally I solved it by finding an open source app that worked out of the box and looked at how they did it. The code is rather long so I won't quote it here but post a link. Look at the sendEmail function in line 449

http://rehearsalassist.svn.sourceforge.net/viewvc/rehearsalassist/android/trunk/src/urbanstew/RehearsalAssistant/SessionPlayback.java?revision=94&view=markup

I refactored my code to be similar, and now it works. I hope this will help others in the same situation.

Railsdev
  • 31
  • 2
3

From RFC 1738 section 3.10:

A file URL takes the form:

   file://<host>/<path>

where host is the fully qualified domain name of the system on which the path is accessible, and path is a hierarchical directory path of the form directory/directory/.../name.

So it's file:///path/from/root just like http://host/path/from/root because there's an implicit 'localhost' between the second and third slash. But as mentioned above, use Uri.FromFile() to build it.

android.weasel
  • 3,343
  • 1
  • 30
  • 41
0

I had the same symptoms. In my case it was because I was initially saving the attachment with the permissions MODE_PRIVATE. As soon as I changed it to MODE_WORLD_READABLE it seems GMail was then able to access the file and send the attachment properly.

See more

Danny Beckett
  • 20,529
  • 24
  • 107
  • 134
0

It's work perfectly for me: On this solution the Nicolas create one copy inside Cache folder and here gmail intent has access! http://stephendnicholas.com/archives/974

lucasddaniel
  • 1,779
  • 22
  • 22
0
public void sendMail(String path) {
        Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
        emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL,
        new String[] {AppConstant.server_mail});
        emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT,
        "IBPS ERROR Mail");
        emailIntent.putExtra(android.content.Intent.EXTRA_TEXT,
        "This is an autogenerated mail from IBPS app");
        emailIntent.setType("image/png");
        Uri myUri = Uri.parse("file://" + path);
        emailIntent.putExtra(Intent.EXTRA_STREAM, myUri);
        startActivity(Intent.createChooser(emailIntent, "Send mail..."));
        }
bummi
  • 27,123
  • 14
  • 62
  • 101
Jotiram Chavan
  • 375
  • 1
  • 8
0

Also try adding Intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); This helped with my issue.

James Jones
  • 572
  • 1
  • 6
  • 17
0

I have got solution on this after 4 days, Please note following points while giving path to File class in Android(Java):

1) Use path for internal storage String path="/storage/sdcard0/myfile.txt";

2) path="/storage/sdcard1/myfile.txt";

3) mention permissions in Manifest file.

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

4) First check file length for confirmation.

5) Check paths in ES File Explorer regarding sdcard0 & sdcard1 is this same or else......

e.g.

File file=new File(path); 
long=file.length();//in Bytes
Shaishav Jogani
  • 2,111
  • 3
  • 23
  • 33
Mahadev Mane
  • 810
  • 8
  • 11
0

Send an email with an attachment: (By docs)

Intent emailIntent = new Intent(Intent.ACTION_SEND); emailIntent.setType(HTTP.PLAIN_TEXT_TYPE);

emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] {"jon@example.com"});

emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Email subject"); emailIntent.putExtra(Intent.EXTRA_TEXT, "Email message text"); emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("content://path/to/email/attachment"));

// You can also attach multiple items by passing an ArrayList of Uris

Community
  • 1
  • 1
shaiban
  • 331
  • 5
  • 12