Blog Post

How to Sign a PDF on Android with PSPDFKit's Signature Library

Illustration: How to Sign a PDF on Android with PSPDFKit's Signature Library

In this post, you’ll learn how to add electronic and digital signatures to a PDF in your Android application using PSPDFKit’s Android signature library.

This post will also cover the various types of signatures PSPDFKit facilitates. Additionally, it’ll include code examples of adding a signature programmatically and through PSPDFKit’s built-in user interface (UI).

PSPDFKit supports the following signature types:

  • Drawn eSignatures

  • Image eSignatures

  • Typed eSignatures

  • Digital Signatures

PSPDFKit also supports eSigning with a certificate.

Requirements to Get Started

To get started, you’ll need:

Getting Started and Integrating the PSPDFKit Library

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

Creating a New Project

  1. To create a new project for your application, open Android Studio and select New Project. Or, if another project is open, choose File > New > New Project…

Image showing how to create a new project in Android Studio

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

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

  1. When prompted, choose your app name (PSPDFKit Demo) and set the Save location and 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 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 'https://my.pspdfkit.com/maven/'
        }
    }
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
        maven {
            url = uri("https://my.pspdfkit.com/maven")
        }
    }
}
  1. Add the PSPDFKit dependency in app/build.gradle:

dependencies {
    implementation 'com.pspdfkit:pspdfkit:8.4.0'

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

}

Configuring Your Build

PSPDFKit is supported on Android devices running API level 21 and newer and targeting the latest stable Android version 12 (API 31). Furthermore, PSPDFKit requires apps to enable Java 8 language features to build:

android {
    compileSdk 31
    buildToolsVersion '30.0.3'

    defaultConfig {
        applicationId 'com.example.app'
        minSdk 21
        targetSdk 31
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}
android {
    compileSdk = 31
    buildToolsVersion = "30.0.3"

    defaultConfig {
        applicationId = "com.example.app"
        minSdk = 21
        targetSdk = 31
    }

    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }
}

Adding an Android Signature Pad to Accept Signatures

To enable users to sign a document digitally, the document needs to have at least one signature pad. This is a reserved area within a document for digital and electronic signatures.

If your test document doesn’t contain a signature form field, you can create one using PSPDFKit. This is done by defining the index page and the annotation bounding box that will contain the signature form element using the code below:

private fun createSignatureFormField(
    pageIndex: Int,
    left: Float,
    top: Float,
    right: Float,
    bottom: Float,
    formFieldId: String
) {
    val formConfigurationRect = RectF(
        left,
        top,
        right,
        bottom
    )
    val signatureFormConfiguration = SignatureFormConfiguration.Builder(pageIndex, formConfigurationRect)
    .build()

    val signatureFormField = document.formProvider.addFormElementToPage(formFieldId, signatureFormConfiguration)
}

Adding Electronic Signatures Programmatically in Android

Electronic signatures in PSPDFKit are sometimes referred to as signature annotations because they’re modeled using annotations.

To enable eSignature functionality, your license must include either the Annotations component or the Electronic Signatures component.

Signatures can be ink or image annotations with the isSignature property set to true. To programmatically create signatures, you can create instances of InkAnnotation or StampAnnotation, call setIsSignature(true) on them, and add them to a document via PdfFragment#addAnnotationToPage().

  1. To create an ink signature:

val pdfFragment: PdfFragment = ...

// Create the ink annotation.
val annotation = InkAnnotation(pageIndex)

// Set the line color and width.
annotation.color = Color.RED
annotation.lineWidth = 3f

// Set the stroke data. For example, this would be loaded from user input on another device.
// This example code is just hardcoding a stroke with three points.
val line = listOf(
    PointF(100f, 100f),
    PointF(150f, 150f),
    PointF(200f, 100f)
)
annotation.lines = listOf(line)

// Mark this ink annotation as a signature.
annotation.setIsSignature(true)

// Add it to the page.
pdfFragment.addAnnotationToPage(annotation, false)
  1. To create an image signature:

val pdfFragment: PdfFragment = ...
val bitmap = BitmapFactory.decodeFile("my-signature.png")

// Create the image annotation.
val annotation = StampAnnotation(pageIndex, RectF(50f, 440.0f, 500f, 0.0f), bitmap)

// Mark this image annotation as a signature.
annotation.setIsSignature(true)

// Add it to the page.
pdfFragment.addAnnotationToPage(annotation, false)

Adding Electronic Signatures through the UI

There are two ways to add electronic signatures via the UI.

  • With a signature form field

You can bring up the signature creation modal view by tapping a signature form field in the document if you’re using PSPDFKit with forms.

  • Without a signature form field

If your license includes Annotations, the signature tool can be found with the other annotation tools, as shown in image below.

Image showing the signature tool in the annotation toolbar

If this isn’t the case, you’ll only be able to create, move, resize, and delete signature annotations, but not modify them.

The signature tool can also be added using forceSignatureButtonPositionInMainToolbar in the PdfActivityConfiguration.Builder, like so:

Image showing the signature tool in the main toolbar

The signature creation modal view offers the options for signatures outlined below.

  1. Draw

Drawn eSignatures are similar to paper-based signatures, and they’re especially suited to using a touchscreen and stylus.

Image showing a drawn eSignature

Drawn eSignatures let the user choose between the following inks:

  • Black — #000000

  • Palatinate Blue — #4636e3

  • Blue (Crayola) — #2972ff

  1. Image

The image option lets the user snap a picture or scan a signature on paper. It also allows users to select an existing image from their gallery.

Image showing an eSignature taken from an image

  1. Typed

The type option allows users to enter their name and select a signature style. It’s compatible with screen readers such as VoiceOver, TalkBack, NVDA, and JAWS, as well as other accessibility technologies like Switch Control on macOS and iOS.

Image showing a typed eSignature

Like drawn eSignatures, typed eSignatures also let the user choose between three inks:

  • Black — #000000

  • Palatinate Blue — #4636e3

  • Blue (Crayola) — #2972ff

Adding Digital Signatures to PDFs in Android

Digital signatures are signed with a certificate, which we cover in depth in our generating a digital certificate guide. For demonstration purposes, this next section uses a self-signed certificate.

Download the test certificate and place it in the android_assets folder.

Since you’re using a self-signed certificate, you need to add it to a trusted certificate store for it to validate. Since PSPDFKit and other readers (like Acrobat) will warn when using self-signed certificates, your app should use a CA-issued certificate instead.

To add a digital signature, do the following:

private fun addJohnAppleseedCertificateToTrustedCertificates(context: Context) {
    try {
        val keystoreFile = context.assets.open("JohnAppleseed.p12")
        // Inside a p12, we have both the certificate and private key used for signing. We just
        // need the certificate here. Proper signatures should have a root CA-approved
        // certificate, making this step unnecessary.
        val key = SignatureManager.loadPrivateKeyPairFromStream(keystoreFile, "test", null, null)
        if (key.certificate.type == "X.509") {
            SignatureManager.addTrustedCertificate((key.certificate as X509Certificate))
        }
    } catch (e: Exception) {
        // Handle exception here.
    }
}

After adding the self-signed certificate to the trusted certificate store, you can sign the document like so:

private fun signDocument(context: Context, assetName: String): Uri {
    val outputFile = File(context.filesDir, "signedDocument.pdf")

    // The signer is a named entity holding a certificate (usually a person) and has a display
    // name shown in the app.
    val signer = Pkcs12Signer(
        "John Appleseed",
        Uri.parse("file:///android_asset/JohnAppleseed.p12")
    )

    // Provide a password to the signer, which will be used to unlock its private key.
    signer.unlockPrivateKeyWithPassword("test")
    val unsignedDocument = PdfDocumentLoader.openDocument(context, DocumentSource(AssetDataProvider(assetName)))
    val signatureFormFields = unsignedDocument.documentSignatureInfo.signatureFormFields
    check(signatureFormFields.isNotEmpty()) { "No signature form element found in document '$assetName'" }
    val signerOptions = SignerOptions.Builder(signatureFormFields[0], FileOutputStream(outputFile)).build()
    signer.signFormFieldAsync(signerOptions).blockingAwait()
    return Uri.fromFile(outputFile)
}

The above function signs and returns a URI to the document. You can load and show the document with the following:

val intent = PdfActivityIntentBuilder.fromUri(context, signedDocument)
            .configuration(configuration.build())
            .build()
context.startActivity(intent)

Expanding the Capabilities of Your Android App with PSPDFKit

PSPDFKit also supports the following:

They’re beyond the scope of this post, but you can read more if you’re interested.

Conclusion

In this post, you learned how to add electronic and digital signatures to a document using the PSPDFKit library on Android. You also had an overview of the various types of electronic signatures supported by PSPDFKit. 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.

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

Related Articles

Explore more
DEVELOPMENT  |  Android • Jetpack Compose

How to Implement Drag-to-Reorder List Functionality with Jetpack Compose

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