Kaynağa Gözat

Implement printer

Wayne 6 yıl önce
ebeveyn
işleme
6839d411ab

+ 261 - 0
src/main/java/com/bomostory/sceneeditmodule/PrintTools.java

@@ -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();
+                    }
+                }
+            });
+        }
+    }
+}

+ 45 - 0
src/main/java/com/bomostory/sceneeditmodule/screen/movie/MovieEditActivity.kt

@@ -18,6 +18,7 @@ import android.widget.SeekBar
 import android.widget.Toast
 import com.bomostory.sceneeditmodule.Config
 import com.bomostory.sceneeditmodule.PdfMaker
+import com.bomostory.sceneeditmodule.PrintTools
 import com.bomostory.sceneeditmodule.SuperMovieMaker
 import com.bomostory.sceneeditmodule.basicdata.Music
 import com.bomostory.sceneeditmodule.basicdata.Project
@@ -421,6 +422,7 @@ class MovieEditActivity : AppCompatActivity(),
                 startActivity(Intent.createChooser(intent, ""))
             }
             onClickExportPdf = Runnable { onClickExportPdf() }
+            onClickPrint = Runnable { onClickPrint() }
             onClickPlay = Runnable {
                 moviePlayer.moviePlayListener = dialogMoviePlayListener
                 moviePlayer.init()
@@ -429,6 +431,49 @@ class MovieEditActivity : AppCompatActivity(),
         }.show(supportFragmentManager)
     }
 
+    private fun onClickPrint() {
+        ExportPdfDialog().also { exportPdfDialog ->
+            exportPdfDialog.project = viewModel.project!!
+            exportPdfDialog.image1Path = viewModel.project?.scene1File?.path ?: ""
+            exportPdfDialog.image2Path = viewModel.project?.scene2File?.path ?: ""
+            exportPdfDialog.onClickPrint = Runnable {
+                when (exportPdfDialog.type) {
+                    ExportPdfDialog.Type.Standard -> {
+                        val name = "standard_${viewModel.project?.name}_${System.currentTimeMillis()}.pdf"
+                        if (!Config.PDF_FOLDER.exists()) {
+                            Config.PDF_FOLDER.mkdirs()
+                        }
+                        val file = File(Config.PDF_FOLDER, name)
+                        file.createNewFile()
+                        val observable = PdfMaker.makeStandard(this@MovieEditActivity, viewModel.project!!, file)
+                        Pair(file, observable)
+                    }
+                    ExportPdfDialog.Type.Booklet -> {
+                        val name = "booklet_${viewModel.project?.name}_${System.currentTimeMillis()}.pdf"
+                        if (!Config.PDF_FOLDER.exists()) {
+                            Config.PDF_FOLDER.mkdirs()
+                        }
+                        val file = File(Config.PDF_FOLDER, name)
+                        file.createNewFile()
+                        val observable = PdfMaker.makeBooklet(this@MovieEditActivity, viewModel.project!!, file)
+                        Pair(file, observable)
+                    }
+                }.apply {
+                    exportPdfFile(second, Runnable {
+                        exportPdfDialog.dismiss()
+                    }, Runnable {
+                        val context = this@MovieEditActivity
+                        val file = first
+                        viewModel.project?.story?.let {
+                            val pages = it.scenes.size
+                            PrintTools.getInstance().doPrint(context, file, pages)
+                        }
+                    })
+                }
+            }
+        }.show(supportFragmentManager)
+    }
+
     private fun onClickExportPdf() {
         ExportPdfDialog().also { exportPdfDialog ->
             exportPdfDialog.project = viewModel.project!!

+ 0 - 2
src/main/res/layout/dialog_share.xml

@@ -100,9 +100,7 @@
         android:layout_marginTop="16dp"
         android:background="@null"
         android:drawablePadding="8dp"
-        android:drawableTint="@android:color/darker_gray"
         android:drawableTop="@drawable/ic_print_36dp"
-        android:enabled="false"
         android:gravity="center"
         android:text="@string/share_dialog_print"
         app:layout_constraintLeft_toLeftOf="parent"