|
@@ -0,0 +1,261 @@
|
|
|
|
+package com.bomostory.sceneeditmodule;
|
|
|
|
+
|
|
|
|
+import android.annotation.SuppressLint;
|
|
|
|
+import android.app.Activity;
|
|
|
|
+import android.content.Context;
|
|
|
|
+import android.graphics.Canvas;
|
|
|
|
+import android.graphics.pdf.PdfDocument;
|
|
|
|
+import android.os.AsyncTask;
|
|
|
|
+import android.os.Bundle;
|
|
|
|
+import android.os.CancellationSignal;
|
|
|
|
+import android.os.CancellationSignal.OnCancelListener;
|
|
|
|
+import android.os.ParcelFileDescriptor;
|
|
|
|
+import android.print.PageRange;
|
|
|
|
+import android.print.PrintAttributes;
|
|
|
|
+import android.print.PrintDocumentAdapter;
|
|
|
|
+import android.print.PrintDocumentInfo;
|
|
|
|
+import android.print.PrintManager;
|
|
|
|
+import android.print.pdf.PrintedPdfDocument;
|
|
|
|
+import android.util.SparseIntArray;
|
|
|
|
+import android.widget.Toast;
|
|
|
|
+
|
|
|
|
+import java.io.File;
|
|
|
|
+import java.io.FileInputStream;
|
|
|
|
+import java.io.FileOutputStream;
|
|
|
|
+import java.io.IOException;
|
|
|
|
+import java.io.InputStream;
|
|
|
|
+import java.io.OutputStream;
|
|
|
|
+import java.util.ArrayList;
|
|
|
|
+import java.util.List;
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * @项目名称:PDFReader_android_for_as
|
|
|
|
+ * @包名称:com.kdanmobile.pdf.tools
|
|
|
|
+ * @文件名称:PrintTools
|
|
|
|
+ * @创建时间:15/8/25 - 下午12:07 - 12
|
|
|
|
+ * @创建人:luozhipeng
|
|
|
|
+ * @修改记录:
|
|
|
|
+ * @修改人: --------------------------------------
|
|
|
|
+ * @Copyright (c)-2015kdanmobile
|
|
|
|
+ */
|
|
|
|
+@SuppressLint("NewApi")
|
|
|
|
+public class PrintTools {
|
|
|
|
+ private int tatalPages = 0;
|
|
|
|
+ private File file = null;
|
|
|
|
+ private int pagescount = 0;
|
|
|
|
+
|
|
|
|
+ private PrintTools() {
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* 该单例实现了延迟加载和线程安全 */
|
|
|
|
+ public static PrintTools getInstance() {
|
|
|
|
+ return SingTonHolder.instance;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public void doPrint(Activity context, File file,
|
|
|
|
+ int totalPages) {
|
|
|
|
+ this.tatalPages = totalPages;
|
|
|
|
+ this.file = file;
|
|
|
|
+
|
|
|
|
+ // Get a PrintManager instance
|
|
|
|
+ PrintManager printManager = (PrintManager) context
|
|
|
|
+ .getSystemService(Context.PRINT_SERVICE);
|
|
|
|
+
|
|
|
|
+ // Set job name, which will be displayed in the print queue
|
|
|
|
+ if (file == null)
|
|
|
|
+ return;
|
|
|
|
+ String jobName = file.getName();
|
|
|
|
+
|
|
|
|
+ // Start a print job, passing in a PrintDocumentAdapter implementation
|
|
|
|
+ // to handle the generation of a print document
|
|
|
|
+ try {
|
|
|
|
+ android.print.PrintJob job = printManager.print(jobName, new MyPrintDocumentAdapter(context),
|
|
|
|
+ new PrintAttributes.Builder().build());
|
|
|
|
+ if (job == null) {
|
|
|
|
+ Toast.makeText(context, "print failed!", Toast.LENGTH_SHORT).show();
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ } catch (Exception ignored) {
|
|
|
|
+ Toast.makeText(context, "Print is not Available!", Toast.LENGTH_SHORT).show();
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private int computePageCount(PrintAttributes printAttributes) {
|
|
|
|
+// int itemsPerPage = 4; // default item count for portrait mode
|
|
|
|
+//
|
|
|
|
+// PrintAttributes.MediaSize pageSize = printAttributes.getMediaSize();
|
|
|
|
+// if (!pageSize.isPortrait()) {
|
|
|
|
+// // Six items per page in landscape orientation
|
|
|
|
+// itemsPerPage = 6;
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// // Determine number of print items
|
|
|
|
+// int printItemCount = getPrintItemCount();
|
|
|
|
+//
|
|
|
|
+// return (int) Math.ceil(printItemCount / itemsPerPage);
|
|
|
|
+ return tatalPages;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private int getPrintItemCount() {
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+// private boolean containsPage(PageRange[] pageRanges, int page) {
|
|
|
|
+// final int pageRangeCount = pageRanges.length;
|
|
|
|
+// for (int i = 0; i < pageRangeCount; i++) {
|
|
|
|
+// if (pageRanges[i].getStart() <= page
|
|
|
|
+// && pageRanges[i].getEnd() >= page) {
|
|
|
|
+// return true;
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+// return false;
|
|
|
|
+// }
|
|
|
|
+
|
|
|
|
+ private void drawPage(PdfDocument.Page page) {
|
|
|
|
+ Canvas canvas = page.getCanvas();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* 类级的内部类,也就是静态的成员式内部类,该内部类的实例与外部类的实例 没有绑定的关系,而且只有被调用到时才会装载,从而实现了延迟加载 */
|
|
|
|
+ private static class SingTonHolder {
|
|
|
|
+ /* 静态初始化器,由JVM来保证线程安全 */
|
|
|
|
+ private static PrintTools instance = new PrintTools();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ class MyPrintDocumentAdapter extends PrintDocumentAdapter {
|
|
|
|
+ private final Object mLock = new Object();
|
|
|
|
+ Activity mactivity;
|
|
|
|
+ PrintedPdfDocument mPdfDocument;
|
|
|
|
+
|
|
|
|
+ public MyPrintDocumentAdapter(Activity mactivity) {
|
|
|
|
+ this.mactivity = mactivity;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void onLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes,
|
|
|
|
+ CancellationSignal cancellationSignal, LayoutResultCallback callback, Bundle extras) {
|
|
|
|
+ // Create a new PdfDocument with the requested page attributes
|
|
|
|
+ mPdfDocument = new PrintedPdfDocument(mactivity, newAttributes);
|
|
|
|
+
|
|
|
|
+ // Respond to cancellation request
|
|
|
|
+ if (cancellationSignal.isCanceled()) {
|
|
|
|
+ callback.onLayoutCancelled();
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Compute the expected number of printed pages
|
|
|
|
+ pagescount = computePageCount(newAttributes);
|
|
|
|
+
|
|
|
|
+ if (pagescount > 0) {
|
|
|
|
+ // Return print information to print framework
|
|
|
|
+ PrintDocumentInfo info = new PrintDocumentInfo
|
|
|
|
+ .Builder("print_output.pdf")
|
|
|
|
+ .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT)
|
|
|
|
+ .setPageCount(pagescount)
|
|
|
|
+ .build();
|
|
|
|
+
|
|
|
|
+ // Content layout reflow is complete
|
|
|
|
+ callback.onLayoutFinished(info, true);
|
|
|
|
+ } else {
|
|
|
|
+ // Otherwise report an error to the print framework
|
|
|
|
+ callback.onLayoutFailed("Page count calculation failed.");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void onWrite(PageRange[] pages,
|
|
|
|
+ final ParcelFileDescriptor destination,
|
|
|
|
+ CancellationSignal canclleationSignal,
|
|
|
|
+ final WriteResultCallback callback) {
|
|
|
|
+ final SparseIntArray writtenPagesArray = new SparseIntArray();
|
|
|
|
+ final int totalPages = pagescount;
|
|
|
|
+ final AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ protected void onPreExecute() {
|
|
|
|
+ synchronized (mLock) {
|
|
|
|
+ for (int i = 0; i < totalPages; i++) {
|
|
|
|
+ if (isCancelled()) {
|
|
|
|
+ mPdfDocument.close();
|
|
|
|
+ mPdfDocument = null;
|
|
|
|
+ callback.onWriteCancelled();
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+// if (containsPage(pages, i)) {
|
|
|
|
+// writtenPagesArray.append(writtenPagesArray.size(), i);
|
|
|
|
+// PdfDocument.Page page = mPdfDocument.startPage(i);
|
|
|
|
+// // Draw page content for printing
|
|
|
|
+// drawPage(page);
|
|
|
|
+// //mPdfDocument.finishPage(page);
|
|
|
|
+// }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ protected Void doInBackground(Void... params) {
|
|
|
|
+ // Write PDF document to file
|
|
|
|
+ InputStream input = null;
|
|
|
|
+ OutputStream output = null;
|
|
|
|
+ try {
|
|
|
|
+ input = new FileInputStream(file);
|
|
|
|
+ output = new FileOutputStream(destination
|
|
|
|
+ .getFileDescriptor());
|
|
|
|
+ byte[] buf = new byte[1024];
|
|
|
|
+ int bytesRead;
|
|
|
|
+ while ((bytesRead = input.read(buf)) > 0) {
|
|
|
|
+ output.write(buf, 0, bytesRead);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ mPdfDocument.writeTo(output);
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ callback.onWriteFailed(e.toString());
|
|
|
|
+ } finally {
|
|
|
|
+ if (mPdfDocument != null) {
|
|
|
|
+ mPdfDocument.close();
|
|
|
|
+ mPdfDocument = null;
|
|
|
|
+ }
|
|
|
|
+ try {
|
|
|
|
+ if (input != null)
|
|
|
|
+ input.close();
|
|
|
|
+ if (output != null)
|
|
|
|
+ output.close();
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ List<PageRange> pageRanges = new ArrayList<PageRange>();
|
|
|
|
+ int start;
|
|
|
|
+ int end;
|
|
|
|
+ int writtenPageCount = writtenPagesArray.size();
|
|
|
|
+ for (int i = 0; i < writtenPageCount; i++) {
|
|
|
|
+ start = writtenPagesArray.valueAt(i);
|
|
|
|
+ int oldEnd = end = start;
|
|
|
|
+ while ((i < writtenPageCount) && ((end - oldEnd) <= 1)) {
|
|
|
|
+ oldEnd = end;
|
|
|
|
+ end = writtenPagesArray.valueAt(i);
|
|
|
|
+ i++;
|
|
|
|
+ }
|
|
|
|
+ PageRange pageRange = new PageRange(start, end);
|
|
|
|
+ pageRanges.add(pageRange);
|
|
|
|
+ start = end = -1;
|
|
|
|
+ }
|
|
|
|
+ PageRange[] writtenPages = new PageRange[pageRanges.size()];
|
|
|
|
+ pageRanges.toArray(writtenPages);
|
|
|
|
+ callback.onWriteFinished(new PageRange[]{PageRange.ALL_PAGES});
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+ }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null);
|
|
|
|
+ canclleationSignal.setOnCancelListener(new OnCancelListener() {
|
|
|
|
+ @Override
|
|
|
|
+ public void onCancel() {
|
|
|
|
+ task.cancel(true);
|
|
|
|
+ synchronized (mLock) {
|
|
|
|
+ mLock.notifyAll();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|