【问题标题】:Android PrintManager good preview, fails to print/make pdfAndroid PrintManager 良好的预览,无法打印/制作 pdf
【发布时间】:2016-02-26 21:56:47
【问题描述】:

我的应用正在使用以下代码创建 PDF。执行时,它会很好地调出 android 打印管理器(您可以在其中选择云打印、保存为 PDF 或选择打印机)。在此窗口中,可以正确预览页面。但是,当单击按钮保存时,创建的文件不是有效的 PDF (0 kb)。没有错误消息。

抱歉,代码太长了。我已经删掉了一些,但不确定什么是相关的。我猜问题出在适配器类的onLayoutonWrite 中。

public class PDFMaker {

@TargetApi(19)
public void printDocument(Context context) {
    lesson = WelcomeActivity.selectedLesson;
    Typeface textType = textPaint.getTypeface();

    PrintManager printManager = (PrintManager) context.getSystemService(Context.PRINT_SERVICE);

    String jobName = context.getString(R.string.app_name) +
            " Document";

    printManager.print(jobName, new MyPrintDocumentAdapter(context),
            null);
}

@TargetApi(19)
public class MyPrintDocumentAdapter extends PrintDocumentAdapter {
    Context context;
    private int pageHeight;
    private int pageWidth;
    public PdfDocument myPdfDocument;
    int startIndex = 0;
    Paint boxPaint = new Paint();
    boolean hasExtraProcess = false;
    StaticLayout extraProcessLayout;
    int extraProcessHeight = 0;

    public MyPrintDocumentAdapter(Context context) {
        this.context = context;
        boxPaint.setStyle(Paint.Style.STROKE);
        boxPaint.setStrokeWidth(2);
    }

    @Override
    public void onLayout(PrintAttributes oldAttributes,
                         PrintAttributes newAttributes,
                         CancellationSignal cancellationSignal,
                         LayoutResultCallback callback,
                         Bundle metadata) {
        myPdfDocument = new PrintedPdfDocument(context, newAttributes);

        pageHeight =
                792;
        pageWidth =
                612;

        if (cancellationSignal.isCanceled()) {
            callback.onLayoutCancelled();
            return;
        }
        PrintDocumentInfo.Builder builder = new PrintDocumentInfo
                .Builder(lesson.getField("title") + ".pdf")
                .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT);

        PrintDocumentInfo info = builder.build();
        callback.onLayoutFinished(info, true);
    }

    @Override
    public void onWrite(final PageRange[] pageRanges,
                        final ParcelFileDescriptor destination,
                        final CancellationSignal cancellationSignal,
                        final WriteResultCallback callback) {

        int pageNumber = 1;
        while (startIndex < boxes.length) {
            PageInfo newPage = new PageInfo.Builder(pageWidth,
                    pageHeight, pageNumber).create();

            PdfDocument.Page page =
                    myPdfDocument.startPage(newPage);

            if (cancellationSignal.isCanceled()) {
                callback.onWriteCancelled();
                myPdfDocument.close();
                myPdfDocument = null;
                return;
            }
            drawPage(page, pageNumber);
            myPdfDocument.finishPage(page);
            pageNumber++;
        }

        try {
            myPdfDocument.writeTo(new FileOutputStream(
                    destination.getFileDescriptor()));
        } catch (IOException e) {
            callback.onWriteFailed(e.toString());
            return;
        } finally {
            myPdfDocument.close();
            myPdfDocument = null;
        }

        callback.onWriteFinished(pageRanges);
    }

    private void drawPage(PdfDocument.Page page,
                          int pagenumber) {
        Canvas canvas = page.getCanvas();
        TextPaint headerPaint = new TextPaint();
        headerPaint.setTextSize(14);
        StaticLayout pageNumLayout = new StaticLayout(String.valueOf(pagenumber), headerPaint, printWidth/2, Layout.Alignment.ALIGN_OPPOSITE, 1, 0, false);
        canvas.translate(26, 18);
        if (pagenumber == 1) {
            canvas.translate(printWidth/2, 0);
            pageNumLayout.draw(canvas);
        } else {
            StaticLayout header = new StaticLayout(lesson.getField("title") + " Lesson by " + lesson.getField("authorName"), headerPaint, printWidth/2, Layout.Alignment.ALIGN_NORMAL, 1, 0, false);
            header.draw(canvas);
            canvas.translate(printWidth/2, 0);
            pageNumLayout.draw(canvas);
        }
        canvas.translate(-(printWidth / 2), pageNumLayout.getHeight() + 8);

        int pageFillHeight = 8;
        if (hasExtraProcess) {
            drawExtraProcessBox(canvas);
            if(hasExtraProcess) {
                return;
            }
            pageFillHeight += extraProcessHeight + 8;
            startIndex = 6;
        }
        for (int i = 0; i < boxes.length; i++) {
            if (i >= startIndex) {
                int viewHeight = boxes[i];
                if ((viewHeight + pageFillHeight + 8) < printHeight) {
                    switch (i) {
                        case 0:
                            drawTopBox(canvas);
                            break;
                        case 1:
                            drawObjectivesBox(canvas);
                            break;
                        case 2:
                            drawStandardsBox(canvas);
                            break;
                        case 3:
                            drawRepBox(canvas);
                            break;
                        case 4:
                            drawMediaBox(canvas);
                            break;
                        case 5:
                            drawProcessBox(canvas);
                            break;
                        case 6:
                            drawAssessmentBox(canvas);
                            break;
                        case 7:
                            drawCommentBox(canvas);
                            break;
                        default:
                            break;
                    }
                    pageFillHeight += viewHeight + 8;
                    if (i == boxes.length - 1) {
                        startIndex = i + 1;
                        return;
                    }
                } else {
                    if (i == 5) {
                        breakProcessBox(canvas, printHeight - pageFillHeight);
                    }
                    startIndex = i;
                    return;
                }
            }
        }
    }
    private void drawTopBox(Canvas canvas) {
        titleLayout.draw(canvas);
        canvas.translate(0, titleLayout.getHeight() + 8);
        authorLayout.draw(canvas);
        canvas.translate(0, authorLayout.getHeight() + 8);
        gradeLayout.draw(canvas);
        canvas.translate(printWidth / 2, 0);
        dateLayout.draw(canvas);
        canvas.translate(-(printWidth / 2), gradeLayout.getHeight() + 8);
    }

    private void drawObjectivesBox(Canvas canvas) {
        //Objectives
        int totalHeight = 8;
        canvas.translate(0, 8);
        primaryObjectiveLabel.draw(canvas);
        canvas.translate(100, 0);
        element1Layout.draw(canvas);
        canvas.translate(150, 0);
        objective1Layout.draw(canvas);
        if (primaryObjectiveLabel.getHeight() > objective1Layout.getHeight()) {
            canvas.translate(-250, primaryObjectiveLabel.getHeight() + 8);
            totalHeight += primaryObjectiveLabel.getHeight() + 8;
        } else {
            canvas.translate(-250, objective1Layout.getHeight() + 8);
            totalHeight += objective1Layout.getHeight() + 8;
        }
        secondaryObjectiveLabel.draw(canvas);
        canvas.translate(100, 0);
        element2Layout.draw(canvas);
        canvas.translate(150, 0);
        objective2Layout.draw(canvas);
        if (objective2Layout.getHeight() > element2Layout.getHeight()) {
            canvas.translate(-150, objective2Layout.getHeight() + 8);
            totalHeight += objective2Layout.getHeight() + 8;
        } else {
            canvas.translate(-150, element2Layout.getHeight() + 8);
            totalHeight += element2Layout.getHeight() + 8;
        }
        element3Layout.draw(canvas);
        canvas.translate(150, 0);
        objective3Layout.draw(canvas);
        if (objective3Layout.getHeight() > element3Layout.getHeight()) {
            canvas.translate(-250, objective3Layout.getHeight() + 8);
            totalHeight += objective3Layout.getHeight() + 8;
        } else {
            canvas.translate(-250, element3Layout.getHeight() + 8);
            totalHeight += element3Layout.getHeight() + 8;
        }
        canvas.translate(-8, -totalHeight);
        canvas.drawRect(0, 0, printWidth + 16, totalHeight, boxPaint);
        canvas.translate(8, totalHeight + 8);
    }

    private void drawStandardsBox(Canvas canvas) {
        canvas.translate(0, 8);
        int totalHeight = 8;
        primaryCoreLabel.draw(canvas);
        canvas.translate(100, 0);
        coreProc1Layout.draw(canvas);
        canvas.translate(150, 0);
        coreStand1Layout.draw(canvas);
        if(primaryCoreLabel.getHeight() > coreStand1Layout.getHeight()) {
            canvas.translate(-250, primaryCoreLabel.getHeight() + 8);
            totalHeight += primaryCoreLabel.getHeight() + 8;
        } else {
            canvas.translate(-250, coreStand1Layout.getHeight() + 8);
            totalHeight += coreStand1Layout.getHeight() + 8;
        }
        secondaryCoreLabel.draw(canvas);
        canvas.translate(100, 0);
        coreProc2Layout.draw(canvas);
        canvas.translate(150, 0);
        coreStand2Layout.draw(canvas);
        if (coreProc2Layout.getHeight() > coreStand2Layout.getHeight()) {
            canvas.translate(-150, coreProc2Layout.getHeight() + 8);
            totalHeight += coreProc2Layout.getHeight() + 8;
        } else {
            canvas.translate(-150, coreStand2Layout.getHeight() + 8);
            totalHeight += coreStand2Layout.getHeight() + 8;
        }
        coreProc3Layout.draw(canvas);
        canvas.translate(150, 0);
        coreStand3Layout.draw(canvas);
        if (coreProc3Layout.getHeight() > coreStand3Layout.getHeight()) {
            canvas.translate(-250, coreProc3Layout.getHeight() + 8);
            totalHeight += coreProc3Layout.getHeight() + 8;
        } else {
            canvas.translate(-250, coreStand3Layout.getHeight() + 8);
            totalHeight += coreStand3Layout.getHeight() + 8;
        }
        canvas.translate(-8, -totalHeight);
        canvas.drawRect(0, 0, printWidth + 16, totalHeight, boxPaint);
        canvas.translate(8, totalHeight + 8);
    }

    private void drawRepBox(Canvas canvas) {
        canvas.translate(0, 8);
        int totalHeight = 8;
        repLabel.draw(canvas);
        canvas.translate(100, 0);
        rep1Layout.draw(canvas);
        if (repLabel.getHeight() > rep1Layout.getHeight()) {
            canvas.translate(0, repLabel.getHeight() + 8);
            totalHeight += repLabel.getHeight() + 8;
        } else {
            canvas.translate(0, rep1Layout.getHeight() + 8);
            totalHeight += rep1Layout.getHeight() + 8;
        }
        if (!lesson.getField("repertoire2").equals("")) {
            rep2Layout.draw(canvas);
            canvas.translate(0, rep2Layout.getHeight() + 8);
            totalHeight += rep2Layout.getHeight() + 8;
        }
        if (!lesson.getField("repertoire3").equals("")) {
            rep3Layout.draw(canvas);
            canvas.translate(-100, rep3Layout.getHeight() + 8);
            totalHeight += rep3Layout.getHeight() + 8;
        } else {
            canvas.translate(-100, 0);
        }
        if (scoreBMP != null) {

            canvas.drawBitmap(scoreBMP, 0, 0, new Paint());
            canvas.translate(0, scoreBMP.getHeight() + 8);
            totalHeight += scoreBMP.getHeight() + 8;
        }
        canvas.translate(-8, -totalHeight);
        canvas.drawRect(0, 0, printWidth + 16, totalHeight, boxPaint);
        canvas.translate(8, totalHeight + 8);
    }

    private void drawMediaBox(Canvas canvas) {
        canvas.translate(0, 8);
        int totalHeight = 8;
        mediaLabel.draw(canvas);
        canvas.translate(100, 0);
        m1Layout.draw(canvas);
        if (mediaLabel.getHeight() > m1Layout.getHeight()) {
            canvas.translate(0, mediaLabel.getHeight() + 8);
            totalHeight += mediaLabel.getHeight() + 8;
        } else {
            canvas.translate(0, m1Layout.getHeight() + 8);
            totalHeight += m1Layout.getHeight() + 8;
        }
        if (!lesson.getField("media2").equals("")) {
            m2Layout.draw(canvas);
            canvas.translate(0, m2Layout.getHeight() + 8);
            totalHeight += m2Layout.getHeight() + 8;
        }
        if (!lesson.getField("media3").equals("")) {
            m3Layout.draw(canvas);
            canvas.translate(0, m3Layout.getHeight() + 8);
            totalHeight += m3Layout.getHeight() + 8;
        }
        if (!lesson.getField("media4").equals("")) {
            m4Layout.draw(canvas);
            canvas.translate(0, m4Layout.getHeight() + 8);
            totalHeight += m4Layout.getHeight() + 8;
        }
        if (!lesson.getField("media5").equals("")) {
            m5Layout.draw(canvas);
            canvas.translate(0, m5Layout.getHeight() + 8);
            totalHeight += m5Layout.getHeight() + 8;
        }
        if (!lesson.getField("media6").equals("")) {
            m6Layout.draw(canvas);
            canvas.translate(-100, m6Layout.getHeight() + 8);
            totalHeight += m6Layout.getHeight() + 8;
        } else {
            canvas.translate(-100, 0);
        }
        canvas.translate(-8, -totalHeight);
        canvas.drawRect(0, 0, printWidth + 16, totalHeight, boxPaint);
        canvas.translate(8, totalHeight + 8);
    }

    private void drawProcessBox(Canvas canvas) {
        canvas.translate(0, 8);
        int totalHeight = 8;
        processLabel.draw(canvas);
        canvas.translate(100, 0);
        processLayout.draw(canvas);
        if (processLabel.getHeight() > processLayout.getHeight()) {
            canvas.translate(-100, processLabel.getHeight() + 8);
            totalHeight += processLabel.getHeight() + 8;
        } else {
            canvas.translate(-100, processLayout.getHeight() + 8);
            totalHeight += processLayout.getHeight() + 8;
        }
        canvas.translate(-8, -totalHeight);
        canvas.drawRect(0, 0, printWidth + 16, totalHeight, boxPaint);
        canvas.translate(8, totalHeight + 8);
    }

    private void breakProcessBox(Canvas canvas, int spaceRemaining) {
        double bestHeight = spaceRemaining - 24;
        double processHeight = processLayout.getHeight();
        double percentHeight = bestHeight/processHeight;
        Spanned processString = makeItSpan(lesson.getField("process"));
        String htmlProcessString = HTMLConverter.saveToHtml(processString);
        Pair<StaticLayout, StaticLayout> splitLayouts = splitProcessString(bestHeight, processHeight, htmlProcessString);
        if (splitLayouts.first != null) {
            processLayout = splitLayouts.first;
            drawProcessBox(canvas);
        }
        if (splitLayouts.second != null) {
            extraProcessLayout = splitLayouts.second;
            hasExtraProcess = true;
        } else {
            hasExtraProcess = false;
        }
    }

    private void drawExtraProcessBox(Canvas canvas) {
        if (extraProcessLayout != null) {
            StaticLayout thirdPageLayout = null;
            if (extraProcessLayout.getHeight() > printHeight - 24) {
                Spanned extraText = (Spanned) extraProcessLayout.getText();
                Pair<StaticLayout, StaticLayout> splitLayouts = splitProcessString(printHeight - 24, extraProcessLayout.getHeight(), HTMLConverter.saveToHtml(extraText));
                extraProcessLayout = splitLayouts.first;
                thirdPageLayout = splitLayouts.second;
            }
            canvas.translate(0, 8);
            int totalHeight = 8;
            processLabel.draw(canvas);
            canvas.translate(100, 0);
            extraProcessLayout.draw(canvas);
            if (processLabel.getHeight() > extraProcessLayout.getHeight()) {
                canvas.translate(-100, processLabel.getHeight() + 8);
                totalHeight += processLabel.getHeight() + 8;
            } else {
                canvas.translate(-100, extraProcessLayout.getHeight() + 8);
                totalHeight += extraProcessLayout.getHeight() + 8;
            }
            canvas.translate(-8, -totalHeight);
            canvas.drawRect(0, 0, printWidth + 16, totalHeight, boxPaint);
            canvas.translate(8, totalHeight + 8);
            if (thirdPageLayout != null) {
                extraProcessLayout = thirdPageLayout;
                hasExtraProcess = true;
            } else {
                hasExtraProcess = false;
            }
        }
    }

    private void drawAssessmentBox(Canvas canvas) {
        canvas.translate(0, 8);
        int totalHeight = 8;
        assessmentLabel.draw(canvas);
        canvas.translate(100, 0);
        assessmentLayout.draw(canvas);
        if (assessmentLabel.getHeight() > assessmentLayout.getHeight()) {
            canvas.translate(-100, assessmentLabel.getHeight() + 8);
            totalHeight += assessmentLabel.getHeight() + 8;
        } else {
            canvas.translate(-100, assessmentLayout.getHeight() + 8);
            totalHeight += assessmentLayout.getHeight() + 8;
        }
        canvas.translate(-8, -totalHeight);
        canvas.drawRect(0, 0, printWidth + 16, totalHeight, boxPaint);
        canvas.translate(8, totalHeight + 8);
    }

    private void drawCommentBox(Canvas canvas) {
        canvas.translate(0, 8);
        int totalHeight = 8;
        commentLabel.draw(canvas);
        canvas.translate(100, 0);
        commentLayout.draw(canvas);
        if (commentLabel.getHeight() > commentLayout.getHeight()) {
            canvas.translate(-100, commentLabel.getHeight() + 8);
            totalHeight += commentLabel.getHeight() + 8;
        } else {
            canvas.translate(-100, commentLayout.getHeight() + 8);
            totalHeight += commentLayout.getHeight() + 8;
        }
        canvas.translate(-8, -totalHeight);
        canvas.drawRect(0, 0, printWidth + 16, totalHeight, boxPaint);
        canvas.translate(8, totalHeight + 8);
    }

    private Pair<StaticLayout, StaticLayout> splitProcessString(double remainingSpace, double fullHeight, String htmlString) {
        StaticLayout firstLayout;
        StaticLayout secondLayout;
        double percentHeight = remainingSpace/fullHeight;
        int characterLength = htmlString.length();
        Double split = characterLength * percentHeight;
        int findBreak = htmlString.lastIndexOf("<br>", split.intValue());
        int findParagraphEnd = htmlString.lastIndexOf("</p>", split.intValue());
        int findGoodSpot = -1;
        int offSet = 3;
        if (findBreak > findParagraphEnd) {
            findGoodSpot = findBreak;
        } else {
            findGoodSpot = findParagraphEnd;
            offSet = 4;
        }
        if (findGoodSpot > characterLength) {
            firstLayout = new StaticLayout(HTMLConverter.makeItSpan(htmlString), textPaint, printWidth - 124, Layout.Alignment.ALIGN_NORMAL, 1, 0, false);
            secondLayout = null;
            return Pair.create(firstLayout, secondLayout);
        } else if (findGoodSpot < 0) {
            secondLayout = new StaticLayout(HTMLConverter.makeItSpan(htmlString), textPaint, printWidth - 124, Layout.Alignment.ALIGN_NORMAL, 1, 0, false);
            firstLayout = null;
            return Pair.create(firstLayout, secondLayout);
        } else {
            String firstHalf = htmlString.substring(0, findGoodSpot);
            String secondHalf = htmlString.substring(findGoodSpot + offSet);
            Spanned firstHalfSpanned = HTMLConverter.makeItSpan(firstHalf);
            Spanned secondHalfSpanned = HTMLConverter.makeItSpan(secondHalf);
            firstLayout = new StaticLayout(firstHalfSpanned, textPaint, printWidth - 124, Layout.Alignment.ALIGN_NORMAL, 1, 0, false);
            secondLayout = new StaticLayout(secondHalfSpanned, textPaint, printWidth - 124, Layout.Alignment.ALIGN_NORMAL, 1, 0, false);
            return Pair.create(firstLayout, secondLayout);
        }
    }
}
}

编辑:有时我在尝试后在设备上收到以下消息:“不幸的是,Print Spooler 已停止”。

【问题讨论】:

  • 您是否从日志中检查了打印后台处理程序崩溃消息?您是否检查了您在目的地创建的 pdf 文件,它看起来是否有效?

标签: android pdf printing


【解决方案1】:

问题出在我的while 循环和startIndex 计数器上。 onWrite 被调用两次 - 首先是创建预览,然后是再次保存/打印。在第二次运行时,startIndex 已经超出范围,因此没有打印任何内容。简单的解决方案:在onWrite 中重置startIndex

【讨论】:

    【解决方案2】:

    在使用 Android Chrome 设置-共享-打印多年后,它变得无法使用,因为在每次尝试中它都卡在打印预览模式下不断假脱机。它不会打印 PDF,我在互联网上找不到解决方案。

    使用 Play 商店,我可以自己解决这个问题,方法是禁用 Android 辅助功能套件,然后将其重置为出厂版本,然后返回 Play 商店并进行更新。值得记住,如果你需要它,我希望它也对你有用!

    【讨论】:

      猜你喜欢
      • 2013-11-12
      • 2010-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-04
      • 1970-01-01
      • 2011-12-10
      • 1970-01-01
      相关资源
      最近更新 更多