15

My app creates a PDF using iText library (template PDF with forms which are filled) and I want to then attach it to an email to send. When I try to attach the file I get the error Can't attach empty file in the Gmail app. Have also tried with the HTC email app and Touchdown email app - both of which just don't attach anything and give no error.

Creating the PDF:

public void manipulatePdf(String src, String dest) throws IOException, DocumentException {
        PdfReader reader = new PdfReader(src);
        PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
        AcroFields form = stamper.getAcroFields();

// Fill all PDF forms here (theres quite a few)

        stamper.setFormFlattening(true);
        stamper.close();
        reader.close();
}

Attempting to attach file and send email:

public void sendMail(){
    Intent emailIntent = new Intent(Intent.ACTION_SEND);
    emailIntent .setType("*/*");
    emailIntent .putExtra(Intent.EXTRA_EMAIL, "blah@gmail.com");
    emailIntent .putExtra(Intent.EXTRA_STREAM, Uri.parse(dest));
    emailIntent .putExtra(Intent.EXTRA_SUBJECT, "Subject");
    startActivity(Intent.createChooser(emailIntent, "Send email..."));
}

Where dest is the path and filename of the file in question. I know the path and filename in dest are ok as this is the var used to save the file (which I can view fine on both the device and on a PC).

Gmail logcat:

06-26 00:24:48.901  14476-14476/? E/Gmail﹕ Error adding attachment
    com.android.mail.utils.b: Cannot attach empty attachment
            at com.android.mail.ui.ComposeAttachmentTileGrid.a(SourceFile:62)
            at com.android.mail.compose.c.b(SourceFile:1933)
            at com.android.mail.compose.c.c(SourceFile:2063)
            at com.android.mail.compose.c.a(SourceFile:7992)
            at com.android.mail.compose.c.q(SourceFile:759)
            at com.android.mail.compose.c.onCreate(SourceFile:4830)
            at com.google.android.gm.ComposeActivityGmail.onCreate(SourceFile:194)
            at android.app.Activity.performCreate(Activity.java:5958)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1129)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2364)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2474)
            at android.app.ActivityThread.access$800(ActivityThread.java:144)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1359)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:155)
            at android.app.ActivityThread.main(ActivityThread.java:5696)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1028)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)
Jonny Wright
  • 1,119
  • 4
  • 20
  • 38
  • 6
    "I know the path and filename in dest are ok as this is the var used to save the file" -- that does not necessarily mean that it is a valid `Uri` value that can be parsed. Use `File` objects, not strings, to represent file paths. Then, you can use `Uri.fromFile()` and be better assured of getting a working `Uri` value. You may wish to examine what the `Uri.parse()` result is and see if it looks reasonable (e.g., has a `file` scheme). Also, hold onto the `FileOutputStream` and, if iText lets you, call `getFD().sync()` before you `close()` it. – CommonsWare Jun 25 '15 at 23:37
  • Did you check if the Library is actually creating the file to the given `dest` ? Try to read the file and see if there is something wrong. – osayilgan Jun 25 '15 at 23:39
  • @osayilgan "I know the path and filename in dest are ok as this is the var used to save the file (which I can view fine on both the device and on a PC)" – Jonny Wright Jun 25 '15 at 23:40
  • Then It's clearly the Uri issue. Give it try to CommonsWare's Suggestion. And Log some more data, e.g what do you get with the `Uri.parse(dest)` – osayilgan Jun 25 '15 at 23:44
  • Thanks both - the `Uri.parse()` didn't have a alid `File` scheme. Working now – Jonny Wright Jun 25 '15 at 23:51
  • Have the same issue. I actually believe this is a bug in Google's new Gmail app. I can send data to any other app (using Uri.fromFile and Uri.parse) I have on my phone without a problem, but Gmail fails. There is actually a bug report on Google's forums where a user complains that Google's own Contacts-app is not able to share contacts using Gmail. – SiCN Sep 20 '15 at 15:42

2 Answers2

32

I was facing a similar issue. CommonsWare's comment above resolved it.!

Create a File object and generate a Uri using Uri.fromFile() method.

File file = new File(filePath);
Uri uri = Uri.fromFile(file);
Sahil Gera
  • 478
  • 4
  • 10
  • I have exactly the same thing in my code, yet it doesn't solve the issue. – Marek Oct 23 '15 at 10:26
  • OK I solved it. Your solution will work if file is in external directory. If it is in private directory where only app has access, Gmail will throw can't attach empty file. – Marek Oct 23 '15 at 10:48
  • Uri.parse(imagePath) was not working, but above solution is working fine. Thank you so much. – Smeet Jun 29 '17 at 11:20
2

I ran into the same problem on Nexus 5 with Android 6 (the same code worked on my Nexus 6 with Android 6), found explanation and working solution here: https://stackoverflow.com/a/32982050/534898

Community
  • 1
  • 1
Sergey Galin
  • 426
  • 6
  • 8