Blog Post

How to Add Annotations to PDFs Using the Android Library

Illustration: How to Add Annotations to PDFs Using the Android Library

In this post, you’ll learn how to annotate a PDF file using PSPDFKit’s Android PDF library. More specifically, you’ll learn how to programmatically add:

  • Highlight annotations

  • Link annotations

  • Free text annotations

  • Ink annotations

  • Note annotations

  • Stamp annotations

PSPDFKit for Android provides a clean and elegant way to annotate any PDF document while saving development time and cost.

Requirements

To get started, you’ll need:

  • Android Studio — The official integrated development environment for Android

Getting Started

To follow along, create a fresh Android Studio project and add PSPDFKit to your project. For step-by-step instructions on how to create a new project, follow our Getting Started on Android guide.

Displaying PDFs Using PdfFragment

PSPDFKit for Android has a PdfFragment, which is used for displaying documents. It’s meant to be used if you want full custom implementation and design.

Information

PdfFragment contains only the document view, without any additional views like the outline, thumbnail bar, search, etc.

  1. Make sure your application is prepared for displaying and editing PDFs. Set the android:largeHeap="true" property in your <application> tag in app/src/mainAndroidManifest.xml:

    <application android:largeHeap="true">
        ...
    </application>
    ...
Information

This property will ensure your app has enough heap allocated to avoid out-of-memory errors.

  1. Add a blank fragment by right-clicking src and going to New > Fragment > Fragment (Blank). Ensure you select Kotlin as the language.

    Image showing the navigation to blank fragment in Android Studio

  2. When prompted, enter the fragment name and click Finish.

    Image showing the Android studio’s UI for naming the fragment

  3. Open your src/main/res/layout/activity_main.xml file and a <fragment> tag:

    <fragment
        android:id="@+id/fragmentContainer"
        android:name="[your-application-id].[your-fragment-name]"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
Information

Remember to replace "[your-application-id]" and "[your-fragment-name]" with your actual app ID and fragment name.

  1. Remove any code and TODOs you don’t need in your newly created fragment file and pass the ID of the fragment tag you created earlier to the Fragment constructor:

    package com.example.pspdfkitannotations
    
    import androidx.fragment.app.Fragment
    
    class PSPDFKitPDFAnnotationDemoFragment : Fragment(R.layout.fragment_pspdfkit_pdf_annotation_demo_fragment) {
    
    }

If you want to follow along with the code, use the package name com.example.pspdfkitannotations. Alternatively, you can use your own name.

  1. In MainActivity.kt, create a fragment using the PdfConfiguration instance and attach it to your activity:

    package [your-application-id]
    
    import android.net.Uri
    import androidx.appcompat.app.AppCompatActivity
    import android.os.Bundle
    import com.pspdfkit.configuration.PdfConfiguration
    import com.pspdfkit.configuration.page.PageScrollDirection
    import com.pspdfkit.ui.PdfFragment
    
    class MainActivity : AppCompatActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
    
            val uri = Uri.parse("file:///android_asset/[your-document].pdf")
            val configuration = PdfConfiguration.Builder()
                .scrollDirection(PageScrollDirection.HORIZONTAL)
                .build()
    
            createFragment(uri, configuration)
    
        }
    
        private fun createFragment(documentUri: Uri, configuration: PdfConfiguration): PdfFragment {
            val fragment = PdfFragment.newInstance(documentUri, configuration)
            supportFragmentManager.beginTransaction()
                .replace(R.id.fragmentContainer, fragment)
                .commit()
            return fragment
        }
    }
Information

Just like the PdfActivity, PdfFragment allows passing in a configuration object that defines various options.

  1. Run your application to display your PDF using PdfFragment.

    GIF showing the result of running the application in Android studio

Adding Highlight Annotations

In activity_main.xml, add a button tag. You’ll use this button to add annotations when it’s clicked:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/fragmentContainer"
        android:name="com.example.testapp.TestPdfFragment"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintBottom_toTopOf="@id/annotatePdf"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:layout="@layout/fragment_pdf" />

    <Button
        android:id="@+id/annotatePdf"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="12dp"
        android:text="Add Annotation"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/fragmentContainer" />

</androidx.constraintlayout.widget.ConstraintLayout>

Get the button’s reference and add a listener to it in your MainActivity.kt file to display a toast when clicked:

val annotateBtn = findViewById<Button>(R.id.annotatePdf)

annotateBtn.setOnClickListener{
    Toast.makeText(this, "Annotation Added!", Toast.LENGTH_LONG).show()
    frag.addAnnotationToPage(highlightAnnotation, false)
}

The HighlightAnnotation API expects a page index and a list of rectangles that represent highlights (List<RectF>).

  1. Define the places you want to highlight:

    val textRects = listOf(RectF(440f, 760f, 715f, 800f))
  2. Supply the HighlightAnnotation API with the page index and the places you want to highlight:

    val highlightAnnotation = HighlightAnnotation(0, textRects)
  3. Set the highlight color and add the annotation to the document using the addAnnotationToPage method:

    package [your-application-id]
    
    import android.graphics.Color
    import android.graphics.RectF
    import android.net.Uri
    import androidx.appcompat.app.AppCompatActivity
    import android.os.Bundle
    import android.widget.Button
    import android.widget.Toast
    import com.pspdfkit.annotations.HighlightAnnotation
    import com.pspdfkit.configuration.PdfConfiguration
    import com.pspdfkit.configuration.page.PageScrollDirection
    import com.pspdfkit.ui.PdfFragment
    
    class MainActivity : AppCompatActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
    
            val uri = Uri.parse("file:///android_asset/[your-document].pdf")
            val configuration = PdfConfiguration.Builder()
                .scrollDirection(PageScrollDirection.HORIZONTAL)
                .build()
    
            // Define the places you want to highlight.
            val textRects = listOf(RectF(440f, 760f, 715f, 800f))
            // Create the highlight on the first page.
            val highlightAnnotation = HighlightAnnotation(0, textRects)
            // Set the color.
            highlightAnnotation.color = Color.YELLOW
    
    
            val frag = createFragment(uri, configuration)
    
            val annotateBtn = findViewById<Button>(R.id.annotatePdf)
    
            annotateBtn.setOnClickListener{
                Toast.makeText(this, "Annotation Added!", Toast.LENGTH_LONG).show()
                frag.addAnnotationToPage(highlightAnnotation, false)
            }
    
        }
    
        private fun createFragment(documentUri: Uri, configuration: PdfConfiguration): PdfFragment {
            val fragment = PdfFragment.newInstance(documentUri, configuration)
            supportFragmentManager.beginTransaction()
                .replace(R.id.fragmentContainer, fragment)
                .commit()
            return fragment
        }
    }
  4. Run your application and click the Add Annotation button to add a highlight annotation to your document.

    GIF showing the highlight annotation in action

The LinkAnnotation API expects only the page index.

  1. Create the link on the first page:

    val linkAnnotation = LinkAnnotation(0)
  2. Set the annotation position:

    linkAnnotation.boundingBox = RectF(10f, 0f, 600f, 1000f)
  3. Set where the link points to:

    linkAnnotation.action = GoToAction(4)
  4. Add the annotation to the document using the addAnnotationToPage method:

    package [your-application-id]
    
    import android.graphics.RectF
    import android.net.Uri
    import androidx.appcompat.app.AppCompatActivity
    import android.os.Bundle
    import android.widget.Button
    import android.widget.Toast
    import com.pspdfkit.annotations.LinkAnnotation
    import com.pspdfkit.annotations.actions.GoToAction
    import com.pspdfkit.configuration.PdfConfiguration
    import com.pspdfkit.configuration.page.PageScrollDirection
    import com.pspdfkit.ui.PdfFragment
    
    class MainActivity : AppCompatActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
    
            val uri = Uri.parse("file:///android_asset/[your-document].pdf")
            val configuration = PdfConfiguration.Builder()
                .scrollDirection(PageScrollDirection.HORIZONTAL)
                .build()
    
            // Create the link on the first page.
            val linkAnnotation = LinkAnnotation(0)
            // Set the position.
            linkAnnotation.boundingBox = RectF(10f, 0f, 600f, 1000f)
            // Set where the link points to — in this case, the fifth page.
            linkAnnotation.action = GoToAction(4)
    
    
            val frag = createFragment(uri, configuration)
    
            val annotateBtn = findViewById<Button>(R.id.annotatePdf)
    
            annotateBtn.setOnClickListener{
                Toast.makeText(this, "Annotation Added!", Toast.LENGTH_LONG).show()
                frag.addAnnotationToPage(linkAnnotation, false)
            }
    
        }
    
        private fun createFragment(documentUri: Uri, configuration: PdfConfiguration): PdfFragment {
            val fragment = PdfFragment.newInstance(documentUri, configuration)
            supportFragmentManager.beginTransaction()
                .replace(R.id.fragmentContainer, fragment)
                .commit()
            return fragment
        }
    }
  5. Run your application and click the Add Annotation button to add a link annotation to your document.

    GIF showing the link annotation in action

Adding Free Text Annotations

The FreeTextAnnotation API expects a page index, a bounding rectangle (RectF), and a String (text of the annotation).

  1. Create the text on the first page:

    val freeTextAnnotation = FreeTextAnnotation(0, RectF(100f, 550f, 300f, 600f), "My Annotation")
  2. Set the text color:

    freeTextAnnotation.color = Color.RED
  3. Set the text size and add the annotation to the document using the addAnnotationToPage method:

    package [your-application-id]
    
    import android.graphics.Color
    import android.graphics.RectF
    import android.net.Uri
    import androidx.appcompat.app.AppCompatActivity
    import android.os.Bundle
    import android.widget.Button
    import android.widget.Toast
    import com.pspdfkit.annotations.FreeTextAnnotation
    import com.pspdfkit.configuration.PdfConfiguration
    import com.pspdfkit.configuration.page.PageScrollDirection
    import com.pspdfkit.ui.PdfFragment
    
    class MainActivity : AppCompatActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
    
            val uri = Uri.parse("file:///android_asset/[your-documnet].pdf")
            val configuration = PdfConfiguration.Builder()
                .scrollDirection(PageScrollDirection.HORIZONTAL)
                .build()
    
            // Create the text on the first page.
            val freeTextAnnotation = FreeTextAnnotation(0, RectF(100f, 550f, 300f, 600f), "My Annotation")
            // Set the text color.
            freeTextAnnotation.color = Color.RED
            // Set the text size.
            freeTextAnnotation.textSize = 30f
    
    
            val frag = createFragment(uri, configuration)
    
            val annotateBtn = findViewById<Button>(R.id.annotatePdf)
    
            annotateBtn.setOnClickListener{
                Toast.makeText(this, "Annotation Added!", Toast.LENGTH_LONG).show()
                frag.addAnnotationToPage(freeTextAnnotation, false)
            }
    
        }
    
        private fun createFragment(documentUri: Uri, configuration: PdfConfiguration): PdfFragment {
            val fragment = PdfFragment.newInstance(documentUri, configuration)
            supportFragmentManager.beginTransaction()
                .replace(R.id.fragmentContainer, fragment)
                .commit()
            return fragment
        }
    }
  4. Run your application and click the Add Annotation button to add a free text annotation to your document.

    GIF showing the free text annotation in action

Adding Ink Annotations

The InkAnnotation API expects only the page index.

  1. Create the ink annotation on the first page:

    val inkAnnotation = InkAnnotation(0)
  2. Set the line color:

    inkAnnotation.color = Color.RED
  3. Set the line width:

    inkAnnotation.lineWidth = 10f
  4. Create a line from a list of points and set it to the annotation:

    val line = listOf(
        PointF(100f, 100f),
        PointF(150f, 150f),
        PointF(200f, 100f),
        PointF(250f, 150f),
        PointF(200f, 200f)
    )
    // Ink annotations can hold multiple lines. We only use one here.
    inkAnnotation.lines = listOf(line)
  5. Add the annotation to the document using the addAnnotationToPage method:

    package [your-application-id]
    
    import android.graphics.Color
    import android.graphics.PointF
    import android.net.Uri
    import androidx.appcompat.app.AppCompatActivity
    import android.os.Bundle
    import android.widget.Button
    import android.widget.Toast
    import com.pspdfkit.annotations.InkAnnotation
    import com.pspdfkit.configuration.PdfConfiguration
    import com.pspdfkit.configuration.page.PageScrollDirection
    import com.pspdfkit.ui.PdfFragment
    
    class MainActivity : AppCompatActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
    
            val uri = Uri.parse("file:///android_asset/[your-document].pdf")
            val configuration = PdfConfiguration.Builder()
                .scrollDirection(PageScrollDirection.HORIZONTAL)
                .build()
    
            // Create the ink annotation on the first page.
            val inkAnnotation = InkAnnotation(0)
            // Set the line color.
            inkAnnotation.color = Color.RED
            // Set the line width.
            inkAnnotation.lineWidth = 10f
            // Create a line from a list of points.
            val line = listOf(
                PointF(100f, 100f),
                PointF(150f, 150f),
                PointF(200f, 100f),
                PointF(250f, 150f),
                PointF(200f, 200f)
            )
            // Ink annotations can hold multiple lines. We only use one here.
            inkAnnotation.lines = listOf(line)
    
    
            val frag = createFragment(uri, configuration)
    
            val annotateBtn = findViewById<Button>(R.id.annotatePdf)
    
            annotateBtn.setOnClickListener{
                Toast.makeText(this, "Annotation Added!", Toast.LENGTH_LONG).show()
                frag.addAnnotationToPage(inkAnnotation, false)
            }
    
        }
    
        private fun createFragment(documentUri: Uri, configuration: PdfConfiguration): PdfFragment {
            val fragment = PdfFragment.newInstance(documentUri, configuration)
            supportFragmentManager.beginTransaction()
                .replace(R.id.fragmentContainer, fragment)
                .commit()
            return fragment
        }
    }
  6. Run your application and click the Add Annotation button to add an ink annotation to your document.

    GIF showing the ink annotation in action

Adding Note Annotations

The NoteAnnotation API expects a page index, a rectangle in page coordinates of the note position on the page (RectF), and two String values — one for the text of the note, and one for the icon name.

  1. Create the note on the first page:

    val noteAnnotation = NoteAnnotation(0,
            RectF(100f, 550f, 132f, 600f),
            "This is my note",
            NoteAnnotation.NOTE)
  2. Add the annotation to the document using the addAnnotationToPage method:

    package [your-application-id]
    
    import android.graphics.RectF
    import android.net.Uri
    import androidx.appcompat.app.AppCompatActivity
    import android.os.Bundle
    import android.widget.Button
    import android.widget.Toast
    import com.pspdfkit.annotations.NoteAnnotation
    import com.pspdfkit.configuration.PdfConfiguration
    import com.pspdfkit.configuration.page.PageScrollDirection
    import com.pspdfkit.ui.PdfFragment
    
    class MainActivity : AppCompatActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
    
            val uri = Uri.parse("file:///android_asset/[your-document].pdf")
            val configuration = PdfConfiguration.Builder()
                .scrollDirection(PageScrollDirection.HORIZONTAL)
                .build()
    
            // Create the note on the first page.
            val noteAnnotation = NoteAnnotation(0,
                RectF(100f, 550f, 132f, 600f),
                "This is my note",
                NoteAnnotation.NOTE)
    
    
    
            val frag = createFragment(uri, configuration)
    
            val annotateBtn = findViewById<Button>(R.id.annotatePdf)
    
            annotateBtn.setOnClickListener{
                Toast.makeText(this, "Annotation Added!", Toast.LENGTH_LONG).show()
                frag.addAnnotationToPage(noteAnnotation, false)
            }
    
        }
    
        private fun createFragment(documentUri: Uri, configuration: PdfConfiguration): PdfFragment {
            val fragment = PdfFragment.newInstance(documentUri, configuration)
            supportFragmentManager.beginTransaction()
                .replace(R.id.fragmentContainer, fragment)
                .commit()
            return fragment
        }
    }
  3. Run your application and click the Add Annotation button to add a note annotation to your document:

    GIF showing the note annotation in action

Adding Stamp Annotations

  1. Create the stamp on the first page using the StampAnnotation API:

    val stampAnnotation = StampAnnotation(0,
            RectF(100f, 550f, 300f, 600f),
            StampType.CONFIDENTIAL)
  2. Add the annotation to the document using the addAnnotationToPage method:

    package [your-application-id]
    
    import android.graphics.RectF
    import android.net.Uri
    import androidx.appcompat.app.AppCompatActivity
    import android.os.Bundle
    import android.widget.Button
    import android.widget.Toast
    import com.pspdfkit.annotations.StampAnnotation
    import com.pspdfkit.annotations.stamps.StampType
    import com.pspdfkit.configuration.PdfConfiguration
    import com.pspdfkit.configuration.page.PageScrollDirection
    import com.pspdfkit.ui.PdfFragment
    
    class MainActivity : AppCompatActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
    
            val uri = Uri.parse("file:///android_asset/[your-document].pdf")
            val configuration = PdfConfiguration.Builder()
                .scrollDirection(PageScrollDirection.HORIZONTAL)
                .build()
    
            // Create the stamp on the first page.
            val stampAnnotation = StampAnnotation(0,
                RectF(100f, 550f, 300f, 600f),
                StampType.CONFIDENTIAL)
    
    
    
            val frag = createFragment(uri, configuration)
    
            val annotateBtn = findViewById<Button>(R.id.annotatePdf)
    
            annotateBtn.setOnClickListener{
                Toast.makeText(this, "Annotation Added!", Toast.LENGTH_LONG).show()
                frag.addAnnotationToPage(stampAnnotation, false)
            }
    
        }
    
        private fun createFragment(documentUri: Uri, configuration: PdfConfiguration): PdfFragment {
            val fragment = PdfFragment.newInstance(documentUri, configuration)
            supportFragmentManager.beginTransaction()
                .replace(R.id.fragmentContainer, fragment)
                .commit()
            return fragment
        }
    }
  3. Run your application and click the Add Annotation button to add a stamp annotation to your document.

GIF showing the stamp annotation in action

Conclusion

In this post, you learned how to annotate a PDF document using PSPDFKit for Android. If you hit any snags while trying to implement any of the steps, 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.

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

Related Articles

Explore more
PRODUCTS  |  Android • Releases

Android 2024.1 Update: Advanced Content Editing and Digital Signatures, Plus Expanded Jetpack Compose Support

TUTORIALS  |  Android • How To

How to Persist Zoom While Scrolling through a Document Using the PSPDFKit Android Library

CUSTOMER STORIES  |  Case Study • React Native • iOS • Android

Case Study: How Trinoor Uses PSPDFKit to Drive Operational Excellence with Flexible, Mobile Applications for the Energy and Utilities Market