Android WebView в PDF: проблема с рулонным принтером - PullRequest
0 голосов
/ 20 июня 2020

Мне нужно распечатать PDF-файл из WebView (WebView.createPrintDocumentAdapter ()), а затем отправить его на рулонный принтер.

Для этого я создаю PDF-файл с одной страницей на основе Содержимое WebView на принтер.

1- Сначала я генерирую PrintDocumentAdapter из содержимого WebView (WebView.createPrintDocumentAdapter ()), а затем отправляю его на печать как файл PDF с очень маленькой высотой (новый MediaSize (ширина, высота)).

2- Затем я открываю и читаю предыдущий сгенерированный PDF-файл и суммирую высоту каждой страницы, созданной с этой небольшой высотой.

3- Затем я снова печатаю снова тот же WebView, но на этот раз с настройкой общей высоты, накопленной ранее.

Кажется, это сработало: у меня есть только одностраничный PDF-файл для печати на бумажном принтере (рулон).

Но на некоторых устройствах возникает проблема (наихудшая производительность старых устройств): onLayoutFinished -> onWriteFinished никогда не вызывается, когда используются небольшие значения высоты, чтобы получить n точное измерение высоты (работает ли MediaSize как украшение с некоторыми размерами?).

Кто-нибудь может мне помочь? Совет?

Заранее спасибо!

Это метод, который я использую для печати содержимого WebView в файл:

package android.print; // mandatory to compile
  
import android.os.CancellationSignal;
import android.os.ParcelFileDescriptor;
import android.print.PrintDocumentAdapter.LayoutResultCallback;
import android.print.PrintDocumentAdapter.WriteResultCallback;
import android.util.Log;
import java.io.File;

public class PdfPrint {

    private static final String TAG = PdfPrint.class.getSimpleName();
    private final PrintAttributes printAttributes;

    public PdfPrint(PrintAttributes printAttributes) {
        this.printAttributes = printAttributes;
    }

    public void print(final PrintDocumentAdapter printAdapter, final File path, final String fileName, final PdfPrint.CallbackPrint callback) throws Exception {

        ParcelFileDescriptor oParcelFile = PdfPrint.this.getOutputFile(path, fileName);

        printAdapter.onLayout(null, this.printAttributes, null, new LayoutResultCallback() {
            public void onLayoutFinished(PrintDocumentInfo info, boolean changed) {

                printAdapter.onWrite(new PageRange[]{PageRange.ALL_PAGES}, oParcelFile, new CancellationSignal(), new WriteResultCallback() {
                    public void onWriteFinished(PageRange[] pages) {
                        super.onWriteFinished(pages);
                        if (pages.length > 0) {
                            File file = new File(path, fileName);
                            String pathx = file.getAbsolutePath();
                            callback.success(pathx);
                        } else {
                            callback.onFailure();
                        }
                    }
                });

            }
        }, null);

    }

    private ParcelFileDescriptor getOutputFile(File path, String fileName) throws Exception {
        if (!path.exists()) {
            if (!path.mkdirs()) {
                throw new Exception("Couldn't create PFD folder.");
            }
        }

        File file = new File(path, fileName);

        try {
            if (!file.createNewFile()) {
                throw new Exception("Couldn't create PFD file.");
            }

            return ParcelFileDescriptor.open(file, 805306368);
        } catch (Exception var5) {
            Log.e(TAG, "Failed to open ParcelFileDescriptor", var5);
            return null;
        }
    }

    public interface CallbackPrint {
        void success(String var1);

        void onFailure();
    }
}

И это - это метод, который я использую в трех настройках для создания моего одностраничного PDF-файла из веб-просмотра:

  final int paperPrintAreaWidthInches = 3000;  // 3 inches
    final int heightSegment = 72;   // 
    
    private void pre_renderPDF(WebView oWebView) {
        try {
            final ProgressDialog progressDialog = new ProgressDialog(this);
            progressDialog.setMessage("Processs...");
            progressDialog.show();
    
            String preFileName = "pre_" + _sBoletin + "_" + System.currentTimeMillis() + ".pdf";
            PrintAttributes.MediaSize mediaSize = getMediaSize(paperPrintAreaWidthInches, heightSegment);
            PdfView.createWebPrintJob(this, oWebView, mediaSize, outputDir, preFileName, new PdfView.Callback() {
    
                @Override
                public void success(String path) {
                    try {
                        progressDialog.setMessage("Generate PDF...");
    
                        ParcelFileDescriptor parcelFileDescriptor = ParcelFileDescriptor.open(new File(path), ParcelFileDescriptor.MODE_READ_ONLY);
                        PdfRenderer pdfRender = new PdfRenderer(parcelFileDescriptor);
    
                        float readHeightDocument = 0; // x * 1000 ->  MARGIN
                        int i = 0;
                        while (i < pdfRender.getPageCount()) {
                            PdfRenderer.Page pg = pdfRender.openPage(i);
                            readHeightDocument += pg.getHeight();
                            pg.close();
                            i++;
                        }
    
                        float inchesMil = (1000F * readHeightDocument / 72F) + 200F; // 200 margin
    
    
                        // 2
                        new Handler().postDelayed(() -> {
                            String fileName = _sBoletin + "_" + System.currentTimeMillis() + ".pdf";
                            PrintAttributes.MediaSize realSize = getMediaSize(paperPrintAreaWidthInches, Math.round(inchesMil));
                            try {
                                PdfView.createWebPrintJob(PrintMultaPdfActivity.this, oWebView, realSize, outputDir, fileName, new PdfView.Callback() {
                                    @Override
                                    public void success(String var1) {
                                        multaOk = new File(var1);
                                        oPDFViewer.fromFile(multaOk).load();
                                        if(inchesMil>10000) {
                                            oPDFViewer.zoomTo(oPDFViewer.getMaxZoom());
                                        }
                                        progressDialog.dismiss();
                                    }
                                    @Override
                                    public void failure() {
                                        progressDialog.dismiss();
                                    }
                                });
                            } catch (Exception e) {
                                e.printStackTrace();
                                progressDialog.dismiss();
                                Toast.makeText(PrintMultaPdfActivity.this, "No se pudo generar el documento por favor inténtelo de nuevo.", Toast.LENGTH_SHORT).show();
                            }
                        }, 5);
    
                    } catch (Exception e) {
                        e.printStackTrace();
                        progressDialog.dismiss();
                        Toast.makeText(PrintMultaPdfActivity.this, "No se pudo generar el documento por favor inténtelo de nuevo.", Toast.LENGTH_SHORT).show();
                    }
                }
    
                @Override
                public void failure() {
                    progressDialog.dismiss();
                }
            });
    
        } catch (Exception ex) {
            Log.e(null, null, ex);
        }
    }
    
    public static PrintAttributes.MediaSize getMediaSize(int width, int height) {
        return new PrintAttributes.MediaSize(
                "3 in roll",
                "3 in roll",
                width,
                height);
    }
    
...