0
我的应用程序使用以下代码创建PDF。执行时,它会启动android打印管理器(您可以选择云打印,保存为PDF或选择打印机)。在这个窗口中,有一个正确的页面预览。但是,单击保存按钮时,创建的文件不是有效的PDF(0 kb)。没有错误消息。Android PrintManager很好的预览功能,无法打印/制作pdf
对不起,长码。我已经删除了一些,但不确定什么是相关的。我猜这个问题在适配器类的onLayout
或onWrite
中。
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文件吗?它看起来有效吗? – Nonos