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.

Information

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;
}