Export and Share

How Scanly generates PDFs and image archives for documents and groups.

Overview

DefaultDocumentExportRepository (data/export/) handles all export and share operations. ViewModels call export use cases; use cases delegate to the repository.

Export types

Single document

TypeUse caseOutput
PDFExportDocumentPdfUseCaseSingle PDF in export cache
Image archiveExportDocumentImageArchiveUseCaseZIP of processed JPEGs
Share PDFPrepareDocumentPdfShareUseCaseShareArtifact with FileProvider URI
Share imagesPrepareDocumentImageShareUseCaseShareArtifact with FileProvider URI

Group

TypeUse caseOutput
Merged PDFExportGroupPdfUseCaseOne PDF with all pages from all group documents
Zipped PDFsExportGroupZippedPdfsUseCaseZIP with one PDF per document
Share merged PDFPrepareGroupPdfShareUseCaseShare artifact
Share zipped PDFsPrepareGroupZippedPdfsShareUseCaseShare artifact

PDF generation

Uses Android PdfDocument for page rendering. Password-protected output is then encrypted with PdfBox-Android using AES and a 256-bit encryption key. The temporary unprotected file is deleted immediately after encryption.

Options (PdfExportOptions)

OptionValues
PasswordOff, or a validated 4–64 character open password
Page numberNone, lower left, bottom center, lower right
Page sizeAuto fit, A3, A4, A5, B4, B5, Letter, Tabloid, Legal, Executive, Postcard, American foolscap, European foolscap
OrientationAuto per page, portrait, landscape
MarginsNone, small, large

Fixed paper sizes are encoded in PostScript points (72 points per inch), so exported PDFs retain real print dimensions. Auto fit uses each source image's aspect ratio with an A4-length long edge. When numbering is enabled, the renderer reserves a footer instead of drawing over the scan.

Page source

  • Uses processed image paths from Room
  • Falls back to raw if processed is unavailable
  • Pages rendered in pageIndex order

Group merged PDF

  1. Load all documents in group (sorted by title).
  2. For each document, load pages in index order.
  3. Append all pages sequentially into one PDF.
  4. Page numbers, when enabled, continue across document boundaries.

Group zipped PDFs

  1. Generate one PDF per document in the group.
  2. Package all PDFs into a single ZIP.
  3. Page numbers, when enabled, restart at 1 for each PDF.

Image archive

ZIP containing processed JPEGs (raw fallback) for all pages in a document. One file per page, named by page index.

Export cache paths

cache/exports/{documentId}/          # Document exports
cache/exports/group_{groupId}/       # Group exports

Cache is ephemeral — safe to delete without losing library data. Included in storage usage and cleared by clear-all-data.

Save destination

Save actions copy generated artifacts directly to the configured base folder. The default uses MediaStore.Downloads with Download/Scanly; a custom folder uses its persisted Storage Access Framework tree. Filename collisions receive (n) suffixes. The dedicated lowercase backup/ child is reserved for .scanly library archives and is never used for normal PDF/image exports.

Share flow

  1. Export repository writes file to cache.
  2. Returns ShareArtifact or ExportArtifact with file path.
  3. ViewModel creates FileProvider URI: ${applicationId}.fileprovider
  4. Android share sheet opens with grantUriPermissions.

FileProvider configured in AndroidManifest.xml with paths in res/xml/file_paths.xml.

Progress reporting

Group export operations support progress callbacks consumed by GroupDetailViewModel for UI progress indicators during long exports.

Domain models

ModelPurpose
PdfExportOptionsPDF layout configuration
ExportArtifactExport result with file path
ShareArtifactShare-ready result with URI metadata

View source on GitHub · Markdown