Java Android PdfDocument在保存到外部存储时损坏

Java Android PdfDocument在保存到外部存储时损坏,java,android,xml,pdf,android-4.4-kitkat,Java,Android,Xml,Pdf,Android 4.4 Kitkat,我正在尝试使用Androids原生PdfDocument类(来自api 19)创建一个简单的PDF文档。我想要的是有一个XML布局文件,例如称为pdf_doc.XML,然后在创建pdf时将其膨胀。在pdf_doc.xml中,我将拥有一组视图,这些视图可以在代码中获取,然后分别绘制到PdfDocuments页面上。问题是,这会创建一个损坏的PDF文件 另一方面,如果我只是在main_activity.xml(创建PDF时使用的活动的xml)中创建一个简单的文本视图,并使用该文本视图,它就可以正常工

我正在尝试使用Androids原生PdfDocument类(来自api 19)创建一个简单的PDF文档。我想要的是有一个XML布局文件,例如称为pdf_doc.XML,然后在创建pdf时将其膨胀。在pdf_doc.xml中,我将拥有一组视图,这些视图可以在代码中获取,然后分别绘制到PdfDocuments页面上。问题是,这会创建一个损坏的PDF文件

另一方面,如果我只是在main_activity.xml(创建PDF时使用的活动的xml)中创建一个简单的文本视图,并使用该文本视图,它就可以正常工作

为什么文本视图来自膨胀的布局还是活动的布局会有区别?我是不是想用错误的方法

仅供参考:以编程方式创建TextView时也会失败

下面是我的源代码。这两个函数是紧接着调用的。第一个创建PDF,另一个保存它。问题在于我从膨胀的布局中得到的视图,称为内容。如果我将该文本视图放在活动的XML中,然后从活动中获取它,如下面的
act.findViewById(R.id.pdf_text)然后按预期工作

代码:

两项建议:

  • 由于您的
    mainLayout
    将具有零高度和零宽度(您尚未将其膨胀为父级),请尝试手动布局,方法是按此顺序调用
    measure()
    layout()
    。您需要指定一个以像素为单位的大小,以便调整布局的大小

  • out.flush()
    之后和
    out.close()之前调用
    out.getFd().sync()
    。我怀疑这是造成你的具体问题的原因,但这是个好主意,不太可能造成伤害


  • @也许我不够清楚,但我不想马上画出整个布局。我只是从布局中获取一个文本视图并尝试绘制它。我看不出这样做与从活动使用的布局中获取有什么区别……不,一点也不。正如我所说的,如果我从活动的XML中获取TextView,我可以将其绘制到PdfDocument pages画布上,但是我不能使用编程膨胀布局中的TextView来完成这项工作?感谢您提出的两个建设性建议。明天早上我会试试的!如果我想让布局尽可能多地填充空间,那么measure()的参数是什么?“最多是多少?”托马斯泰尔曼:我可受不了。我还没试过。我不确定是否有“尽可能多的空间”,因为没有家长。由于IIRC必须提供以像素为单位的纸张尺寸,因此可能需要使用相同数量的像素(或者更少)。
        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);
        }