Android Question How to Print PDF Using Android Printing Framework

nadhiras

Member
Licensed User
Longtime User
Hi all.
I read this post :
https://www.b4x.com/android/forum/threads/android-printing-framework.38796/
on that post describe how to print using android printing framework. but we need printing pdf
and as we know webview cannot load pdf.
i know there is many ways to print in here.
but i want my apps print using android printing framework.

if found some code form net to use this framework. but in java . i don't understand java :(:(
so anyone can converting java to b4a ..

and this code i found :
B4X:
public class PrintPDFAdapter extends PrintDocumentAdapter {
    private File pdfFile;
    private String fileName;

    public PrintPDFAdapter(File pdfFile, String fileName) {
        this.pdfFile = pdfFile;
        this.fileName = fileName;
    }


    @Override
    public void onLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes, CancellationSignal cancellationSignal, LayoutResultCallback callback, Bundle extras) {
        if (cancellationSignal.isCanceled()) {
            callback.onLayoutCancelled();
            return;
        }

        PrintDocumentInfo pdi = new PrintDocumentInfo.Builder(fileName).setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT).build();

        callback.onLayoutFinished(pdi, true);
    }

    @Override
    public void onWrite(PageRange[] pages, ParcelFileDescriptor destination, CancellationSignal cancellationSignal, WriteResultCallback callback) {
        InputStream input = null;
        OutputStream output = null;

        try {

            input = new FileInputStream(pdfFile);
            output = new FileOutputStream(destination.getFileDescriptor());

            byte[] buf = new byte[1024];
            int bytesRead;

                while ((bytesRead = input.read(buf)) > 0) {
                output.write(buf, 0, bytesRead);
            }

            callback.onWriteFinished(new PageRange[]{PageRange.ALL_PAGES});

        } catch (FileNotFoundException ee){
            //Catch exception
        } catch (Exception e) {
            //Catch exception
        } finally {
            try {
                input.close();
                output.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
B4X:
private void doPDFPrint(File pdfFile, String filename) {
    PrintManager printManager = (PrintManager) this.getSystemService(Context.PRINT_SERVICE);
    String jobName = this.getString(R.string.app_name) + " Report";
    PrintPDFAdapter pda = new PrintPDFAdapter(pdfFile, filename);
    PrintAttributes attrib = new PrintAttributes.Builder().
            setMediaSize(PrintAttributes.MediaSize.NA_LETTER.asLandscape()).
            setMinMargins(PrintAttributes.Margins.NO_MARGINS).
            build();
    printManager.print(jobName, pda, attrib);
}

Sorry for my bad English...
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
Try this:
B4X:
Sub Activity_Create(FirstTime As Boolean)
   File.Copy(File.DirAssets, "myfile.pdf", File.DirRootExternal, "1.pdf")
   PrintPDF(File.DirRootExternal, "1.pdf")
End Sub

Sub PrintPDF(Dir As String, FileName As String)
   Dim ctxt As JavaObject
   ctxt.InitializeContext
   Dim jPrintManager As JavaObject = ctxt.RunMethod("getSystemService", Array As Object("print"))
   Dim jPrintAdapter As JavaObject
   jPrintAdapter.InitializeNewInstance(Application.PackageName & ".main$PrintPDFAdapter", Array (File.Combine(Dir, FileName), FileName))
   Dim jobName As String = "Document"
   jPrintManager.RunMethod("print", Array As Object(jobName, jPrintAdapter, Null))
End Sub

#if Java
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.ParcelFileDescriptor;
import android.print.PageRange;
import android.print.PrintAttributes;
import android.print.PrintDocumentAdapter;
import android.print.PrintDocumentInfo;
public static class PrintPDFAdapter extends PrintDocumentAdapter {
    private String pdfFile;
    private String fileName;

    public PrintPDFAdapter(String pdfFile, String fileName) {
    this.pdfFile = pdfFile;
    this.fileName = fileName;
    }


    @Override
    public void onLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes, CancellationSignal cancellationSignal, LayoutResultCallback callback, Bundle extras) {
    if (cancellationSignal.isCanceled()) {
    callback.onLayoutCancelled();
    return;
    }

    PrintDocumentInfo pdi = new PrintDocumentInfo.Builder(fileName).setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT).build();

    callback.onLayoutFinished(pdi, true);
    }

    @Override
    public void onWrite(PageRange[] pages, ParcelFileDescriptor destination, CancellationSignal cancellationSignal, WriteResultCallback callback) {
    InputStream input = null;
    OutputStream output = null;

    try {

    input = new FileInputStream(pdfFile);
    output = new FileOutputStream(destination.getFileDescriptor());

    byte[] buf = new byte[1024];
    int bytesRead;

    while ((bytesRead = input.read(buf)) > 0) {
    output.write(buf, 0, bytesRead);
    }

    callback.onWriteFinished(new PageRange[]{PageRange.ALL_PAGES});

    } catch (Exception e) {
    throw new RuntimeException(e);
    } finally {
    try {
    input.close();
    output.close();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }
   }
#end if
 
Upvote 0

krlos2004

Member
Licensed User
Longtime User
hi

this error


jPrintAdapter.InitializeNewInstance(Application.PackageName & ".main$PrintPDFAdapter", Array (File.Combine(Dir, FileName), FileName))

->>> (Exception) java.lang.Exception: java.lang.ClassNotFoundException: b4a$example$main$PrintPDFAdapter !!!
 
Upvote 0

krlos2004

Member
Licensed User
Longtime User
Help error Adapter print bluetootf, whats error ??


B4X:
#Region  Project Attributes
    #ApplicationLabel: Print PDF
    #VersionCode: 1
    #VersionName:
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: unspecified
    #CanInstallToExternalStorage: False
#End Region

#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: True
#End Region

Sub Process_Globals
 
    Dim Serial1 As Serial     
    Dim wmac As String       
   
End Sub

Sub Globals
    Private btImprimir As Button
    Private btDesconectar As Button
    Private btConect As Button
End Sub

Sub Activity_Create(FirstTime As Boolean)
    Activity.LoadLayout("1")    
     Serial1.Initialize("Serial1")
   
    btConect.Enabled=True
     btImprimir.Enabled=False       
    btDesconectar.Enabled=False
   
End Sub

Sub btImprimir_Click
    File.Copy(File.DirAssets, "teste.pdf", File.DirRootExternal, "1.pdf")
    PrintPDF(File.DirRootExternal, "1.pdf")
End Sub

Sub Activity_Resume
    If Serial1.IsEnabled = False Then
        Msgbox("Habilite o BlueToof", "")
    End If
End Sub

Sub Activity_Pause (UserClosed As Boolean)
    If btDesconectar.Enabled = True Then Serial1.Disconnect    
End Sub


Sub btConect_Click

    Dim PairedDevices As Map
    PairedDevices = Serial1.GetPairedDevices
   
    Dim l As List
    l.Initialize
    For i = 0 To PairedDevices.Size - 1
        l.Add(PairedDevices.GetKeyAt(i))
    Next
   
    wmac = ""
    Dim res As Int
    res = InputList(l, "Escolha o Dispositivo", -1) 
    If res <> DialogResponse.CANCEL Then       
         wmac = PairedDevices.Get(l.Get(res))
        Serial1.Connect(wmac) 'convert the name to mac address
    End If
End Sub

Sub btDesconectar_Click
    Serial1.Disconnect
   
    btConect.Enabled=True
    btImprimir.Enabled=False   
    btDesconectar.Enabled=False
   
End Sub

Sub Serial1_Connected (Success As Boolean)
    If Success Then         
        ToastMessageShow("Você está Conectado", False)   
            
        btConect.Enabled=False
         btImprimir.Enabled=True       
        btDesconectar.Enabled=True
       
    Else
        Msgbox(LastException.Message, "Problemas na Conexão ")
    End If   
End Sub


Sub PrintPDF(Dir As String, FileName As String)
   
     Try
       
        Dim ctxt As JavaObject
        ctxt.InitializeContext
       
        Dim jPrintManager As JavaObject = ctxt.RunMethod("getSystemService", Array As Object(wmac))  
       
        'line 111 - error :  (Exception) java.lang.Exception:  java.lang.ClassNotFoundException: b4a$example$main$PrintPDFAdapter
       
        Dim jPrintAdapter As JavaObject
        jPrintAdapter.InitializeNewInstance(Application.PackageName & ".main$PrintPDFAdapter", Array (File.Combine(Dir, FileName), FileName))
       
        Dim jobName As String = "Document"
        jPrintManager.RunMethod( wmac, Array As Object(jobName, jPrintAdapter, Null))
       

    Catch
        Log(LastException)
    End Try

 
End Sub

#if Java

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.ParcelFileDescriptor;
import android.print.PageRange;
import android.print.PrintAttributes;
import android.print.PrintDocumentAdapter;
import android.print.PrintDocumentInfo;

public static class PrintPDFAdapter extends PrintDocumentAdapter {
    private String pdfFile;
    private String fileName;

    public PrintPDFAdapter(String pdfFile, String fileName) {
    this.pdfFile = pdfFile;
    this.fileName = fileName;
    }


    @Override
    public void onLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes, CancellationSignal cancellationSignal, LayoutResultCallback callback, Bundle extras) {
    if (cancellationSignal.isCanceled()) {
    callback.onLayoutCancelled();
    return;
    }

    PrintDocumentInfo pdi = new PrintDocumentInfo.Builder(fileName).setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT).build();

    callback.onLayoutFinished(pdi, true);
    }

    @Override
    public void onWrite(PageRange[] pages, ParcelFileDescriptor destination, CancellationSignal cancellationSignal, WriteResultCallback callback) {
    InputStream input = null;
    OutputStream output = null;

    try {

    input = new FileInputStream(pdfFile);
    output = new FileOutputStream(destination.getFileDescriptor());

    byte[] buf = new byte[1024];
    int bytesRead;

    while ((bytesRead = input.read(buf)) > 0) {
    output.write(buf, 0, bytesRead);
    }

    callback.onWriteFinished(new PageRange[]{PageRange.ALL_PAGES});

    } catch (Exception e) {
    throw new RuntimeException(e);
    } finally {
    try {
    input.close();
    output.close();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }
   }
#end if
 
Upvote 0

krlos2004

Member
Licensed User
Longtime User
Error occurred on line: 112 (Main)
java.lang.ClassNotFoundException: b4a$example$main$PrintPDFAdapter
at java.lang.Class.classForName(Native Method)
at java.lang.Class.forName(Class.java:217)
at java.lang.Class.forName(Class.java:172)
at anywheresoftware.b4j.object.JavaObject.getCorrectClassName(JavaObject.java:273)
at anywheresoftware.b4j.object.JavaObject.InitializeNewInstance(JavaObject.java:83)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at anywheresoftware.b4a.shell.Shell.runVoidMethod(Shell.java:753)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:343)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:247)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:134)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:157)
at anywheresoftware.b4a.debug.Debug.delegate(Debug.java:259)
at b4a.example.main._printpdf(main.java:538)
at b4a.example.main._btimprimir_click(main.java:530)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:708)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:340)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:247)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:134)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:157)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:153)
at anywheresoftware.b4a.objects.ViewWrapper$1.onClick(ViewWrapper.java:78)
at android.view.View.performClick(View.java:6824)
at android.view.View$PerformClick.run(View.java:27191)
at android.os.Handler.handleCallback(Handler.java:605)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4517)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:993)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:760)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NoClassDefFoundError: b4a$example$main$PrintPDFAdapter
... 39 more
Caused by: java.lang.ClassNotFoundException: b4a$example$main$PrintPDFAdapter
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:61)
at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
... 39 more
(Exception) java.lang.Exception: java.lang.ClassNotFoundException: b4a$example$main$PrintPDFAdapter
 
Upvote 0

krlos2004

Member
Licensed User
Longtime User
True, on another android 5.2 it worked, but
Give another mistake


** Service (starter) Create **
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
Error occurred on line: 103 (Main)
java.lang.RuntimeException: Object should first be initialized (JavaObject).
at anywheresoftware.b4a.AbsObjectWrapper.getObject(AbsObjectWrapper.java:50)
at anywheresoftware.b4j.object.JavaObject.getCurrentClass(JavaObject.java:258)
at anywheresoftware.b4j.object.JavaObject.RunMethod(JavaObject.java:118)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at anywheresoftware.b4a.shell.Shell.runVoidMethod(Shell.java:753)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:343)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:247)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:134)
at anywheresoftware.b4a.BA$2.run(BA.java:328)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:7007)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)
java.lang.Exception: java.lang.RuntimeException: Object should first be initialized (JavaObject).
Connected to B4A-Bridge (Wifi)
sending message to waiting queue (CallSubDelayed - UpdateStatus)
 
Upvote 0
Top