Save signed PDFs directly to a remote server on Android
Many apps need to let users sign PDFs (e.g. contracts, delivery confirmations) and save the signed version directly to a remote server without storing files locally.
This guide explains how to:
- Capture user annotations (like signatures).
- Flatten them into the PDF (making them permanent).
- Securely upload the modified PDF to your server.
Key challenge
- By default, annotations exist as separate layers. Without flattening, uploaded PDFs may appear unsigned.
Solution
- Flatten annotations — Merge signatures into the PDF content.
- Process asynchronously — Avoid user interface (UI) freezes during PDF processing.
- Upload from cache — Temporarily save the modified PDF to the app’s cache (not device storage).
Implementation
To flatten annotations, use PdfProcessorTask
to burn annotations into the PDF:
val task = PdfProcessorTask .fromDocument(document) .changeAllAnnotations(PdfProcessorTask.AnnotationProcessingMode.FLATTEN)
Next, generate the signed PDF in the app’s cache directory:
val outputFile = File(context.cacheDir, "signed.pdf")
PdfProcessor.processDocumentAsync(task, outputFile) .subscribeOn(Schedulers.io()) .subscribe( { /* Track progress */ }, { error -> /* Handle errors */ }, { // Upload to server after processing. lifecycleScope.launch(Dispatchers.IO) { uploadToServer(outputFile) // Clean up: Delete the cached file after upload. outputFile.delete()
} } )
Finally, implement your server upload logic in uploadToServer()
. Here’s an example using Retrofit:
private suspend fun uploadToServer(file: File) { val requestBody = file.asRequestBody("application/pdf".toMediaType()) val part = MultipartBody.Part.createFormData("file", file.name, requestBody) val response = yourApiService.uploadSignedPdf(part) // Handle response.}
Improvement ideas
Error handling
- Use
throwable.printStackTrace()
to debug processing errors. - Retry failed uploads with exponential backoff.
Security
- Validate server responses to ensure successful uploads.
- Delete cached files after upload using
outputFile.delete()
.
Improve the user experience
- For large PDFs, add a progress indicator during processing/upload.