How to Add Annotations to PDFs Using the Android Library

Table of contents

    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:

    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.

    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>
      ...

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

    2. 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

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

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

    4. 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" />

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

    5. 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.

    6. 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
      }
      }

      Just like the PdfActivity(opens in a new tab), PdfFragment(opens in a new tab) allows passing in a configuration object that defines various options.

    7. 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.

    Teja Tatimatla

    Teja Tatimatla

    Explore related topics

    FREE TRIAL Ready to get started?