2

I'm trying to attach a PDF, that is created from a Scroll view, to an email. But the email is sent with nothing attached. There are no error messages displayed.

public void emailPDF(View view){

    PdfDocument document = getPDF();

    ByteArrayOutputStream os = new ByteArrayOutputStream();
    try{
        document.writeTo(os);
        document.close();
        os.close();
    }catch (IOException e){
        throw new RuntimeException("Error generating file", e);
    }


    Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
    emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, "ammar5001@gmail.com");
    emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "report");
    emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, " ");
    emailIntent.setType("application/pdf"); // accept any image
    //attach the file to the intent
    emailIntent.putExtra(Intent.EXTRA_STREAM, os.toByteArray() );

    startActivity(Intent.createChooser(emailIntent, "Send your email in:"));
}

public PdfDocument getPDF(){

    PdfDocument document = new PdfDocument();
    PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(300, 300, 1).create();
    PdfDocument.Page page = document.startPage(pageInfo);
    View content = findViewById(R.id.scrollView);
    content.draw(page.getCanvas());

    document.finishPage(page);

    return document;
}
Onik
  • 19,396
  • 14
  • 68
  • 91
Ammar Samater
  • 529
  • 2
  • 7
  • 24

1 Answers1

1

EXTRA_STREAM does not take a byte[]. It takes a Uri, pointing to the data to be streamed. That could be a File on external storage, or a content:// Uri from a FileProvider for files on internal storage, or a content:// Uri from a ContentProvider that attempts to serve your byte[] (though I worry about heap space), etc.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Ok I understood that I can't use byte array on Extra_STREAM, and about the Heap space issue. but you lost me on the rest, can you clarify please? – Ammar Samater Sep 02 '15 at 18:18
  • 1
    @AmmarSamater: Most likely, you are using a Web browser to view this page. If you look in the address bar, you will see a URL. This is an address to some place to stream some data -- in this case, it points to a Web server that can stream this page. A `Uri` works similarly. If you look at any working `EXTRA_STREAM` example, you will see that it uses a `Uri`, and that `Uri` usually will point to a file or a `ContentProvider`. Note that a file would need to be on external storage to be directly readable by the app that you are sending it to. – CommonsWare Sep 02 '15 at 18:33
  • @AmmarSamater: So, for example, you could write the PDF to a file on external storage, then use `Uri.fromFile()` to convert the `File` object into a `Uri` that you can use with `EXTRA_STREAM`. – CommonsWare Sep 02 '15 at 18:34
  • Ah ok, so I will just write the PDF to a external storage, and then read it from there. if that is the only way. – Ammar Samater Sep 02 '15 at 18:49
  • @AmmarSamater: It is not the only way. As I mentioned in my answer, you can write the file to internal storage and [use `FileProvider`](http://developer.android.com/reference/android/support/v4/content/FileProvider.html) to serve it, or you can create your own streaming `ContentProvider` to serve it by some other means. – CommonsWare Sep 02 '15 at 18:54
  • Ok, according to https://androidcookbook.com/Recipe.seam?recipeId=4576 emailIntent.putExtra(getClass().getPackage().getName() + "." + "SendPDF", os.toByteArray());
    could be used, but I still got the same problem. I'll try to figure out how to do it as you suggested.
    – Ammar Samater Sep 02 '15 at 19:03