Blog Post

How to Build an Android PDF Viewer with PSPDFKit Library

Teja Tatimatla
Jonathan D. Rhyne
Illustration: How to Build an Android PDF Viewer with PSPDFKit Library
Information

This article was first published in August 2022 and was updated in June 2024.

In this post, you’ll learn how to use PSPDFKit’s library to build a PDF viewer for your Android application.

With more than 3 billion active devices, Android is one of the most widely used mobile operating systems. If your Android application has a use case for opening and viewing PDF documents, a PDF viewer is just what you need.

To get started, you’ll begin by setting up a new Android Studio project and opening a document from the android-assets folder. Then, you’ll learn how to open a document from your device’s local storage.

What Is an Android PDF Viewer?

An Android PDF viewer allows you to render and display PDF documents inside your app without your users needing to download them or use an external application like a PDF reader. You can build one from scratch, or you can save dev time by deploying a commercial Android PDF viewer library, like the one PSPDFKit offers.

PSPDFKit Android PDF Viewer Library

PSPDFKit’s Android PDF viewer library uses a high-fidelity, reliable, PDFium-based rendering engine that’s fast, precise, and feature rich. It enables you to quickly and painlessly embed a fully configurable PDF viewer in your Android application.

PSPDFKit SDKs are deployed in some of the world’s most popular applications, including Autodesk, Disney, Dropbox, IBM, and Lufthansa.

Key capabilities include:

  • A customizable UI — Hide or add buttons, and match your look and feel.

  • 30+ features — Easily add features like PDF editing, digital signatures, form filling, real-time document collaboration, and more.

  • Dedicated support — Deploy faster by working 1-on-1 with our developers.

  • Page modes and transition — Use single or double page modes and multiple scroll modes.

  • Outline — Supports all custom variants and PDF action types.

  • Bookmarks — Users can add, remove, and sort bookmarks.

  • Reader view — Reflow text to present it in a single-column view.

  • PNG and JPG — Open images in the viewer (in addition to PDFs).

You can view our demo to see what PSPDFKit is capable of and determine how you can use it for your project.

Requirements

To get started, you’ll need:

  • Android Studio — The official integrated development environment for Android

Getting Started with PSPDFKit

The next few sections will walk you through the getting started process.

Creating a New Project

  1. Open Android Studio and select New Project. Then, go to File > New > New Project… to create a new project for your application.

Image showing how to create a new project in Android Studio

  1. Choose the correct template for your project. For this example, use Empty Activity.

Image showing a menu in Android Studio that lets user choose an activity

  1. When prompted, choose your app name (PSPDFKit Demo) and set the Save location and Build configuration language to your choice. Set the Minimum SDK to API 21.

Image showing a wizard for project setup

  1. Click Finish to let Android Studio create your project at your preferred save location.

Adding PSPDFKit’s Android PDF Viewer Library to Your Project

  1. Add the PSPDFKit Maven repository in settings.gradle, which is located at the root of your project:

dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
        maven {
            url = uri("https://my.pspdfkit.com/maven")
        }
    }
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
        maven {
            'https://my.pspdfkit.com/maven/'
        }
    }
}
  1. Add the PSPDFKit dependency in app/build.gradle:

dependencies {
    	implementation("com.pspdfkit:pspdfkit:2024.3.1")
}
dependencies {
   implementation("com.pspdfkit:pspdfkit:2024.3.1")
}

Displaying a PDF Using PSPDFKit’s Android PDF Viewer Library

To verify that PSPDFKit is successfully integrated into your application, open a PDF file with the ready-to-use PdfActivity.

  1. Copy a PDF document to the assets directory of your Android project — for example, to src/main/assets/my-document.pdf.

  2. Optional— If you have a trial key or license key, add it to your AndroidManifest.xml. Otherwise, skip this step:

<application>
    <meta-data
        android:name="pspdfkit_license_key"
        android:value="YOUR_LICENSE_KEY_GOES_HERE" />

    ...
</application>
  1. Add PdfActivity to your app’s AndroidManifest.xml:

<application>
    <activity
        android:name="com.pspdfkit.ui.PdfActivity"
        android:windowSoftInputMode="adjustNothing" />
</application>
  1. You can now start PdfActivity with the document from your assets directory:

val uri = Uri.parse("file:///android_asset/my-document.pdf")
val config = PdfActivityConfiguration.Builder(context).build()
PdfActivity.showDocument(this, uri, config)
final Uri uri = Uri.parse("file:///android_asset/my-document.pdf");
final PdfActivityConfiguration config = new PdfActivityConfiguration.Builder(context).build();
PdfActivity.showDocument(this, uri, config);
  1. PdfActivity will now present the document from your assets directory.

GIF showing the application running on the Android emulator

Information

This is a simple demonstration using the android_assets folder. This folder is a read-only directory that, during the build process, gets built into the .apk file in most Android applications. For more information on its use, refer to the following section.

Opening a Local PDF File on Android

In this section, you’ll display a PDF file from the device’s local storage. But before starting, it’s important to understand local storage.

The Android system provides two types of physical storage locations:

  • Internal storage, which is smaller and is always available.

  • External storage, which is usually larger than internal storage and might not always be available. This is why you need to ensure your application is able to handle opening files from both internal and external storage.

Opening a PDF from App-Specific Storage

Absolute paths must never be hardcoded. Directories where your app stores files aren’t guaranteed to be stable between different devices or even between app restarts. As such, we recommend using methods from Context to access different special file system directories.

  1. Internal Storage

Use the getFilesDir method from Context to get the path to the file system directory where your internal files are stored:

// This will fail if "my-document.pdf" isn't created in
// advance using `openFileOutput(String, int)`.

val uri = Uri.parse(getFilesDir() + "my-document.pdf")
val config = PdfActivityConfiguration.Builder(context).build()
PdfActivity.showDocument(this, uri, config)
// This will fail if "my-document.pdf" isn't created in
// advance using `openFileOutput(String, int)`.

final Uri uri = Uri.parse(getFilesDir() + "my-document.pdf");
final PdfActivityConfiguration config = new PdfActivityConfiguration.Builder(context).build();
PdfActivity.showDocument(this, uri, config);
Information

Learn more about openFileOutput(String, int) here.

  1. External Storage

Use Context#getExternalFilesDir(null) to access the directory that the system provides for your app on external storage:

// This will fail if external storage is not mounted correctly
// or if "my-document.pdf" isn't present in the directory.
// returned by getExternalFilesDir(null)

val uri = Uri.parse(getExternalFilesDir(null) + "my-document.pdf")
val config = PdfActivityConfiguration.Builder(context).build()
PdfActivity.showDocument(this, uri, config)
// This will fail if external storage is not mounted correctly
// or if "my-document.pdf" isn't present in the directory.
// returned by getExternalFilesDir(null)

final Uri uri = Uri.parse(getExternalFilesDir(null) + "my-document.pdf");
final PdfActivityConfiguration config = new PdfActivityConfiguration.Builder(context).build();
PdfActivity.showDocument(this, uri, config);

Opening a PDF from Shared Storage

As the name suggests, shared storage is shared between all the applications running on a device. Shared storage directories and their data aren’t affected by a particular app’s uninstall.

The recommended method for accessing shared storage is through the Storage Access Framework (SAF). According to the documentation, “the SAF makes it simple for users to browse and open documents, images, and other files across all of their preferred document storage providers. A standard, easy-to-use UI lets users browse files and access recents in a consistent way across apps and providers.”

To open a PDF, invoke the ACTION_OPEN_DOCUMENT intent as follows:

package com.example.yourappid; // Replace with your actual app ID or package name.

import android.app.Activity
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.enableEdgeToEdge
import androidx.activity.result.ActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import com.pspdfkit.configuration.activity.PdfActivityConfiguration
import com.pspdfkit.ui.PdfActivity

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()

        val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply{
            addCategory(Intent.CATEGORY_OPENABLE)
            type = "application/pdf"
        }

        registerForActivityResult(ActivityResultContracts.StartActivityForResult()){ result ->
            onDone(result)
        }.launch(intent)

    }

    private fun onDone(result: ActivityResult){
        if(result.resultCode == Activity.RESULT_OK) {
            val resultData = result.data
            resultData?.data?.also { uri ->
                val documentUri = Uri.parse(uri.toString())
                val config = PdfActivityConfiguration.Builder(this).build()
                PdfActivity.showDocument(this, documentUri, config)

            }
        }
    }
}
package com.example.yourappid; // Replace with your actual app ID or package name,

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import androidx.activity.ComponentActivity;
import androidx.activity.result.ActivityResult;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import com.pspdfkit.configuration.activity.PdfActivityConfiguration;
import com.pspdfkit.ui.PdfActivity;

public class MainActivity extends AppCompatActivity {

    private ActivityResultLauncher<Intent> launcher;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        launcher = registerForActivityResult(
                new ActivityResultContracts.StartActivityForResult(),
                this::onDone);

        Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.setType("application/pdf");

        launcher.launch(intent);

    }

    private void onDone(ActivityResult result) {
        if (result.getResultCode() == Activity.RESULT_OK) {
            Intent resultData = result.getData();
            if (resultData != null) {
                Uri uri = resultData.getData();
                if (uri != null) {
                    Uri documentUri = Uri.parse(uri.toString());
                    PdfActivityConfiguration config = new PdfActivityConfiguration.Builder(this).build();
                    PdfActivity.showDocument(this, documentUri, config);
                }
            }
        }
    }
}

GIF showing the application running on the Android emulator

Information

Since the user is browsing and selecting the document through a file picker, they’re completely aware of what files your app has access to. Hence, your application doesn’t need to ask for runtime permissions.

Beyond Local Storage

PSPDFKit’s Android library isn’t just limited to opening and manipulating documents from local storage. PSPDFKit can also open documents:

  • From remote storage

  • From PSPDFKit Server

  • From a custom data provider

  • That are password protected

To learn more about opening PDF documents in Android apps, refer to our related blog post.

FAQ

This section covers some frequently asked questions and other information related to the topic of PDF viewers on Android.

What Is an Intent in Android?

Intents are messages you pass to the Android OS. They describe actions you want the system to perform on your behalf. After describing an intent, you pass it to the OS and act on the result. Usually, the result is passed to a callback function.

What’s a Request Code Used for in Android?

In Android, request codes help identify intents and their corresponding results. The best place to declare a request code is in a separate file that holds all your constants.

More about PdfActivity

PdfActivity is a public class that extends AppCompactActivity and implements PdfUi, PdfActivityListener, and PdfActivityComponentsApi. It’s an activity with fully integrated views and behavior, and it can be invoked by the simple helper methods showDocument and showImage.

More about the showDocument Helper Method

The showDocument(Context context, Uri documentUri, PdfActivityConfiguration configuration) helper method opens a new PdfActivity displaying a passed document. If the document is password protected, PSPDFKit will prompt the user to enter the password. If you want to supply the password programmatically, use the showDocument(Context context, Uri documentUri, String password PdfActivityConfiguration configuration) method overload, which has been documented here.

Conclusion

This post demonstrated how to integrate PSPDFKit’s Android PDF viewer library into an Android application and present a PDF document from local directories. If you hit any snags, don’t hesitate to reach out to our Support team for help.

At PSPDFKit, we offer a commercial, feature-rich, and completely customizable Android PDF library that’s easy to integrate and comes with well-documented APIs to handle advanced use cases. Try it for free, or visit our demo to see it in action.

Author
Jonathan D. Rhyne Co-Founder and CEO

Jonathan joined PSPDFKit in 2014. As CEO, Jonathan defines the company’s vision and strategic goals, bolsters the team culture, and steers product direction. When he’s not working, he enjoys being a dad, photography, and soccer.

Related Products
Share Post
Free 60-Day Trial Try PSPDFKit in your app today.
Free Trial

Related Articles

Explore more
DEVELOPMENT  |  iOS • Android • Room • Kotlin Multiplatform • Tips

Seamless Room Database Integration for Kotlin Multiplatform Projects

PRODUCTS  |  Android • Releases

Android 2024.1 Update: Advanced Content Editing and Digital Signatures, Plus Expanded Jetpack Compose Support

TUTORIALS  |  Android • How To

How to Persist Zoom While Scrolling through a Document Using the PSPDFKit Android Library