kotlinretrofit2okhttppdfrenderer

Kotlin download and display a PDF


Hi I would like to download and display a pdf using Kotlin. I want to download and display a progress bar with the first page of the pdf display while we are downloading.Then display the PDF. I did it in swift with PDFKit it was very simple but I can't find an equivalent in Kotlin.

I made many research to display a pdf in Kotlin but I didn't got much result, it's seem that this subject is not really so first I looked at PdfRenderer that is native but most exemple are in java and not Kotlin and I don't get what is : documented.getSeekableFileDescriptor().

Then I looked at pdfView lib that is really nice to display a pdf but only from asset, the pdfView.fromStream doesn't seem to work and I can't get any exemple to how it's work.More over I would like to avoid downloading the pdf I want to display it directly to avoid long loading.

Finaly I used okhttp and retrofit to download the pdf but I can't use pdfView to display it because in the from asset the pdf has to be already in the project.

I found that downloading pdf from and url and display it with Kotlin is very difficult and not very documented.

So if anyone has some suggestion I'll take it.

here is my sample of code using pdfView.fromStream this only load a blanc page

 private fun loadpdf(){
        println("pdfview")
        //PDF View
        Thread(Runnable {
            val input = URL(pdf_url).openStream()
            val pdfView = this.findViewById<PDFView>(com.example.mylibrary.R.id.pdfView)
            //pdfView.fromFile(file)
            pdfView.fromStream(input)
                .enableSwipe(true) // allows to block changing pages using swipe
                .swipeHorizontal(true)
                .enableDoubletap(true)
                .defaultPage(0)
                .enableAnnotationRendering(false) // render annotations (such as comments, colors or forms)
                .password(null)
                .scrollHandle(null)
                .enableAntialiasing(true) // improve rendering a little bit on low-res screens
                // spacing between pages in dp. To define spacing color, set view background
                .spacing(0)
                .pageFitPolicy(FitPolicy.WIDTH)
                .load()
            println("testpdf")
        })
    }

And here is my sample of code using pdfView.fromAsset this one work but only if the file is already on the project however I want to get my pdf from and url

private fun loadpdf(){
        //PDF View
        Thread(Runnable {
            val pdfView = this.findViewById<PDFView>(com.example.mylibrary.R.id.pdfView)
            pdfView.fromAsset("url")
                .enableSwipe(true) // allows to block changing pages using swipe
                .swipeHorizontal(true)
                .enableDoubletap(true)
                .defaultPage(0)
                .enableAnnotationRendering(false) // render annotations (such as comments, colors or forms)
                .password(null)
                .scrollHandle(null)
                .enableAntialiasing(true) // improve rendering a little bit on low-res screens
                // spacing between pages in dp. To define spacing color, set view background
                .spacing(0)
                .pageFitPolicy(FitPolicy.WIDTH)
                .load()
        })
    }

Solution

  • If anyone got this problem, I solved it by using the coroutine :

    Add this dependency to your gradle build :

    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.2")
    

    then import this line :

    import kotlinx.coroutines.* 
    

    in your file.

    Then use launch coroutine methods as follow :

    private fun loadpdf(pdfView: PDFView){
            //PDF View
            GlobalScope.launch{
                val input : InputStream
                input = URL(pdf_url).openStream()
                pdfView.fromStream(input)
                    .enableSwipe(true) // allows to block changing pages using swipe
                    .swipeHorizontal(true)
                    .enableDoubletap(true)
                    .defaultPage(0)
                    .enableAnnotationRendering(false) // render annotations (such as comments, colors or forms)
                    .password(null)
                    .scrollHandle(null)
                    .enableAntialiasing(true) // improve rendering a little bit on low-res screens
                    // spacing between pages in dp. To define spacing color, set view background
                    .spacing(0)
                    .pageFitPolicy(FitPolicy.WIDTH)
                    .load()
            }
    

    You have to pass the pdfView cos you can use the global view in asyctask.

    Now to add a progress bar you can add to your xml :

    <ProgressBar
                android:id="@+id/Progressbar"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:layout_centerHorizontal="true"
                android:layout_centerVertical="true"
                android:layout_gravity="center"
                android:indeterminate="true"
                android:minWidth="200dp"
                android:minHeight="50dp" />
    

    then you need to override the function loadComplete to get the call back for your progress bar and implement OnLoadCompleteListener interface for your activity.

    And btw if you want to display page per page with the pdfView lib add :

    .swipeHorizontal(true)
    .pageSnap(true)
    .autoSpacing(true)
    .pageFling(true)