How to Build an Android PDF Viewer with PSPDFKit Library
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
-
Open Android Studio and select New Project. Then, go to File > New > New Project… to create a new project for your application.
-
Choose the correct template for your project. For this example, use Empty Activity.
-
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.
-
Click Finish to let Android Studio create your project at your preferred save location.
Adding PSPDFKit’s Android PDF Viewer Library to Your Project
-
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/'
}
}
}
-
Add the PSPDFKit dependency in
app/build.gradle
:
dependencies {
implementation("com.pspdfkit:pspdfkit:2024.4.0")
}
dependencies {
implementation("com.pspdfkit:pspdfkit:2024.4.0")
}
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
.
-
Copy a PDF document to the
assets
directory of your Android project — for example, tosrc/main/assets/my-document.pdf
. -
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>
-
Add
PdfActivity
to your app’sAndroidManifest.xml
:
<application> <activity android:name="com.pspdfkit.ui.PdfActivity" android:windowSoftInputMode="adjustNothing" /> </application>
-
You can now start
PdfActivity
with the document from yourassets
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);
-
PdfActivity
will now present the document from yourassets
directory.
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.
-
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);
Learn more about
openFileOutput(String, int)
here.
-
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); } } } } }
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.