In order to let users view PDF documents in an Android app, it's common practice to defer this functionality to a third-party app on the user’s device. By doing so, developers won't have to build their own PDF viewer from scratch, however this isn't always the best solution. What if you want to view PDF documents directly in your app? Luckily, the Android SDK provides classes to handle PDF documents in apps running Android 5.0 or higher.

In this blog post, we’ll use PdfRenderer from the android.graphics.pdf package to create a basic PDF viewer in your Android app. Then, we'll see how easy it is to implement a document viewer using the PDFTron SDK. Here are a few steps to get you started.

For reference, the sample code for this post can be found at Github.

linkView a PDF using the Android SDK

To keep things simple, we're going to view a PDF file stored in the raw resource folder (i.e. res/raw/sample.pdf). Your app will also need to set the minimum API level to 21 (Android 5.0).

  1. Add PdfRenderer and PdfRenderer.Page member variables to your activity so that we can clean them up later. You'll also need to add an ImageView to your activity in order to display the PDF:

    // ...
    private PdfRenderer mPdfRenderer;
    private PdfRenderer.Page mPdfPage;
    private ImageView mImageView;
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mPdfPage != null) {
            mPdfPage.close();
        }
        if (mPdfRenderer != null) {
            mPdfRenderer.close();
        }
    }
  2. In order for PdfRenderer to handle PDFs from the res/raw folder, we'll need to copy the file and cache it locally. Add this method to your activity:

    // Copies the resource PDF file locally so that PdfRenderer can handle the file
    void copyToLocalCache(File outputFile, @RawRes int pdfResource) throws IOException {
        if (!outputFile.exists()) {
            InputStream input = getResources().openRawResource(pdfResource);
            FileOutputStream output;
            output = new FileOutputStream(outputFile);
            byte[] buffer = new byte[1024];
            int size;
            // Just copy the entire contents of the file
            while ((size = input.read(buffer)) != -1) {
                output.write(buffer, 0, size);
            }
            input.close();
            output.close();
        }
    }
  3. Then you can display a page from your PDF by loading it to an ImageView as a bitmap:

    // Display a page from the PDF on an ImageView
    void openPdfWithAndroidSDK(ImageView imageView, int pageNumber) throws IOException {
        // Copy sample.pdf from 'res/raw' folder into local cache so PdfRenderer can handle it
        File fileCopy = new File(getCacheDir(), FILE_NAME);
        copyToLocalCache(fileCopy, R.raw.sample);
    
        // We will get a page from the PDF file by calling openPage
        ParcelFileDescriptor fileDescriptor =
                ParcelFileDescriptor.open(fileCopy,
                        ParcelFileDescriptor.MODE_READ_ONLY);
        mPdfRenderer = new PdfRenderer(fileDescriptor);
        mPdfPage = mPdfRenderer.openPage(pageNumber);
    
        // Create a new bitmap and render the page contents on to it
        Bitmap bitmap = Bitmap.createBitmap(mPdfPage.getWidth(),
                mPdfPage.getHeight(),
                Bitmap.Config.ARGB_8888);
        mPdfPage.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);
    
        // Set the bitmap in the ImageView so we can view it
        imageView.setImageBitmap(bitmap);
    }

The sample above will look something like this:

As you can see, using PdfRenderer is an easy way to create a simple single-page PDF viewer in your Android app. However if you need users to interact with a PDF document, then I'm afraid you're out of luck. The Android SDK does not provide any basic UI controls for PDF viewing like page zooming and scrolling, and PdfRenderer only supports opening one page at a time - you'll need to write your own UI to handle user interaction and multi-page documents.

Additionally, PdfRenderer does not support password-protected or encrypted files, and uses PDFium for rendering which only works well with simple documents. You could run in to some rendering inconsistencies or failures when working with more complex or unsupported PDF documents. For a more stable and interactive viewing experience you'll have to look elsewhere for a solution.

Fortunately, PDFTron's Android PDF SDK comes with a fully-featured document viewer that includes these basic controls in addition to features such as:

  • Annotation creation and editing
  • Form filling
  • Office file viewing and conversion (including .doc, .docx, .xlsx, .pptx formats)
  • Page manipulation
  • Reflow
  • Custom viewing modes
  • and more!

Also it's easy as pie to integrate with your Android app, here's how!

linkView a PDF using PDFTron

If you do not already have a PDFTron license key, you can sign-up for a free trial key. Afterwards, add the PDFTron Gradle dependency to you Android project.

  1. We'll be using DocumentActivity as our PDF viewer. Set up this activity as described in this short guide.

  2. From your main activity, open the PDF document in DocumentActivity by calling:

    // Open the document 'res/raw/sample.pdf' in DocumentActivity
    DocumentActivity.openDocument(this, R.raw.sample);

That's it! You now have a fully-featured document viewer in your Android app.

Out of the box, PDFTron provides an interactive document viewer that can be easily integrated into existing Android apps with dozens of features, giving users a better document viewing experience. What's even better is that it's highly customizable, allowing for feature customization and UI theming to fit all use-cases.

If you have any questions about PDFTron's Android PDF SDK, please feel free to get in touch!

You can find the source code for this blog post at Github.