AndroidStudio attaching PDF to email issue

916 Views Asked by At

Can anyone help explain why this code works in the Geneymotion emulator but not in any actual android device? The code perfectly works in an emulator, I've had no issues with it, I'm totally confused as to why it won't work in actual device.

Here's the method, which is called when "create PDF" button is clicked:

    try {

        String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/invoices";

        File dir = new File(path);
        if(!dir.exists())
            dir.mkdirs();

        Log.d("PDFCreator", "PDF Path: " + path);

        File delete = new File(dir, "invoice.pdf");
        if (delete.exists())
            delete.delete();

        File file = new File(dir, "invoice.pdf");
        FileOutputStream fOut = new FileOutputStream(file);

        PdfWriter.getInstance(doc, fOut);

        //open the document
        doc.open();
        Log.d("test", "PDF Doccument Opened for input");

In the emulator: - when I click the "create PDF" button, email intent is called, and I can choose between email clients to use and send the PDF through it.

In an actual android device: When I click the "create PDF" in an actual device, absolutely nothing happens.

I assume the problem might revolve around the directory where I'm storing the PDF, but I have not been able to resolve it.

If someone could help me, it would be greatly appreciated. Thanks in advance.

NOTE: I'm using DroidText library to produce the PDF.

Log from test on actual device says:

11-05 21:09:14.839  10375-10375/motawaze.com.invoicepdf D/dalvikvm﹕ GC_EXTERNAL_ALLOC freed 93K, 47% free 2913K/5447K, external 0K/0K, paused 30ms
11-05 21:09:25.989  10375-10375/motawaze.com.invoicepdf D/CLIPBOARD﹕ Hide Clipboard dialog at Starting input: finished by someone else... !
11-05 21:09:29.849  10375-10378/motawaze.com.invoicepdf D/dalvikvm﹕ GC_CONCURRENT freed 153K, 47% free 3043K/5639K, external 171K/1281K, paused 7ms+2ms
11-05 21:09:39.899  10375-10378/motawaze.com.invoicepdf D/dalvikvm﹕ GC_CONCURRENT freed 351K, 48% free 3105K/5895K, external 171K/1281K, paused 7ms+3ms
11-05 21:09:53.639  10375-10375/motawaze.com.invoicepdf D/test﹕ set the fields for PDF input
11-05 21:09:53.649  10375-10375/motawaze.com.invoicepdf D/test﹕ set the document
11-05 21:09:53.669  10375-10375/motawaze.com.invoicepdf D/test﹕ set the calender
11-05 21:09:53.669  10375-10375/motawaze.com.invoicepdf D/PDFCreator﹕ PDF Path: /mnt/sdcard/Download/invoices
11-05 21:09:53.669  10375-10375/motawaze.com.invoicepdf E/PDFCreator﹕ ioException:java.io.FileNotFoundException: /mnt/sdcard/Download/invoices/Invoice.pdf (No such file or directory)
11-05 21:10:31.420  10375-10378/motawaze.com.invoicepdf D/dalvikvm﹕ GC_CONCURRENT freed 358K, 48% free 3152K/5959K, external 171K/1281K, paused 7ms+2ms
2

There are 2 best solutions below

5
On BEST ANSWER

As mentioned in the chat too. Looks like your PDF is not being created, hence you get the FileNotFoundException. Look into your PDF creation code. That's the problem.

Change these lines:

 if(!dir.exists())
     dir.mkdirs();

to:

 boolean created = false;
 if(!dir.exists())
     created = dir.mkdirs();

 if(created)
  Log.d("test", "Path created");

This will check whether the directory is created or not.

0
On

This code may help you.

I use DroidText.0.2.jar for Pdf Creation.

public void createPDF()
    {
        Document doc = new Document();

        try {
            path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/droidText";
//            File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);

            File dir = new File(path);
            if(!dir.exists())
                dir.mkdirs();

            Log.d("PDFCreator", "PDF Path: " + path);


            file = new File(path, "HomeInventory.pdf");
            FileOutputStream fOut = new FileOutputStream(file);

            PdfWriter.getInstance(doc, fOut);

            //open the document
            doc.open();


            Paragraph p1 = new Paragraph("Hi! I am generating my first PDF using DroidText");
            Font paraFont= new Font(Font.COURIER);
            p1.setAlignment(Paragraph.ALIGN_CENTER);
            p1.setFont(paraFont);

            //add paragraph to document
            doc.add(p1);

            Paragraph p2 = new Paragraph("This is an example of a paragraph");
            Font paraFont2= new Font(Font.COURIER,14.0f, Color.GREEN);
            p2.setAlignment(Paragraph.ALIGN_CENTER);
            p2.setFont(paraFont2);

            doc.add(p2);

            ByteArrayOutputStream stream = new ByteArrayOutputStream();
//            Bitmap bitmap = BitmapFactory.decodeResource(getBaseContext().getResources(), R.drawable.android);
            Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.action_search);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100 , stream);
            Image myImg = Image.getInstance(stream.toByteArray());
            myImg.setAlignment(Image.MIDDLE);
            //add image to document
            doc.add(myImg);

            //set footer
            Phrase footerText = new Phrase("This is an example of a footer");
            HeaderFooter pdfFooter = new HeaderFooter(footerText, false);
            doc.setFooter(pdfFooter);



        } catch (DocumentException de) {
            Log.e("PDFCreator", "DocumentException:" + de);
        } catch (IOException e) {
            Log.e("PDFCreator", "ioException:" + e);
        }
        finally
        {
            doc.close();
        }
    }

Attach this created Pdf File to Email like this way..

String[] mailto = {"[email protected]"};
                Uri uri = Uri.fromFile(file);

                Intent emailIntent = new Intent(Intent.ACTION_SEND,Uri.parse("mailto:"));
                emailIntent.setType("text/plain");
                emailIntent.putExtra(Intent.EXTRA_EMAIL, mailto);
                emailIntent.putExtra(Intent.EXTRA_SUBJECT, "My Subject");
                emailIntent.putExtra(Intent.EXTRA_TEXT, "My Body");

                emailIntent.putExtra(Intent.EXTRA_STREAM, uri);

                emailIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // this will make such that when user returns to your app, your app is displayed, instead of the email app.
                getActivity().startActivity(emailIntent);