Open a PDF File from Document Engine on Android

Document Engine is an optional backend for PSPDFKit for Android that powers our Instant synchronization component for syncing annotations across users and devices.

This guide will give you an overview of the Instant API and how to use it for displaying documents from the server, in addition to talking about the lifecycle documents go through while being displayed.

API Overview

The entry class into Instant is InstantClient. This represents a connection to your PSPDFKit Server. An app typically creates one InstantClient, although it could create several to connect to multiple PSPDFKit Server instances.

Instant manages downloading and storing PDF files when your app requests this. Each PDF file managed by Instant is identified by its documentId and can have one or more named layers. Each layer represents a separate set of annotations displayed on top of the base document and is identified by its name.

In your app, each Instant layer is represented by an InstantDocumentDescriptor instance that can be created by calling getInstantDocumentDescriptorForJwt() on an InstantClient. For each document layer, your app must obtain a JSON Web Token (JWT) from your server.

A document descriptor may be used to request downloading the associated PDF file and all annotations in the layer. Once that has finished, an InstantPdfDocument may be created. Set this document on an InstantPdfFragment or InstantPdfActivity and then show it to the user. Changes to annotations will be synchronized for all users viewing the same document.

InstantPdfFragment is a subclass of PdfFragment, just as InstantPdfActivity is a subclass of PdfActivity, and both can be used to show only InstantPdfDocument. Trying to display a PdfDocument instance will result in an exception being thrown. Conversely, showing a PdfDocument created by Instant in any activity or fragment not subclassing InstantPdfActivity or InstantPdfFragment, respectively, is not supported.

Document Lifecycle

When using a document managed by Instant, you might go through these stages:

  • Obtaining a document identifier from your server

  • Obtaining a document descriptor

  • Downloading the document

  • Showing the document and synchronizing annotations

  • Updating the authentication token to keep synchronizing annotations

  • Losing access to the document

  • Clearing local storage

Usage in Detail

After signing in to your server and finding out the identifier of the document you want to show to the user, you can start downloading and opening the document. You need to obtain a JWT from your server for this document and then use this JWT to start the download:

val serverUrl = "location of your Document Engine here"
val jwt = "some JWT from your server identifying document layer"

// Downloads and opens the document layer encoded by the JWT.
InstantClient.create(context, serverUrl).openDocumentAsync(jwt).subscribe(...)
String serverUrl = "location of your Document Engine here";
val jwt = "some JWT from your server identifying document layer"

// Downloads and opens the document layer encoded by the JWT.
InstantClient.create(context, serverUrl).openDocumentAsync(jwt).subscribe(...);

For showing a document and synchronizing annotations, create an InstantPdfFragment or an InstantPdfActivity by using their static create methods and displaying them to the user:

val activity = InstantPdfActivity.showInstantDocument(context, serverUrl, jwt, configuration)
// Show activity, for example: `startActivity(activity)`.

val fragment = InstantPdfFragment.newInstance(serverUrl, jwt, configuration)
// Display a fragment inside your layout.
InstantPdfActivity activity = InstantPdfActivity.showInstantDocument(context, serverUrl, jwt, configuration);
// Show activity, for example: `startActivity(activity)`.

InstantPdfFragment fragment = InstantPdfFragment.newInstance(serverUrl, jwt, configuration);
// Display a fragment inside your layout.

Instant doesn’t persist JWTs, and the JWTs have an expiration date. When a new JWT is needed for a document, the error will be thrown with InstantErrorCode.AUTHENTICATION_FAILED. In that case, you have to update the JWT on the opened document via InstantPdfDocument#reauthenticateWithJwt(token).

Your app might find out that a user no longer has access to a document from your server or from the Document Engine. If your app finds the user has lost access to the document, you’ll probably want to stop showing the document and clear the local storage via pdfDocument.getDocumentDescriptor().removeLocalStorage().