How to open a PDF file in Android programmatically?

Opening and viewing documents in Android applications is very interesting and a must to have thing in every application. You can open any application present on your mobile and you will find that every application contains documents in some or the other way. And among these documents, the most popular and widely used document format is the PDF format. PDF or Portable Document Format is a file format that has captured all the elements of a printed document. This is the most used document format. For example, in the Paytm application, you get your monthly expenses in the form of PDF document. So, if you want to display some kind of document in your application, then you can use the PDF format.

In this blog, we will learn how to open a PDF file in Android programmatically. So, let’s get started.

Ways of opening PDF in Android

If you want to display PDF in your Android application, there are various ways of doing it. Some of the ways of opening the PDF can be:

  1. From Assets: Let’s take an example, if you want to display some icons in your application then you will put all your icons in the drawable folder and then you will use those icons in your application. Same is with the case of PDF files. If you have some PDF file that is constant and you want to display it in your application then you can put that PDF file in the assets folder and use that PDF in your app. One example can be the Terms and Conditions file. The terms and conditions files are rarely changed. So, you can put that document in the assets folder and use it.
  2. From Device: The other way of opening a PDF is to open it from the device itself. Here, you can open the PDF present in your mobile device in your mobile application. This is the most used approach for opening the PDF in an Android device. What you need to do is just take the READ/WRITE EXTERNAL STORAGE permission and you can open the PDF files of your device.
  3. From Internet: Here, you can open PDF files from the internet. All you need to do is just use the URL of the PDF file and after downloading the PDF file, you can open the PDF file in your mobile application.

So, we will look upon all these ways of viewing the PDF in your Android Application. Let’s get started.

Opening a PDF file in Android using WebView

The very first and the easiest way of displaying the PDF file is to display it in the WebView. All you need to do is just put WebView in your layout and load the desired URL by using the webView.loadUrl() function.

In my case, the name of my Activity is WebViewPdf. The code for the activity_web_view_pdf.xml is:

<RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    <WebView
            android:id="@+id/webView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>

</RelativeLayout>

Now, let’s move on to the coding part of WebViewPdf.kt file. Here I am using the URL of Github Cheat Sheet. You can replace it with your own URL. Also, you can take input of the URL form the user, using an EditText and then use this URL to load PDF. The code for the WebViewPdf.kt file is:

class WebViewPdf : AppCompatActivity() {

    lateinit var webView: WebView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_web_view_pdf)

        webView = findViewById<WebView>(R.id.webView)
        webView.webViewClient = WebViewClient()
        webView.settings.setSupportZoom(true)
        webView.settings.javaScriptEnabled = true
        val url = "https://github.github.com/training-kit/downloads/github-git-cheat-sheet.pdf"
        webView.loadUrl("https://docs.google.com/gview?embedded=true&url=$url")
    }
}

The last thing that you need to do is adding INTERNET permission to your application. So, add the below line in your AndroidManifest.xml file:

<uses-permission android:name="android.permission.INTERNET" />

Now, run the application on your mobile phone and the PDF will be displayed on the screen.

Opening a PDF file in Android using some library

There are various libraries that can be used to display PDF files in our application. So, in this part of the blog, we will learn how to open a PDF file from Assets folder or from your device or from the Internet.

We will use the PDFViewer library to read PDF files and File-Loader library to download the file from the Internet and then display it in the application.

So, in your project level build.gradle file, add the below line of code in the repositories section:

repositories {
    google()
    jcenter()
    maven {url "https://jitpack.io"}//add this line
}

Also, in the module level build.gradle file, add the below dependencies:

implementation 'com.github.barteksc:android-pdf-viewer:2.8.2'
implementation 'com.github.kk121:File-Loader:1.2'

After adding the dependencies, our next task is to add the permissions of INTERNET and READ/WRITE EXTERNAL STORAGE in your application’s AndroidManifest.xml file:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Assets Folder

Firstly, we will look upon how to view PDF, stored in the Assets Folder.

So, until now, we are done with permissions and dependencies. Our next step is to design the UI of our application. Here we are having three Buttons for opening PDF i.e. for opening PDF from the Assets folder or from the mobile device or from the Internet. So, here is the code for our activity_main.xml file:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    
    <LinearLayout
            android:orientation="vertical"
            android:layout_centerInParent="true"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">
        <Button
                android:id="@+id/open_assets"
                android:text="From Assets"
                android:layout_width="320dp"
                android:layout_height="wrap_content" />
        <Button
                android:id="@+id/open_storage"
                android:text="From Device"
                android:layout_width="320dp"
                android:layout_height="wrap_content" />
        <Button
                android:id="@+id/open_internet"
                android:text="From Internet"
                android:layout_width="320dp"
                android:layout_height="wrap_content" />
    </LinearLayout>

</RelativeLayout>

Now, create an Activity to display PDF files in the application. So, make an Activity named ViewActivity and add the below code for the activity_view.xml file:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".ViewActivity">

    <com.github.barteksc.pdfviewer.PDFView
            android:id="@+id/pdf_viewer"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    </com.github.barteksc.pdfviewer.PDFView>
    <ProgressBar
            android:id="@+id/progress_bar"
            android:indeterminate="true"
            android:layout_centerInParent="true"
            android:visibility="gone"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
</RelativeLayout>

The next step is adding the PDF file in our Assets folder. Make an asset folder in the java folder by right clicking on java folder and then New > Folder > Assets Folder. After that paste the PDF file in your assets folder.

Now, add the below code to handle the onClick listener for the Assets Button:

class MainActivity : AppCompatActivity() {

    val PICK_PDF_CODE = 1000
    lateinit var btn_open_assets: Button//for assets
    lateinit var btn_open_storage:Button//for phone storage
    lateinit var btn_opn_intenet:Button//for internet

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        btn_open_assets = findViewById(R.id.open_assets)

        btn_open_assets.setOnClickListener(object: View.OnClickListener {
            override fun onClick(view:View) {
                val intent = Intent(this@MainActivity, ViewActivity::class.java)
                intent.putExtra("ViewType", "assets")
                startActivity(intent)
            }
        })
    }
}

Now, we will use the PDFViewer Library to perform various operations on PDF i.e setting the default Page by using defaultPage(), setting the swipe event by using enableSwipe(), enable the double tap to zoom by using enableDoubletap() any many more.

So, the code for the ViewActivity.kt file is below:

class ViewActivity : AppCompatActivity() {

    lateinit var pdfView: PDFView
    lateinit var progressBar: ProgressBar

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_view)

        pdfView = findViewById(R.id.pdf_viewer)
        progressBar = findViewById(R.id.progress_bar)
        if (intent != null)
        {
            val viewType = intent.getStringExtra("ViewType")
            if (viewType != null || TextUtils.isEmpty(viewType))
            {
                if (viewType == "assets")
                {
                    pdfView.fromAsset("github_git_cheat_sheet.pdf")
                        .password(null)//enter password if PDF is password protected
                        .defaultPage(0)//set the default page
                        .enableSwipe(true)//enable the swipe to change page
                        .swipeHorizontal(false)//set horizontal swipe to false
                        .enableDoubletap(true)//double tap to zoom
                        .onDraw(object: OnDrawListener {
                            override fun onLayerDrawn(canvas: Canvas, pageWidth:Float, pageHeight:Float, displayedPage:Int) {
                            }
                        })
                        .onDrawAll(object: OnDrawListener {
                            override fun onLayerDrawn(canvas:Canvas, pageWidth:Float, pageHeight:Float, displayedPage:Int) {
                            }
                        })
                        .onPageError(object: OnPageErrorListener {
                            override fun onPageError(page:Int, t:Throwable) {
                                Toast.makeText(this@ViewActivity, "Error", Toast.LENGTH_LONG).show()
                            }
                        })
                        .onPageChange(object: OnPageChangeListener {
                            override fun onPageChanged(page:Int, pageCount:Int) {
                            }
                        })
                        .onTap(object: OnTapListener {
                            override fun onTap(e: MotionEvent):Boolean {
                                return true
                            }
                        })
                        .onRender(object: OnRenderListener {
                            override fun onInitiallyRendered(nbPages:Int, pageWidth:Float, pageHeight:Float) {
                                pdfView.fitToWidth()
                            }
                        })
                        .enableAnnotationRendering(true)
                        .invalidPageColor(Color.WHITE)
                        .load()
                }
            }
        }
    }
}

Finally, run the application on your mobile device and see the output.

From Phone Storage

Now, we will look upon how to open PDF files from the Phone’s storage. Firstly, we have to connect the onClick of Storage button with the ViewActivity. So, in the onCreate of the MainActivtiy.kt file, add the below lines:

btn_open_storage = findViewById(R.id.open_storage)

btn_open_storage.setOnClickListener(object: View.OnClickListener {
    override fun onClick(view:View) {
        val browseStorage = Intent(Intent.ACTION_GET_CONTENT)
        browseStorage.setType("application/pdf")
        browseStorage.addCategory(Intent.CATEGORY_OPENABLE)
        startActivityForResult(Intent.createChooser(browseStorage, "Select PDF"), PICK_PDF_CODE)
    }
})

Also, add the onActivityResult in the MainActivity.kt file:

override protected fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    if (requestCode == PICK_PDF_CODE && requestCode == RESULT_OK && data != null)
    {
        val selectedPdf = data.getData()
        val intent = Intent(this@MainActivity, ViewActivity::class.java)
        intent.putExtra("ViewType", "storage")
        intent.putExtra("FileUri", selectedPdf.toString())
        startActivity(intent)
    }
}

Now, the code for opening PDF file from the device is same as that of opening from the assets folder. All you need to do is instead of using fromAsset, use fromUri. So, the modified code of ViewActivity.kt file is:

if (viewType == "assets") {
    ...
    ...
    //assets code
}
else if (viewType == "storage") {
    val pdfFile = Uri.parse(intent.getStringExtra("FileUri"))
    pdfView.fromUri(pdfFile)
        .password(null)
        .defaultPage(0)
        .enableSwipe(true)
        .swipeHorizontal(false)
        .enableDoubletap(true)
        .onDraw(object: OnDrawListener {
            override fun onLayerDrawn(canvas:Canvas, pageWidth:Float, pageHeight:Float, displayedPage:Int) {
            }
        })
        .onDrawAll(object:OnDrawListener {
            override fun onLayerDrawn(canvas:Canvas, pageWidth:Float, pageHeight:Float, displayedPage:Int) {
            }
        })
        .onPageError(object:OnPageErrorListener {
            override fun onPageError(page:Int, t:Throwable) {
                Toast.makeText(this@ViewActivity, "Error", Toast.LENGTH_LONG).show()
            }
        })
        .onPageChange(object:OnPageChangeListener {
            override fun onPageChanged(page:Int, pageCount:Int) {
            }
        })
        .onTap(object:OnTapListener {
            override fun onTap(e:MotionEvent):Boolean {
                return true
            }
        })
        .onRender(object:OnRenderListener {
            override fun onInitiallyRendered(nbPages:Int, pageWidth:Float, pageHeight:Float) {
                pdfView.fitToWidth()
            }
        })
        .enableAnnotationRendering(true)
        .invalidPageColor(Color.WHITE)
        .load()
}

Now, you can check the output by running your application on your mobile device and select the desired PDF.

PDF from Internet

Lastly, our aim is to view the PDF files from the Internet. We will first download the PDF by using the FileLoader and then use this file to display the PDF on your ViewActivity by using the same process as used for Assets and Storage but here you have to use fromFile() to add display the PDF. Here is the modified code for the ViewActivity.kt file:

if (viewType == "assets") {
    ...
    ...
    //assets code    
}
else if (viewType == "storage") {
    ...
    ...
    //storage code
}
else if (viewType == "internet")
{
    progressBar.visibility = View.VISIBLE
    FileLoader.with(this)
        .load("https://github.github.com/training-kit/downloads/github-git-cheat-sheet.pdf")
        .fromDirectory("PDFFiles", FileLoader.DIR_EXTERNAL_PUBLIC)
        .asFile(object: FileRequestListener<File> {
            override fun onLoad(fileLoadRequest: FileLoadRequest, fileResponse: FileResponse<File>) {
                progressBar.visibility = View.GONE
                val pdfFile = fileResponse.getBody()
                pdfView.fromFile(pdfFile)
                    .password(null)
                    .defaultPage(0)
                    .enableSwipe(true)
                    .swipeHorizontal(false)
                    .enableDoubletap(true)
                    .onDraw(object:OnDrawListener {
                        override fun onLayerDrawn(canvas:Canvas, pageWidth:Float, pageHeight:Float, displayedPage:Int) {
                        }
                    })
                    .onDrawAll(object:OnDrawListener {
                        override fun onLayerDrawn(canvas:Canvas, pageWidth:Float, pageHeight:Float, displayedPage:Int) {
                        }
                    })
                    .onPageError(object:OnPageErrorListener {
                        override fun onPageError(page:Int, t:Throwable) {
                            Toast.makeText(this@ViewActivity, "Error", Toast.LENGTH_LONG).show()
                        }
                    })
                    .onPageChange(object:OnPageChangeListener {
                        override fun onPageChanged(page:Int, pageCount:Int) {
                        }
                    })
                    .onTap(object:OnTapListener {
                        override fun onTap(e:MotionEvent):Boolean {
                            return true
                        }
                    })
                    .onRender(object:OnRenderListener {
                        override fun onInitiallyRendered(nbPages:Int, pageWidth:Float, pageHeight:Float) {
                            pdfView.fitToWidth()
                        }
                    })
                    .enableAnnotationRendering(true)
                    .invalidPageColor(Color.WHITE)
                    .load()
            }
            override fun onError(fileLoadRequest:FileLoadRequest, throwable:Throwable) {
                Toast.makeText(this@ViewActivity, "Error", Toast.LENGTH_LONG).show()
                progressBar.setVisibility(View.GONE)
            }
        })
}

Finally, run the application and try to verify all the three options i.e. assets, storage and internet options to view PDF in Android Application. Try to replace the PDF link used in the above example with your own PDF URL.

Conclusion

In this blog, we learned how to display PDF files in our Android Application. We can do so by using WebView or we can use it by using some existing Library to display PDF files from the assets or from the mobile device or from the internet. Hope you enjoyed this blog.

That’s all for this blog. Keep Learning :)

Team MindOrks!