How to save documents as PDFs on Android
Use Save As to save a modified PDF to a new location without overwriting the original.
Since Nutrient Android SDK 12.0, PdfActivity and PdfUiFragment include a Save As dialog. Open Save As… next to Open in the sharing menu. For a custom button, call showSaveAsDialog().
The dialog enables users to choose the copy’s name, page range, and destination. If the original document isn’t writable, Nutrient displays the copy and applies subsequent edits to it. Otherwise, Nutrient writes the copy but keeps the original open.
To build a custom Save As flow, follow these steps:
- Add a Save As button to the toolbar.
- Start a file picker with
Intent.ACTION_CREATE_DOCUMENTwhen the user taps the button. - Save the document to the selected destination.
For toolbar customization, refer to the customizing menus guide. Implement a picker using the Android guidelines(opens in a new tab), or use Nutrient’s internal picker.
Access the internal picker through thumbnailGrid in PdfActivity or PdfUiFragment. The internal picker requires RxJava.
Use save for synchronous saving or saveAsync for asynchronous saving. Both methods accept a file path and support overloads with save options. The following example saves to a temporary file before copying it to the selected URI:
getPSPDFKitViews() .getThumbnailGridView() .getFilePicker() .getDestinationUri(Intent.ACTION_CREATE_DOCUMENT) // Saving and copying block, so leave the main thread first. .observeOn(Schedulers.io()) .map(uri -> { // The picker returns a URI, but the save functions take a file path. // Save to a temporary file, then copy it to the picked URI. final File tempFile = File.createTempFile("save-as", ".pdf", getCacheDir()); try { // Call one of our saving methods here. document.save(tempFile.getAbsolutePath()); try (InputStream input = new FileInputStream(tempFile); OutputStream output = getContentResolver().openOutputStream(uri, "w")) { if (output == null) throw new IOException("Can't write to " + uri); final byte[] buffer = new byte[8192]; int read; while ((read = input.read(buffer)) != -1) { output.write(buffer, 0, read); } } } finally { tempFile.delete(); } return uri; }) .observeOn(AndroidSchedulers.mainThread()) .subscribe( // `onSuccess` (a file was selected and the document was saved to it). (uri) -> {
}, // `onError` (something happened). (throwable) -> {
}, // `onComplete` (== filepicker operation was canceled). () -> {
} );