Android PdfDocument corrupted when saving to external storage

I am trying to create a simple PDF document using Androids native PdfDocument class (from api 19). I want an XML file, for example, called pdf_doc.xml, and then inflate it when creating a PDF. Inside pdf_doc.xml, I will have a bunch of views that can be extracted in code and then drawn separately on the PdfDocuments pages. The problem is that this creates a damaged PDF file.

On the other hand, if I just create a simple TextView, in my main_activity.xml (the xml of the activity I use when creating the PDF), and use TextView instead, it works fine.

Why does it matter whether the TextView is dependent on a bloated layout or an activity layout? Am I trying to do it wrong?

FYI: it also does not work when programmatically creating a TextView.

Below is my source code. These two functions are called immediately after eachother. The first creates a PDF, the other saves it. The problem is the view called content, which im gets from the bloated layout. If instead I placed this TextView in an Activity XML file and then pulled it out of an action, for example, this act.findViewById(R.id.pdf_text); then he will work as intended.

code:

  public static PdfDocument createPdf(Activity act){ PrintAttributes printAttrs = new PrintAttributes.Builder(). setColorMode(PrintAttributes.COLOR_MODE_COLOR). setMediaSize(PrintAttributes.MediaSize.ISO_A4). setMinMargins(PrintAttributes.Margins.NO_MARGINS). build(); ViewGroup mainLayout = (ViewGroup) View.inflate(act, R.layout.pdf_doc, null); int pageHeight = printAttrs.getMediaSize().getHeightMils() / 1000 * 72; int pageWidth = printAttrs.getMediaSize().getWidthMils() / 1000 * 72; PdfDocument document = new PrintedPdfDocument(act, printAttrs); PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(pageWidth, pageHeight, 1).create(); PdfDocument.Page page = document.startPage(pageInfo); View content = mainLayout.findViewById(R.id.pdf_text); content.draw(page.getCanvas()); document.finishPage(page); return document; } public static void saveFile(PdfDocument doc){ String root = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString(); File myDir = new File(root + "/pdf_test"); myDir.mkdirs(); File file = new File(myDir, "test.pdf"); if (file.exists()) { file.delete(); } try { FileOutputStream out = new FileOutputStream(file); doc.writeTo(out); doc.close(); out.flush(); out.close(); } catch (Exception e) { e.printStackTrace(); } String path = file.getAbsolutePath(); Log.d("pdftest", "path: " + path); } 
+6
source share
1 answer

Two suggestions:

  • Since your mainLayout will have zero height and zero width (you did not inflate it in the parent), try manually laying it out by calling measure() and layout() on it, this is the order. You will need to specify the size in pixels, the size of which must have a format.

  • Call out.getFd().sync() after out.flush() and before out.close() . I doubt this causes your specific problem here, but it is a good idea and is unlikely to hurt.

+1
source

All Articles