0

I'm trying to show a pdf in android app. The response I get from the server is looking like this. I convert it to input stream and pass it to pdf viewer library

%PDF-1.4 %ÓôÌá 1 0 obj << /CreationDate(D:20180403085232+02'00') /Creator(PDFsharp 1.32.3057-g (www.pdfsharp.net)) /Producer(PDFsharp 1.32.3057-g (www.pdfsharp.net)) endobj 2 0 obj << /Type/Catalog /Pages 3 0 R endobj 3 0 obj << /Type/Pages /Count 3 /Kids[4 0 R 8 0 R 11 0 R] endobj 4 0 obj << /Type/Page /MediaBox[0 0 612 792] /Parent 3 0 R /Contents 5 0 R /Resources << /ProcSet [/PDF/Text/ImageB/ImageC/ImageI] /XObject << /I0 6 0 R /ExtGState << /GS0 7 0 R

/Group << /CS/DeviceRGB /S/Transparency /I false /K false

endobj 5 0 obj << /Length 260 /Filter/FlateDecode stream xœíRMK1½÷Wä˜M“&Mî¢àa]oâIEDF‚¿ÞÌ̺²ø¥”4y¯—´C©@¹ŽÆÐƒáú!ÏDpñZ†2€š W9#¾g­NŽa“/…à4÷}©gåòŠàf§{¾.«õ–àWìÚ¡WÆT4Bµ †¡O·e[F>g^í=|UEw‡ª‚Ö$å(U‘ôÇ›„L¶ÜÑ™—~¤6•š'Ú9f”Pz›PŽ€¦¨"бv_gly›Û÷Mä~.î] ™ÛëØˆ?œå€«Ul¡À™y_6þ»Aÿ—ÿ¤|èYòÿX`ìfÈ»ï³Éõй·ò endstream endobj 6 0 obj << /Type/XObject /Subtype/Image /Length 5097196 /Filter/FlateDecode /Width 2511 /Height 3531 /BitsPerComponent 8 /ColorSpace/DeviceRGB /Interpolate true stream xœìÝ œ¤g]'ðïé9rÂáˆJAE%€ Š"ë‚FQ0 Ë!º» ¢‚+^ (h

This is my code:

    // get the response as string
    val body = response.body?.string() 
    // convert it to inputstream
    val inputStream = ByteArrayInputStream(body.toByteArray(Charsets.UTF_8)) 
    // load it wil pdf viewer
    pdf_viewer.fromStream(inputStream).load() 

Everything till the last line is ok. I got init FPDF library but there is nothing on the screen. It stays with white background. If I open the pdf standalone I can see that everything is fine.

I'm using

implementation 'com.github.barteksc:android-pdf-viewer:2.8.2'

here is the xml file

<com.github.barteksc.pdfviewer.PDFView
  android:id="@+id/pdf_viewer"
  android:layout_width="match_parent"
  android:layout_height="match_parent" />

EDIT: the working solution was to get the bytes and pass them to PDFViewer

    
val bodyBytes: ByteArray = response.body!!.bytes()
runOnUiThread {
    pdf_viewer.fromBytes(bodyBytes).enableSwipe(true) // allows to block changing pages using swipe
        .swipeHorizontal(false)
        .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)
        .invalidPageColor(Color.WHITE) // color of page that is invalid and cannot be loaded
        .load()
}
kmignt
  • 67
  • 14
  • 1
    `response.body?.string()` -- a PDF is not a string. It will contain binary data. Your use of `string()` is corrupting the PDF data. – CommonsWare Sep 13 '19 at 10:40
  • My idea was to convert the string of data to input stream easily. I coudn't find any solution of converting the pdf data to input stream. Can you give me a guidelines for that? – kmignt Sep 13 '19 at 11:33
  • 1
    Use `response.body?.bytes()` to get the bytes. Note that you will crash with an `OutOfMemoryException` for larger PDFs. A safer solution is to [write the PDF to a file](https://stackoverflow.com/a/29012988/115145), then open the file. – CommonsWare Sep 13 '19 at 11:43
  • Hi, thank you! it worked. Btw do you have any idea how I can accomplish the same thing in iOS with Swift? – kmignt Sep 18 '19 at 08:28
  • Sorry, that's not my area of expertise. – CommonsWare Sep 18 '19 at 11:07
  • which library have you used @kmignt for parsing the data.Can you post the full parsing code here. – Chinmaay May 28 '21 at 06:07
  • @Chinmaay I put it in the post. – kmignt May 28 '21 at 10:32

0 Answers0