dennisrufigill
dennisrufigill

Reputation: 379

Print Manager is now showing save to PDF when printer is connected

I am trying to convert webview into Pdf and saving it on personal mobile using Print Manager. It works fine when printer is not connected but if printer is connected to mobile then save pdf option is not showing. Device has android 10.

 fun printWebPage(webView: WebView, loadID: String) {
    var jobName = ""
 
    printBtnPressed = true
    val printManager =
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
            requireContext().getSystemService(Context.PRINT_SERVICE) as PrintManager
        } else {
            TODO("VERSION.SDK_INT < KITKAT")
        }

    // on below line we are creating a variable for job name
    if(loadID.isEmpty()){
        jobName = "Load Detail"
    }else{
         jobName = "Load ID:$loadID"
    }

    // on below line we are initializing our print adapter.
    val printAdapter =
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
            // on below line we are creating
            // our print document adapter.
            webView.createPrintDocumentAdapter(jobName)
        } else {
            TODO("VERSION.SDK_INT < LOLLIPOP")
        }
    // on below line we are checking id
    // print manager is not null
    assert(printManager != null)

    // on below line we are initializing
    // our print job with print manager
    printJob = printManager.print(
        jobName, printAdapter,
        // on below line we are calling
        // build method for print attributes.
        PrintAttributes.Builder().build()
    )

}

Upvotes: 0

Views: 818

Answers (1)

R. Cozendey
R. Cozendey

Reputation: 61

Print Manager rarely recognizes any printer, and I guess its main purpose has become to simply save to pdf...

In my case, I solved this by firstly converting the webview into a bitmap, then scaling the bitmap to fit into the pdf page.

As for the printing part, I think it was more flexible to simply share the pdf and ask the user to select his printer software, as it's more useful than simply saving as pdf.

If you want to print several pages, I think it is more manageable to create different bitmaps and assign them to different pdf pages.

This code converts a webview into a pdf page and then shares it, asking the user to select his printer app:

public static void sharePdfFile(WebView webView, Context context)
{
    Bitmap bitmap = webviewToBitmap( webView );
    PrintedPdfDocument pdf =  bitmapToPdf( bitmap, context );
    File file = pdfToFile( pdf, context );
    shareFile( file,"application/pdf", context );
}

private static void shareFile(File file, String contentType, Context context)
{
    Uri uri = FileProvider.getUriForFile(
        context,
        context.getPackageName() + ".fileprovider",
        file);
    Intent shareIntent = new Intent(android.content.Intent.ACTION_SEND);
    shareIntent.setType(contentType);
    shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
    shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    Toast.makeText(
        context,
        "Choose your printer app",
        Toast.LENGTH_LONG
    ).show();
    context.startActivity( shareIntent );
}

private static File pdfToFile(PrintedPdfDocument printedPdfDocument, Context context)
{
    File file = new File(context.getFilesDir(), "share.pdf");
    try {
        FileOutputStream outputStream = new FileOutputStream(file);
        printedPdfDocument.writeTo(outputStream);
        outputStream.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
    printedPdfDocument.close();
    return file;
}


private static PrintedPdfDocument bitmapToPdf(Bitmap bitmap, Context context)
{
    PrintAttributes printAttributes = new PrintAttributes.Builder()
        .setColorMode(PrintAttributes.COLOR_MODE_COLOR)
        .setMediaSize(PrintAttributes.MediaSize.ISO_A4)
        .setMinMargins(PrintAttributes.Margins.NO_MARGINS)
        .setResolution(new PrintAttributes.Resolution("1", "label", 300, 300))
        .build();
    PrintedPdfDocument printedPdfDocument = new PrintedPdfDocument(context, printAttributes);
    PdfDocument.Page pdfDocumentPage = printedPdfDocument.startPage(1);
    Canvas pdfCanvas = pdfDocumentPage.getCanvas();
    bitmap = scaleBitmapToHeight(bitmap, pdfCanvas.getHeight());
    pdfCanvas.drawBitmap(bitmap, 0f, 0f, null);
    printedPdfDocument.finishPage(pdfDocumentPage);
    return printedPdfDocument;
}

private static Bitmap webviewToBitmap(WebView webView) {
    webView.measure(
        View.MeasureSpec.makeMeasureSpec(
            0,
            View.MeasureSpec.UNSPECIFIED
        ),
        View.MeasureSpec.makeMeasureSpec(
            0,
            View.MeasureSpec.UNSPECIFIED
        )
    );
    int webViewWidth = webView.getMeasuredWidth();
    int webViewHeight = webView.getMeasuredHeight();
    webView.layout(0,0, webViewWidth, webViewHeight );
    Bitmap bitmap = Bitmap.createBitmap(webViewWidth, webViewHeight, Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    canvas.drawBitmap(bitmap, 0, bitmap.getHeight(), new Paint());
    webView.draw(canvas);
    return bitmap;
}

private static Bitmap scaleBitmapToHeight(Bitmap bitmap, int maxHeight) {
    int height = bitmap.getHeight();
    if(height > maxHeight) {
        int width = bitmap.getWidth();
        float scalePercentage = ((float)maxHeight) / height;
        return Bitmap.createScaledBitmap(bitmap, (int) (width * scalePercentage), maxHeight, false);
    }
    return bitmap;
}

Upvotes: 0

Related Questions