---
title: "Document Processing"
canonical_url: "https://www.nutrient.io/guides/android/samples/document-processing-kotlin/"
md_url: "https://www.nutrient.io/guides/android/samples/document-processing-kotlin.md"
last_updated: "2025-07-02T00:00:00.000Z"
description: "Process PDFs with PdfProcessor to rotate, flatten, remove pages, and more."
---

# Document Processing

Process PDFs with PdfProcessor to rotate, flatten, remove pages, and more.

[Get Started](https://www.nutrient.io/sdk/android/getting-started.md)

[All Samples](https://www.nutrient.io/guides/android/samples.md)

[Download](https://www.nutrient.io/guides/android/downloads.md)

[Launch Demo](https://www.nutrient.io/demo/)

---

```kotlin

/*
 *   Copyright © 2020-2026 PSPDFKit GmbH. All rights reserved.
 *
 *   The PSPDFKit Sample applications are licensed with a modified BSD license.
 *   Please see License for details. This notice may not be removed from this file.
 */

// We're temporarily suppressing the ProgressDialog being deprecated warning.
// Issue: https://github.com/PSPDFKit/PSPDFKit/issues/32215
@file:Suppress("DEPRECATION")

package com.pspdfkit.catalog.examples.kotlin

import android.app.AlertDialog
import android.app.ProgressDialog
import android.content.Context
import android.graphics.BitmapFactory
import android.graphics.Color
import android.net.Uri
import android.util.Log
import android.view.Menu
import android.view.MenuItem
import com.pspdfkit.annotations.AnnotationType
import com.pspdfkit.catalog.R
import com.pspdfkit.catalog.SdkExample
import com.pspdfkit.catalog.SdkExample.Companion.TAG
import com.pspdfkit.catalog.tasks.ExtractAssetTask
import com.pspdfkit.configuration.activity.PdfActivityConfiguration
import com.pspdfkit.document.processor.NewPage
import com.pspdfkit.document.processor.PageImage
import com.pspdfkit.document.processor.PagePattern
import com.pspdfkit.document.processor.PagePosition
import com.pspdfkit.document.processor.PdfProcessor
import com.pspdfkit.document.processor.PdfProcessor.ProcessorProgress
import com.pspdfkit.document.processor.PdfProcessorTask
import com.pspdfkit.ui.PdfActivity
import com.pspdfkit.ui.PdfActivityIntentBuilder
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.schedulers.Schedulers
import io.reactivex.rxjava3.subscribers.DisposableSubscriber
import java.io.File
import java.io.IOException
import java.util.HashSet
import kotlin.math.ceil

/**
 * This example shows how to use the [PdfProcessor] to split a document, remove annotations from
 * the document, and flatten annotations on a document.
 */
class DocumentProcessingExample(context: Context) :
    SdkExample(context, R.string.documentProcessingExampleTitle, R.string.documentProcessingExampleDescription) {
    override fun launchExample(context: Context, configuration: PdfActivityConfiguration.Builder) {
        // This example uses a custom activity which showcases several document processing features.
        // For the sake of simplicity, deactivate actions in the processing activity.
        configuration.annotationListEnabled(false).searchEnabled(false).outlineEnabled(false).thumbnailGridEnabled(false)

        // First extract the example document from the assets.
        ExtractAssetTask.extract(ANNOTATIONS_EXAMPLE, title, context) { documentFile ->
            // This example opens up a compound document, by providing the extracted document twice.
            // This is just an example of how you can merge two, or more documents.
            val documentUri1 = Uri.fromFile(documentFile)
            val documentUri2 = Uri.fromFile(documentFile)

            // To start the DocumentProcessingExampleActivity create a launch intent using the builder.
            val intent =
                PdfActivityIntentBuilder.fromUri(context, documentUri1, documentUri2).configuration(configuration.build()).activityClass(DocumentProcessingExampleActivity::class).build()
            context.startActivity(intent)
        }
    }
}

/**
 * This activity uses the [PdfProcessor] to split a document, removing annotations from the document, and flatten annotation
 * on a document.
 */
class DocumentProcessingExampleActivity : PdfActivity() {
    private val disposables = CompositeDisposable()

    /**
     * Creates menu items that will trigger document processing.
     */
    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        super.onCreateOptionsMenu(menu)
        // This will add actions for all document processing examples provided by this activity.
        menuInflater.inflate(R.menu.processor_example, menu)
        return true
    }

    /**
     * Triggered by selecting an action from the overflow menu in the action bar.
     */
    override fun onOptionsItemSelected(item: MenuItem): Boolean = when (item.itemId) {
        R.id.item_extract_range -> {
            createDocumentFromRange()
            true
        }

        R.id.item_flatten_annotations -> {
            createFlattenedDocument()
            true
        }

        R.id.item_remove_link_annotations -> {
            createDocumentWithoutLinkAnnotations()
            true
        }

        R.id.item_rotate_pages -> {
            createDocumentWithRotatedPages()
            true
        }

        R.id.item_new_page -> {
            createDocumentWithNewPages()
            true
        }

        else -> {
            super.onOptionsItemSelected(item)
        }
    }

    private fun createDocumentFromRange() {
        val document = document?: return

        // Define the output file. This example writes to the internal app directory, into a file based on the document's Uid.
        val outputFile = File(filesDir, document.uid + "-range.pdf")

        // Extract pages with indexes 1, 2, 3, 5, 6, 14. All other pages won't be copied.
        val task =
            PdfProcessorTask.fromDocument(document).removePages(HashSet(listOf(0, 4, 7, 8, 9, 10, 11, 12, 13)))

        // Start document processing, but without annotation flattening.
        PdfProcessor.processDocumentAsync(task, outputFile)
            // Drop update events to avoid back pressure on slow devices..onBackpressureDrop().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(ProcessorProgressHandler("Extracting pages.", outputFile))
    }

    private fun createFlattenedDocument() {
        // Define the output file. This example writes to the internal app directory, into a file based on the document's Uid.
        val document = document
        val outputFile = File(filesDir, document!!.uid + "-flattened.pdf")

        // Start document processing, requesting a flattening of all annotations.
        val task =
            PdfProcessorTask.fromDocument(document).changeAllAnnotations(PdfProcessorTask.AnnotationProcessingMode.FLATTEN)

        PdfProcessor.processDocumentAsync(task, outputFile)
            // Drop update events to avoid back pressure on slow devices..onBackpressureDrop().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(ProcessorProgressHandler("Flattening annotations.", outputFile))
    }

    private fun createDocumentWithoutLinkAnnotations() {
        val document = document?: return

        // Define the output file. This example writes to the internal app directory, into a file based on the document's Uid.
        val outputFile = File(filesDir, document.uid + "-without-link-annotations.pdf")

        // Start document processing, requesting a flattening of all annotations.
        val task =
            PdfProcessorTask.fromDocument(document).changeAnnotationsOfType(AnnotationType.LINK, PdfProcessorTask.AnnotationProcessingMode.DELETE)

        PdfProcessor.processDocumentAsync(task, outputFile)
            // Drop update events to avoid back pressure on slow devices..onBackpressureDrop().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(ProcessorProgressHandler("Removing link annotations.", outputFile))
    }

    private fun createDocumentWithRotatedPages() {
        val document = document?: return

        // Define the output file. This example writes to the internal app directory, into a file based on the document's Uid.
        val outputFile = File(filesDir, document.uid + "-rotated.pdf")

        // Rotate all pages of the document by 90°.
        val task = PdfProcessorTask.fromDocument(document)
        var pageIndex = 0
        val pageCount = document.pageCount
        while (pageIndex < pageCount) {
            task.rotatePage(pageIndex, 90)
            pageIndex++
        }

        // Start document processing.
        PdfProcessor.processDocumentAsync(task, outputFile)
            // Drop update events to avoid back pressure on slow devices..onBackpressureDrop().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(ProcessorProgressHandler("Rotating pages.", outputFile))
    }

    private fun createDocumentWithNewPages() {
        val document = document?: return

        // Define the output file. This example writes to the internal app directory, into a file based on the document's Uid.
        val outputFile = File(filesDir, document.uid + "-new-page.pdf")

        // Create a yellow A5 page with a line pattern as first page.
        val task = PdfProcessorTask.fromDocument(document)
        task.addNewPage(
            NewPage.patternPage(NewPage.PAGE_SIZE_A5, PagePattern.LINES_7MM).backgroundColor(Color.rgb(241, 236, 121)).build(),
            0,
        )

        // Create an A0 page with an image as second page.
        try {
            val bitmap = BitmapFactory.decodeStream(assets.open("media/images/cover.jpg"))
            task.addNewPage(
                NewPage.emptyPage(NewPage.PAGE_SIZE_A0).withPageItem(PageImage(bitmap, PagePosition.CENTER)).build(),
                1,
            )
        } catch (e: IOException) {
            Log.e(TAG, "Could not read page image.")
        }

        // The third page is cloned from the last page of the document, but rotated by 90°.
        task.addNewPage(
            NewPage.fromPage(document, document.pageCount - 1).rotation(90).build(),
            2,
        )

        // Start document processing.
        PdfProcessor.processDocumentAsync(task, outputFile)
            // Drop update events to avoid back pressure on slow devices..onBackpressureDrop().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(ProcessorProgressHandler("Creating new pages.", outputFile))
    }

    override fun onStop() {
        super.onStop()
        // Dispose all active disposables when activity goes to background.
        disposables.clear()
    }

    private fun showProcessedDocument(processedDocumentFile: File) {
        val context = this@DocumentProcessingExampleActivity
        val intent =
            PdfActivityIntentBuilder.fromUri(context, Uri.fromFile(processedDocumentFile)).configuration(configuration).build()
        startActivity(intent)
    }

    /**
     * Helper class for showing a progress dialog and opening the processed document.
     */
    @Suppress("DEPRECATION")
    private inner class ProcessorProgressHandler(progressMessage: String, private val outputFile: File) :
        DisposableSubscriber<ProcessorProgress>() {
        private val progressDialog: ProgressDialog =
            ProgressDialog.show(
                this@DocumentProcessingExampleActivity,
                "Processing document",
                progressMessage,
                false,
                true,
            ) { cancel() }

        init {
            disposables.add(this)
        }

        override fun onNext(processorProgress: ProcessorProgress) {
            progressDialog.progress = ceil((processorProgress.pagesProcessed / processorProgress.totalPages).toDouble()).toInt()
        }

        override fun onError(e: Throwable) {
            AlertDialog.Builder(this@DocumentProcessingExampleActivity).setMessage("Error while processing file: " + e.localizedMessage).show()
            progressDialog.dismiss()
        }

        override fun onComplete() {
            showProcessedDocument(outputFile)
            progressDialog.dismiss()
        }
    }

    companion object {
    }
}

```

This code sample is an example that illustrates how to use our SDK. Please adapt it to your specific use case.

---

## Related pages

- [Add LTV to Existing Signature](/guides/android/samples/add-ltv-to-existing-signature-kotlin.md)
- [AES Encrypted File](/guides/android/samples/aes-encrypted-file-java.md)
- [AI Assistant (Multiple Documents, Compose)](/guides/android/samples/ai-assistant-multiple-documents-compose-kotlin.md)
- [AI Assistant (Multiple Documents, ViewPager)](/guides/android/samples/ai-assistant-multiple-documents-viewpager-kotlin.md)
- [AI Assistant (Single Document)](/guides/android/samples/ai-assistant-single-document-kotlin.md)
- [Annotation Configuration](/guides/android/samples/annotation-configuration-kotlin.md)
- [Annotation Creation](/guides/android/samples/annotation-creation-kotlin.md)
- [Annotation Flags](/guides/android/samples/annotation-flags-kotlin.md)
- [Annotation Overlay](/guides/android/samples/annotation-overlay-java.md)
- [Annotation Rendering](/guides/android/samples/annotation-rendering-kotlin.md)
- [Annotation Selection Styling](/guides/android/samples/annotation-selection-styling-kotlin.md)
- [Annotation Sidebar](/guides/android/samples/annotation-sidebar-kotlin.md)
- [Annotations with Transparency](/guides/android/samples/annotations-with-transparency-kotlin.md)
- [Application Policy](/guides/android/samples/application-policy-kotlin.md)
- [Bookmark Highlighting](/guides/android/samples/bookmark-highlighting-kotlin.md)
- [Compose Image Document](/guides/android/samples/compose-image-document-kotlin.md)
- [Compose Navigation](/guides/android/samples/compose-navigation-kotlin.md)
- [Construction Floor Plan](/guides/android/samples/construction-floor-plan-kotlin.md)
- [Custom ActionBar Actions](/guides/android/samples/custom-actionbar-actions-kotlin.md)
- [Custom Activity Form Editing](/guides/android/samples/custom-activity-form-editing-java.md)
- [Custom Activity Toolbars](/guides/android/samples/custom-activity-toolbars-java.md)
- [Custom Annotation Creation Toolbar](/guides/android/samples/custom-annotation-creation-toolbar-java.md)
- [Custom Annotation Inspector](/guides/android/samples/custom-annotation-inspector-java.md)
- [Custom Data Provider](/guides/android/samples/custom-data-provider-kotlin.md)
- [Custom Download Dialog](/guides/android/samples/custom-download-dialog-java.md)
- [Custom Electronic Signature](/guides/android/samples/custom-electronic-signature-java.md)
- [Custom Form Highlight Color](/guides/android/samples/custom-form-highlight-color-java.md)
- [Custom Layout](/guides/android/samples/custom-layout-kotlin.md)
- [Custom Main Toolbar](/guides/android/samples/custom-main-toolbar-kotlin.md)
- [Custom Note Hinter](/guides/android/samples/custom-note-hinter-kotlin.md)
- [Custom Outline Provider](/guides/android/samples/custom-outline-provider-kotlin.md)
- [Custom Page Templates](/guides/android/samples/custom-page-templates-java.md)
- [Custom Search UI (Compose)](/guides/android/samples/custom-search-ui-compose-kotlin.md)
- [Custom Search UI (Views)](/guides/android/samples/custom-search-ui-views-java.md)
- [Custom Sharing Dialog](/guides/android/samples/custom-sharing-dialog-java.md)
- [Custom Sharing Menu](/guides/android/samples/custom-sharing-menu-java.md)
- [Custom Stamp Annotations](/guides/android/samples/custom-stamp-annotations-java.md)
- [Custom Toolbar Grouping](/guides/android/samples/custom-toolbar-grouping-java.md)
- [Digital Signature (Basic)](/guides/android/samples/digital-signature-basic-kotlin.md)
- [Digital Signature (Manual)](/guides/android/samples/digital-signature-manual-kotlin.md)
- [Digital Signature (Third-Party)](/guides/android/samples/digital-signature-third-party-kotlin.md)
- [Digital Signature (Two-Step)](/guides/android/samples/digital-signature-two-step-kotlin.md)
- [Disabled Annotation Property](/guides/android/samples/disabled-annotation-property-java.md)
- [Document Comparison](/guides/android/samples/document-comparison-kotlin.md)
- [Document Download](/guides/android/samples/document-download-kotlin.md)
- [Document from Canvas](/guides/android/samples/document-from-canvas-kotlin.md)
- [Document Sharing](/guides/android/samples/document-sharing-java.md)
- [Document Switcher](/guides/android/samples/document-switcher-java.md)
- [DocumentView Composable](/guides/android/samples/documentview-composable-kotlin.md)
- [Download Progress](/guides/android/samples/download-progress-kotlin.md)
- [Dynamic Pages on Scroll](/guides/android/samples/dynamic-pages-on-scroll-kotlin.md)
- [E-Learning](/guides/android/samples/e-learning-kotlin.md)
- [Electronic + Digital Signing](/guides/android/samples/electronic-digital-signing-kotlin.md)
- [External Document](/guides/android/samples/external-document-kotlin.md)
- [File Annotation Creation](/guides/android/samples/file-annotation-creation-kotlin.md)
- [Filterable Thumbnail Grid](/guides/android/samples/filterable-thumbnail-grid-kotlin.md)
- [Form Click Intercept (Compose)](/guides/android/samples/form-click-intercept-compose-kotlin.md)
- [Form Creation](/guides/android/samples/form-creation-kotlin.md)
- [Form Filling](/guides/android/samples/form-filling-kotlin.md)
- [Forms with JavaScript](/guides/android/samples/forms-with-javascript-kotlin.md)
- [Fragment Runtime Configuration](/guides/android/samples/fragment-runtime-configuration-kotlin.md)
- [Generate PDF Report](/guides/android/samples/generate-pdf-report-kotlin.md)
- [Hide and Reveal Areas](/guides/android/samples/hide-and-reveal-areas-kotlin.md)
- [HTML-to-PDF Conversion](/guides/android/samples/html-to-pdf-conversion-kotlin.md)
- [Image Document](/guides/android/samples/image-document-kotlin.md)
- [Inline Multimedia](/guides/android/samples/inline-multimedia-kotlin.md)
- [Inline Search](/guides/android/samples/inline-search-java.md)
- [Instant Document JSON](/guides/android/samples/instant-document-json-kotlin.md)
- [Instant JSON Attachment](/guides/android/samples/instant-json-attachment-kotlin.md)
- [JavaScript Actions](/guides/android/samples/javascript-actions-kotlin.md)
- [JavaScript Calculator](/guides/android/samples/javascript-calculator-kotlin.md)
- [JavaScript Form Filling](/guides/android/samples/javascript-form-filling-kotlin.md)
- [Kiosk Grid](/guides/android/samples/kiosk-grid-kotlin.md)
- [LTV Signature](/guides/android/samples/ltv-signature-kotlin.md)
- [Measurement Tools](/guides/android/samples/measurement-tools-kotlin.md)
- [Merge Documents](/guides/android/samples/merge-documents-kotlin.md)
- [Multimedia Annotations](/guides/android/samples/multimedia-annotations-kotlin.md)
- [Multiple Documents (Compose Pager)](/guides/android/samples/multiple-documents-compose-pager-kotlin.md)
- [OCR](/guides/android/samples/ocr-kotlin.md)
- [Overlay Views](/guides/android/samples/overlay-views-kotlin.md)
- [Overlay Visibility](/guides/android/samples/overlay-visibility-kotlin.md)
- [Password Protected PDF](/guides/android/samples/password-protected-pdf-kotlin.md)
- [PDF from Image](/guides/android/samples/pdf-from-image-kotlin.md)
- [PdfFragment](/guides/android/samples/pdffragment-kotlin.md)
- [PdfUiFragment](/guides/android/samples/pdfuifragment-kotlin.md)
- [Playground](/guides/android/samples/playground-kotlin.md)
- [Popup Toolbar Customization](/guides/android/samples/popup-toolbar-customization-kotlin.md)
- [Programmatic Zoom](/guides/android/samples/programmatic-zoom-kotlin.md)
- [Reader View](/guides/android/samples/reader-view-kotlin.md)
- [Remote URL](/guides/android/samples/remote-url-kotlin.md)
- [Runtime Configuration](/guides/android/samples/runtime-configuration-kotlin.md)
- [Scientific Paper](/guides/android/samples/scientific-paper-kotlin.md)
- [Screen Reader](/guides/android/samples/screen-reader-java.md)
- [Search Indexing](/guides/android/samples/search-indexing-kotlin.md)
- [Selection Customization](/guides/android/samples/selection-customization-java.md)
- [Signature Parcelize](/guides/android/samples/signature-parcelize-kotlin.md)
- [Signature Storage Database](/guides/android/samples/signature-storage-database-kotlin.md)
- [Sound Extraction](/guides/android/samples/sound-extraction-kotlin.md)
- [Split View](/guides/android/samples/split-view-java.md)
- [Tabbed Documents](/guides/android/samples/tabbed-documents-kotlin.md)
- [Tabbed Documents (Persistent)](/guides/android/samples/tabbed-documents-persistent-kotlin.md)
- [Text Field Suggestions](/guides/android/samples/text-field-suggestions-kotlin.md)
- [Thumbnail Bar Modes](/guides/android/samples/thumbnail-bar-modes-kotlin.md)
- [Try Instant](/guides/android/samples/try-instant-kotlin.md)
- [UI View Modes](/guides/android/samples/ui-view-modes-kotlin.md)
- [Vertical Scrollbar](/guides/android/samples/vertical-scrollbar-java.md)
- [Watermarks](/guides/android/samples/watermarks-kotlin.md)
- [XFDF Import/Export](/guides/android/samples/xfdf-import-export-kotlin.md)

