---
title: "Measurement Tools"
canonical_url: "https://www.nutrient.io/guides/android/samples/measurement-tools-kotlin/"
md_url: "https://www.nutrient.io/guides/android/samples/measurement-tools-kotlin.md"
last_updated: "2026-05-15T19:10:04.916Z"
description: "Create and read measurement annotations with scale calibration and precision settings."
---

# Measurement Tools

Create and read measurement annotations with scale calibration and precision settings.

[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 © 2022-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.
 */

package com.pspdfkit.catalog.examples.kotlin

import android.content.Context
import android.graphics.Color
import android.graphics.PointF
import android.net.Uri
import android.os.Bundle
import android.widget.Toast
import androidx.activity.viewModels
import androidx.annotation.UiThread
import com.pspdfkit.annotations.Annotation
import com.pspdfkit.annotations.AnnotationProvider
import com.pspdfkit.annotations.LineAnnotation
import com.pspdfkit.annotations.measurements.MeasurementPrecision
import com.pspdfkit.annotations.measurements.MeasurementValueConfiguration
import com.pspdfkit.annotations.measurements.Scale
import com.pspdfkit.catalog.R
import com.pspdfkit.catalog.SdkExample
import com.pspdfkit.catalog.tasks.ExtractAssetTask
import com.pspdfkit.configuration.activity.PdfActivityConfiguration
import com.pspdfkit.configuration.page.PageLayoutMode
import com.pspdfkit.configuration.sharing.ShareFeatures
import com.pspdfkit.document.PdfDocument
import com.pspdfkit.preferences.PSPDFKitPreferences
import com.pspdfkit.ui.PdfActivity
import com.pspdfkit.ui.PdfActivityIntentBuilder
import com.pspdfkit.ui.special_mode.controller.AnnotationTool
import com.pspdfkit.utils.PdfLog
import kotlinx.coroutines.runBlocking
import java.util.EnumSet
import kotlin.collections.forEach
import kotlin.getValue

/**
 * Measurement Tools example.
 * This example showcases the measurement tools introduced in Nutrient for Android 8.4.
 * You can read more about the measurement tools in our [guides](https://nutrient.io/guides/android/measurements/)
 *  and [Announcement blog post](https://nutrient.io/blog/2022/announcing-pspdfkit-measurement-tools).
 */
class MeasurementToolsExample(context: Context) :
    SdkExample(context, R.string.measurementToolsExampleTitle, R.string.measurementToolsExampleDescription) {
    companion object {
        const val MEASUREMENTS_PDF = "Measurements.pdf"
    }

    override fun launchExample(context: Context, configuration: PdfActivityConfiguration.Builder) {
        // Using this flag to show the ways of changing the defaults without affecting this example.
        val changeDefaultConfiguration = false

        // Here are some ways in which you can change the default settings of the measurement tools:
        if (changeDefaultConfiguration) {
            configuration.apply {
                // Measurement tools are enabled by default if they are licensed. You can turn them off in the configuration if you prefer:
                setMeasurementToolsEnabled(false)

                // Measurement tools use the Android magnifier to help create more accurate measurements. You can turn off this feature here:
                enableMagnifier(false)
            }

            // Measurement tools have a feature where you can snap the drawing to the vector graphics on the page. It is on by default,
            // but you can turn it off by default using the PSPDFKitPreferences singleton:
            PSPDFKitPreferences.get(context).isMeasurementSnappingEnabled = false
        }

        // Disable some features that are not relevant to the example.
        configuration
            // Turn off saving, so we have the clean original document every time the example is launched..autosaveEnabled(false).layoutMode(PageLayoutMode.SINGLE).documentInfoViewEnabled(false).searchEnabled(false).contentEditingEnabled(false).setEnabledShareFeatures(EnumSet.noneOf(ShareFeatures::class.java)).printingEnabled(false).thumbnailGridEnabled(false).setRedactionUiEnabled(false)
            // We only enable the measurement tools for this example..enabledAnnotationTools(
                listOf(
                    AnnotationTool.MEASUREMENT_DISTANCE,
                    AnnotationTool.MEASUREMENT_PERIMETER,
                    AnnotationTool.MEASUREMENT_AREA_POLYGON,
                    AnnotationTool.MEASUREMENT_AREA_ELLIPSE,
                    AnnotationTool.MEASUREMENT_AREA_RECT,
                    AnnotationTool.MEASUREMENT_SCALE_CALIBRATION,
                ),
            )

        ExtractAssetTask.extract(MEASUREMENTS_PDF, title, context) { documentFile ->
            val intent =
                PdfActivityIntentBuilder.fromUri(context, Uri.fromFile(documentFile)).configuration(configuration.build()).activityClass(MeasurementToolsActivity::class).build()

            // Start the MeasurementToolsActivity for the extracted document.
            context.startActivity(intent)
        }
    }
}

/**
 * This subclass of [PdfActivity] adds a listener for newly created and updated measurements, and reads existing measurements from the
 * document when it's loaded.
 */
class MeasurementToolsActivity :
    PdfActivity(),
    AnnotationProvider.OnAnnotationUpdatedListener {
    private val viewModel: AnnotationCreationViewModel by viewModels()

    /** We hold a list of all the measurements created for this activity. */
    private val measurements: MutableList<Annotation> = mutableListOf()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // We can register interest in newly created annotations so we can easily pick up measurement information.
        pdfFragment?.addOnAnnotationUpdatedListener(this)
    }

    @UiThread
    override fun onDocumentLoaded(document: PdfDocument) {
        viewModel.createObjects {
            // If we know the scale of the page, we can create it programmatically.
            val pageScale = Scale(1f, Scale.UnitFrom.CM, 1f, Scale.UnitTo.CM)

            // We can add a new measurement config with new scale and floating point precision of the document pages used by the measurement
            // tool annotations using the measurementValueConfigurationEditor#add API.

            // This will set the scale and precision for future measurements.
            val measurementValueConfiguration = MeasurementValueConfiguration("Custom Scale", pageScale, MeasurementPrecision.EIGHTHS_INCH)
            pdfFragment?.measurementValueConfigurationEditor?.add(measurementValueConfiguration, false)

            // We can also make sure the new config is the selected one.
            pdfFragment?.setSelectedMeasurementValueConfiguration(measurementValueConfiguration)

            // All the above work can be done by selecting the fab, when measurement tool is selected in the UI.

            // All the measurement configuration can be retrieved dynamically as well with
            // measurementValueConfigurationEditor#measurementValueConfigurations API.

            listAllMeasurementConfigurations(pdfFragment?.measurementValueConfigurationEditor?.configurations)

            // Similarly you can remove any configuration as well using
            // measurementValueConfigurationEditor#remove API.

            // We can read the annotations to see if there are any measurements that we need to process...
            for (page in 0 until document.pageCount) {
                measurements.addAll(runBlocking { document.annotationProvider.getAnnotations(page) }.filter { it.isMeasurement })
            }
            //... and process them.
            processAllMeasurements()

            // Let's create a distance measurement annotation programmatically.
            val distanceMeasurement =
                LineAnnotation(
                    0, // Page number
                    PointF(56.693f, 460f), // Start point.
                    PointF(150f, 460f), // End point.
                    pageScale, // We can specify the scale. Let's use the same one set on the document.
                    MeasurementPrecision.THREE_DP, // We can use a different precision for this measurement.
                )
            distanceMeasurement.color = Color.BLUE
            pdfFragment?.addAnnotationToPage(distanceMeasurement, false)
        }
    }

    /** List up all measurement configurations in document. */
    private fun listAllMeasurementConfigurations(measurementValueConfigurations: List<MeasurementValueConfiguration>?) =
        measurementValueConfigurations?.forEach {
            PdfLog.i("MeasurementExample", "${it.getNameForDisplay(true)}")
        }

    /** Process all the measurements in our activity. */
    private fun processAllMeasurements() {
        measurements.forEach(::processMeasurement)
    }

    /** Process any measurements that are passed. */
    private fun processMeasurement(annotation: Annotation) {
        if (!annotation.isMeasurement) return
        val info = annotation.measurementInfo?: return
        PdfLog.i(
            "MeasurementExample",
            "Processing measurement...\n" +
                "Type: ${info.measurementMode.name}; Raw value: ${info.value} ${info.scale.unitTo}; Label: ${info.label}",
        )
    }

    override fun onAnnotationCreated(annotation: Annotation) {
        if (!annotation.isMeasurement) return
        // We have a new measurement!

        // Add it to our set.
        measurements.add(annotation)

        // Let's get the measurement information and do something with it.
        val info = annotation.measurementInfo
        info?.let {
            val toastText = "Created ${it.measurementMode.name} measurement: ${it.label}"
            Toast.makeText(this, toastText, Toast.LENGTH_SHORT).show()
        }

        // It's new, we should also process it...
        processMeasurement(annotation)
    }

    override fun onAnnotationUpdated(annotation: Annotation) {
        processMeasurement(annotation)
    }

    override fun onAnnotationRemoved(annotation: Annotation) {
        if (!annotation.isMeasurement) return
        // Remove it from our set.
        measurements.remove(annotation)
        PdfLog.i("MeasurementExample", "Removed ${annotation.type} measurement annotation.")
    }

    override fun onAnnotationZOrderChanged(pageIndex: Int, oldOrder: List<Annotation>, newOrder: List<Annotation>) {
        // Nothing to do in this example.
    }
}

```

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)
- [Document Processing](/guides/android/samples/document-processing-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)
- [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)

