---
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: "2026-05-15T19:10:04.916Z"
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

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

