2016-02-26 425 views
0

我的应用程序使用以下代码创建PDF。执行时,它会启动android打印管理器(您可以选择云打印,保存为PDF或选择打印机)。在这个窗口中,有一个正确的页面预览。但是,单击保存按钮时,创建的文件不是有效的PDF(0 kb)。没有错误消息。Android PrintManager很好的预览功能,无法打印/制作pdf

对不起,长码。我已经删除了一些,但不确定什么是相关的。我猜这个问题在适配器类的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); 
     } 
    } 
} 
} 

编辑:有时候我试图在设备上得到以下消息:“不幸的是,后台打印程序已停止”。

+0

您是否检查日志中的Print spooler崩溃消息?你检查了你在目的地创建的pdf文件吗?它看起来有效吗? – Nonos

回答

0

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