Managing data storage and privacy in Android

When auditing your app’s data practices, it’s important to understand how Nutrient Android SDK handles data storage, caching, and privacy. This guide explains where and how data is stored locally, and how you can maintain control over data retention and security.

No external data transmission

Nutrient Android SDK operates entirely on-device with no external data transmission. All PDFs, annotations, and metadata remain on the device. The SDK doesn’t send any document data, annotations, or user information to external servers unless you explicitly implement such functionality in your application.

For information about network access used by the SDK itself, refer to our SDK security guide.

Data storage overview

The SDK manages different types of data with varying persistence and cleanup strategies, as detailed below.

Temporary files and caches

The SDK uses Android’s cache directory for temporary data that improves performance but isn’t essential to preserve. This data is stored in cache/nutrient within your app’s cache directory.

Cache types and management

Bitmap memory cache

  • Purpose — Stores prerendered page bitmaps for fast display
  • Size limit — 15 MB by default
  • Eviction — Least recently used (LRU) items removed when limit exceeded
  • Memory pressure — Automatically released when Android signals low memory

Rendered page cache

Automatic cleanup

The Android operating system may clear cache files when:

  • The device is running low on storage
  • The user manually clears app cache via Settings
  • The app is uninstalled

For more information about cache configuration and memory optimization, refer to our memory usage guide.

Clearing caches programmatically

You can manually clear caches when needed:

Kotlin
// Clear Nutrient's bitmap memory cache.
Nutrient.clearCaches()
// Clear all app cache files (including Nutrient's disk cache).
context.cacheDir.deleteRecursively()

Persistent data

Persistent data includes PDFs, annotations, and document state that should be retained across app sessions.

Annotation storage

Annotations are stored differently depending on whether a PDF is writeable.

Writeable PDFs

  • Annotations are saved directly into the PDF file using AnnotationProvider
  • Data persists as part of the PDF document
  • No separate annotation files are created

Read-only PDFs

For read-only documents where you still want users to edit and save annotations, use the Save As functionality to save the modified document to a new writeable location. Refer to the how to save documents as PDFs on Android guide for implementation details.

To learn more about annotation saving mechanism, refer to the save PDF annotations on Android guide.

Document state

Nutrient Android SDK maintains an internal SQLite database that stores document preferences:

  • Last viewed page position
  • Selected annotation tool
  • User interface (UI) state preferences

Important characteristics

  • Does not store annotations — Only UI state and preferences
  • Automatic cleanup — Old data is automatically pruned to keep storage manageable
  • Transient data — Safe to delete without losing document content or annotations

Auto-save behavior

Auto-save triggers when the fragment’s onStop() is called, which happens when:

  • App is backgrounded
  • Activity is no longer visible
  • Configuration changes (for example, screen rotation) since it destroys and recreates the activity, triggering onStop()

You can monitor or customize this behavior as demonstrated below:

Kotlin
// Disable auto-save if needed.
val config = PdfConfiguration.Builder()
.autosaveEnabled(false)
.build()
// Monitor save events with `DocumentListener`.
pdfFragment.addDocumentListener(object : DocumentListener {
override fun onDocumentSaved(document: PdfDocument) {
// Handle successful save.
Log.d("App", "Document saved successfully")
}
override fun onDocumentSaveFailed(document: PdfDocument, error: Throwable) {
// Handle save failure.
Log.e("App", "Document save failed", error)
}
})

For advanced save configuration, including checkpointing, refer to our auto save guide.

Manual save operations

You can programmatically save documents and annotations at any time:

Kotlin
// Synchronous save (blocks until complete).
document.saveIfModified()
// Asynchronous save with callback.
pdfFragment.saveAsync().subscribe(object : SimpleCompletableObserver() {
override fun onComplete() {
// Document saved successfully
}
override fun onError(e: Throwable) {
// Handle save error.
}
})

Security and privacy considerations

An app’s private storage is protected by Android’s sandboxing mechanisms, ensuring other apps cannot access your app’s files. Below are some best practices to enhance data security and privacy.

App sandbox protection

All files created by Nutrient Android SDK reside in your app’s private storage, which is protected by Android’s application sandboxing:

  • Other apps cannot access your app’s private files
  • Files are automatically deleted when the app is uninstalled
  • Root access or compromised devices bypass these protections

Read-only PDF annotations

For read-only PDFs, annotation files are stored separately and persist until explicitly deleted. If you need to implement data retention policies for compliance, use the following:

Kotlin
// Custom retention: Delete old annotation files after a certain period.
fun cleanupOldAnnotations(maxAgeInDays: Int) {
val annotationDir = File(context.filesDir, "annotations")
val cutoffTime = System.currentTimeMillis() - (maxAgeInDays * 24 * 60 * 60 * 1000L)
annotationDir.listFiles()?.forEach { file ->
if (file.lastModified() < cutoffTime) {
file.delete()
}
}
}

Screenshot prevention

By default, Nutrient doesn’t prevent screenshots. To prevent screenshot capture for sensitive documents, you can set the FLAG_SECURE flag on your activity’s window:

Kotlin
// In your activity.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Prevent screenshots and screen recording.
window.setFlags(
WindowManager.LayoutParams.FLAG_SECURE,
WindowManager.LayoutParams.FLAG_SECURE
)
}

Compliance and data retention

We recommend the following practices to help ensure compliance with data protection regulations such as General Data Protection Regulation (GDPR).

GDPR and privacy compliance

To ensure compliance with data protection regulations:

  1. Document what data is stored — PDFs, annotations, document state, and cache files
  2. Implement data deletion — Clear caches and delete annotation files when users delete documents
  3. Respect user privacy — No data leaves the device unless you implement sync features
  4. Provide transparency — Inform users about local storage in your privacy policy

Custom storage paths

If you need to control where documents and annotations are stored, you can implement a custom data provider by extending the WriteableDataProvider interface. This enables you to define your own storage logic and paths:

Kotlin
// Use a custom data provider for full control.
class CustomDataProvider(private val customPath: String) : WriteableDataProvider {
// Implement custom storage logic.
// This gives you full control over where and how data is stored.
}
// Open document with custom provider.
val document = PdfDocumentLoader.openDocument(
context,
CustomDataProvider("/custom/path/document.pdf")
)

For more information about custom data providers, refer to our custom data provider guide.