Detect If an Annotation Has Changed on Android

After loading a document, you can access its annotations via the AnnotationProvider returned by PdfDocument#getAnnotationProvider. The annotation provider supports reading, adding, and removing annotations to and from the document associated with it:

val pageIndex = 0
val annotations: List<Annotation> = document.annotationsProvider.getAnnotations(pageIndex)
final int pageIndex = 0;
final List<Annotation> annotations = document.getAnnotationsProvider().getAnnotations(pageIndex);

Listening for Annotation Changes

The PdfFragment implements the AnnotationManager interface, allowing you to register listeners that are notified whenever an annotation is selected, modified, or deselected:

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

    pdfFragment.addOnAnnotationSelectedListener(object :AnnotationManager.OnAnnotationSelectedListener {
        override fun onPrepareAnnotationSelection(controller: AnnotationSelectionController, annotation: Annotation, annotationCreated: Boolean): Boolean {
            // Returning `false` here would prevent the annotation from being selected.
            return true
        }

        override fun onAnnotationSelected(annotation: Annotation, annotationCreated: Boolean) {
            Log.i(TAG, "The annotation was selected.")
        }
    })

    pdfFragment.addOnAnnotationDeselectedListener { annotation, reselected ->
        Log.i(TAG, "The annotation was deselected.")
    }

    pdfFragment.addOnAnnotationUpdatedListener(object: OnAnnotationUpdatedListener {
        override fun onAnnotationCreated(annotation: Annotation) {
            Log.i(TAG, "The annotation was created.")
        }

        override fun onAnnotationUpdated(annotation: Annotation) {
            Log.i(TAG, "The annotation was updated.")
        }

        override fun onAnnotationRemoved(annotation: Annotation) {
            Log.i(TAG, "The annotation was removed.")
        }
    })

    // This will remove all previously registered listeners. Instead, you could unregister them selectively.
    pdfFragment.clearAnnotationListeners()
}
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    getPdfFragment().addOnAnnotationSelectedListener(new AnnotationManager.OnAnnotationSelectedListener() {
        @Override
        public boolean onPrepareAnnotationSelection(@NonNull AnnotationSelectionController controller, @NonNull Annotation annotation, boolean annotationCreated) {
            // Returning `false` here would prevent the annotation from being selected.
            return true;
        }

        @Override public void onAnnotationSelected(@NonNull Annotation annotation, boolean annotationCreated) {
            Log.i(TAG, "The annotation was selected");
        }
    });

    getPdfFragment().addOnAnnotationDeselectedListener(new AnnotationManager.OnAnnotationDeselectedListener() {
        @Override public void onAnnotationDeselected(@NonNull Annotation annotation, boolean reselected) {
            Log.i(TAG, "The annotation was deselected");
        }
    });

    getPdfFragment().addOnAnnotationUpdatedListener(new AnnotationProvider.OnAnnotationUpdatedListener() {
        @Override
        public void onAnnotationCreated(@NonNull Annotation annotation) {
            Log.i(TAG, "The annotation was created.");
        }

        @Override
        public void onAnnotationUpdated(@NonNull Annotation annotation) {
            Log.i(TAG, "The annotation was updated.");
        }

        @Override
        public void onAnnotationRemoved(@NonNull Annotation annotation) {
            Log.i(TAG, "The annotation was removed.");
        }
    });

    // This will remove all previously registered listeners. Instead, you could unregister them selectively.
    getPdfFragment().clearAnnotationListeners();
}

Modifying and Saving Annotations

If an annotation is modified (i.e. if it has been changed since the document has been loaded) a call to Annotation#isModified will return true. Furthermore, the PdfDocument#wasModified method will return true if annotations were added, changed, or removed. Once you save the document and its annotations, they’re no longer marked as modified.

ℹ️ Note: If you’re editing annotations using one of the annotation tools, modifications to the edited annotation and document will only be visible after you exit the current tool mode by calling PdfFragment#exitCurrentlyActiveMode. If the annotation tool is still active (i.e. the tool is selected in the annotation creation toolbar), PdfDocument#wasModified will still return false.

To save a document and its annotations, you can use any of the synchronous or asynchronous save methods on the PdfDocument class. The following example uses PdfDocument#saveIfModified, which writes the document back to its original location after testing if it has been modified:

override fun onDocumentLoaded(document : PdfDocument) {
    assert(document.wasModified() == false)

    // Add an annotation to the document.
    val annotation = NoteAnnotation(0, RectF(100, 132, 132, 100), "Test annotation", NoteAnnotation.CROSS)
    document.annotationProvider.addAnnotationToPage(annotation)

    assert(annotation.isModified() == true)
    assert(document.wasModified() == true)

    // This will write the document back to its original location.
    document.saveIfModified()

    assert(annotation.isModified() == false)
    assert(document.wasModified() == false)
}
@Override public void onDocumentLoaded(@NonNull PdfDocument document) {
    assert document.wasModified() == false;

    // Add an annotation to the document.
    NoteAnnotation annotation = new NoteAnnotation(0, new RectF(100, 132, 132, 100), "Test annotation", NoteAnnotation.CROSS);
    document.getAnnotationProvider().addAnnotationToPage(annotation);

    assert annotation.isModified() == true;
    assert document.wasModified() == true;

    // This will write the document back to its original location.
    document.saveIfModified();

    assert annotation.isModified() == false;
    assert document.wasModified() == false;
}