---
title: "Save PDF annotation on Android | Nutrient SDK"
canonical_url: "https://www.nutrient.io/guides/android/annotations/annotation-saving-mechanism/"
md_url: "https://www.nutrient.io/guides/android/annotations/annotation-saving-mechanism.md"
last_updated: "2026-06-08T09:14:14.281Z"
description: "By default, Nutrient will save annotations asynchronously and automatically when the onStop() lifecycle event is called."
---

# Save PDF annotations on Android

By default, Nutrient will save annotations asynchronously and automatically when the `onStop()` lifecycle event is called.

Nutrient can write annotations into a PDF under the following conditions:

- The PDF must be in a writeable location. This means that it either has to be in a writeable directory on the file system, or the `ContentProvider` from which the file is loaded must allow saving. For maximum performance, ask for `WRITE_EXTERNAL_STORAGE` permission when opening files from external storage. This will allow Nutrient to bypass the slow `ContentProvider` APIs.

- If the PDF was opened from a custom [`DataProvider`](https://www.nutrient.io/api/android/nutrient/com.pspdfkit.document.providers/-data-provider/index.html), it has to implement [`WriteableDataProvider`](https://www.nutrient.io/api/android/nutrient/com.pspdfkit.document.providers/-writable-data-provider/index.html) and properly handle writing to a file.

- The PDF must be valid according to the Adobe PDF specification. Some PDFs are broken but still work somewhat, so Nutrient can render the content. If Nutrient detects a mismatch in the object tree or is unable to find objects, annotation saving will be stopped, since there would be a risk of damaging the document.

## Annotation saving

By default, Nutrient auto saves changes to a document and to annotations inside `PdfFragment#onStop` — effectively, this means every time the fragment is sent to the background, e.g. when switching to another application or when leaving the viewer activity. You can disable auto saving via the [`#autosaveEnabled`](https://www.nutrient.io/api/android/nutrient/com.pspdfkit.configuration/-pdf-configuration/-builder/autosave-enabled.html) setter on the [`PdfConfiguration.Builder`](https://www.nutrient.io/api/android/nutrient/com.pspdfkit.configuration/-pdf-configuration/-builder/index.html):

### KOTLIN

```kotlin

// By default, auto save is enabled.
val config = PdfConfiguration.Builder().autosaveEnabled(false).build()

val fragment = PdfFragment.newInstance(documentUri, config)...

```

### JAVA

```java

// By default, auto save is enabled.
final PdfConfiguration config = new PdfConfiguration.Builder().autosaveEnabled(false).build();

final PdfFragment fragment = PdfFragment.newInstance(documentUri, config);...

```

If you’re using the [`PdfActivity`](https://www.nutrient.io/api/android/nutrient/com.pspdfkit.ui/-pdf-activity/index.html), you can also deactivate auto save via the [`#autosaveEnabled`](https://www.nutrient.io/api/android/nutrient/com.pspdfkit.configuration.activity/-pdf-activity-configuration/-builder/autosave-enabled.html) setter of the [`PdfActivityConfiguration.Builder`](https://www.nutrient.io/api/android/nutrient/com.pspdfkit.configuration.activity/-pdf-activity-configuration/-builder/index.html):

### KOTLIN

```kotlin

// By default, auto save is enabled.
val config = PdfActivityConfiguration.Builder(context).autosaveEnabled(false).build()

PdfActivity.showDocument(context, documentUri, config)...

```

### JAVA

```java

// By default, auto save is enabled.
final PdfActivityConfiguration config =
    new PdfActivityConfiguration.Builder(context).autosaveEnabled(false).build();

PdfActivity.showDocument(context, documentUri, config);...

```

### 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`](https://www.nutrient.io/api/android/nutrient/com.pspdfkit.annotations/-annotation/is-modified.html) will return `true`. Furthermore, the [`PdfDocument#wasModified`](https://www.nutrient.io/api/android/nutrient/com.pspdfkit.document/-pdf-document/was-modified.html) 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.

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`](https://www.nutrient.io/api/android/nutrient/com.pspdfkit.document/-pdf-document/index.html)&nbsp;class. The following example uses [`PdfDocument#saveIfModified`](https://www.nutrient.io/api/android/nutrient/com.pspdfkit.document/-pdf-document/save-if-modified.html), which writes the document back to its original location after testing if it has been modified:

### KOTLIN

```kotlin

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

```

### JAVA

```java

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

```

### Document-saving callbacks

The [`DocumentListener`](https://www.nutrient.io/api/android/nutrient/com.pspdfkit.listeners/-document-listener/index.html) interface provides three callback methods that allow you to listen to and intercept saving attempts. [`#onDocumentSave(PdfDocument, DocumentSaveOptions)`](https://www.nutrient.io/api/android/nutrient/com.pspdfkit.listeners/-document-listener/on-document-save.html) is called right before the [`PdfFragment`](https://www.nutrient.io/api/android/nutrient/com.pspdfkit.ui/-pdf-fragment/index.html) or the [`PdfActivity`](https://www.nutrient.io/api/android/nutrient/com.pspdfkit.ui/-pdf-activity/index.html) save a document, allowing you to alter the [`DocumentSaveOptions`](https://www.nutrient.io/api/android/nutrient/com.pspdfkit.document/-document-save-options/index.html) or cancel the saving attempt completely by returning `false`.

Saving callbacks aren’t called when using the [`PdfDocument`](https://www.nutrient.io/api/android/nutrient/com.pspdfkit.document/-pdf-document/index.html) save methods directly, but only when the fragment or activity is saving the document — for example, when auto save is enabled or when you explicitly call `fragment.save()`.

### KOTLIN

```kotlin

/**
 * The password used to save the document may be null. Your app can
 * ask for this prior to saving.
 */
private var documentPassword : String? = null

override fun onDocumentSave(document : PdfDocument, saveOptions : DocumentSaveOptions) : Boolean {
    saveOptions.setPassword(documentPassword)

    // By returning `true`, saving is continued. Alternatively, you could return `false` to cancel saving.
    return true
}

```

### JAVA

```java

/**
 * The password used to save the document may be null. Your app can
 * ask for this prior to saving.
 */
private String documentPassword;

@Override
public boolean onDocumentSave(PdfDocument document, DocumentSaveOptions saveOptions) {
    saveOptions.setPassword(documentPassword);

    // By returning `true`, saving is continued. Alternatively, you could return `false` to cancel saving.
    return true;
}

```

The [`DocumentListener#onDocumentSaved(PdfDocument)`](https://www.nutrient.io/api/android/nutrient/com.pspdfkit.listeners/-document-listener/on-document-saved.html) method is called after the document has been successfully saved. If the document couldn’t be saved due to an error, the [`#onDocumentSaveFailed(Throwable)`](https://www.nutrient.io/api/android/nutrient/com.pspdfkit.listeners/-document-listener/on-document-save-failed.html) method is called instead, and it passes in the `exception` that caused the failure:

### KOTLIN

```kotlin

override fun onDocumentSaved(document : PdfDocument) {
    Toast.makeText(context, "Document successfully saved.", Toast.LENGTH_SHORT).show()
}

override fun onDocumentSaveFailed(exception : Throwable?) {
    AlertDialog.Builder(context).setMessage("Error while saving the document. Please try again.").show()
}

```

### JAVA

```java

@Override
public void onDocumentSaved(@NonNull PdfDocument document) {
    Toast.makeText(context, "Document successfully saved.", Toast.LENGTH_SHORT).show();
}

@Override
public void onDocumentSaveFailed(Throwable exception) {
    new AlertDialog.Builder(context).setMessage("Error while saving the document. Please try again.").show();
}

```

We also have an [extensive guide about the `DocumentListener` interface](/guides/android/).
---

## Related pages

- [Embed annotations in a PDF file on Android](/guides/android/annotations/save/embed-into-pdf.md)
- [Save PDF annotations to an external source on Android](/guides/android/annotations/save/to-external-source.md)
- [Auto save PDF annotations on Android](/guides/android/annotations/annotation-and-bookmark-saving-triggers.md)

