Skip to content

Repository files navigation

ScanIt — document scanning on Android

ScanIt

Scan → save → send.
A deliberately simple Android document scanner for people who do not want to manage files.

Android CI Latest release Android 15+ Kotlin 2.2.10 MIT License

ScanIt settings, scan result, and optional AI controls

Why ScanIt exists

Sending a scanned document should not require understanding folders, file managers, or export dialogs. Opening ScanIt launches the scanner directly. After capture, the result is ready to share as a PDF or images through Android's system share sheet.

The monochrome interface follows the system language by default. English and Czech can also be selected in settings. Complete options stay behind the gear icon; experimental cloud AI stays under Advanced and is off by default.

ScanIt was built with AI-assisted coding and design. The source, builds, and real-device workflows were reviewed and tested by its maintainer.

Interface

Presentation images are based on the tested device workflow and were refined with OpenAI ImageGen for presentation. They use an original generated QA rhythm sheet; status bars are standardized to 12:12 and stripped of device-identifying icons.

ScanIt settings ScanIt scan result

ML Kit camera scanning an original QA rhythm sheet for ScanIt ML Kit scan editor opened by ScanIt

ScanIt advanced optional AI settings

Features

  • Direct launch into Google ML Kit Document Scanner; no redundant home-screen button.
  • SCANNER_MODE_FULL for crop, perspective correction, rotation, filters, and document cleanup.
  • Single-page or multi-page scans with JPEG and PDF output.
  • JPEG pages saved to Gallery and PDFs saved to Downloads by default.
  • Automatic PDF saving is on by default and can be disabled in settings; a temporary PDF remains available for sharing.
  • Optional user-selected PDF folder through Android's Storage Access Framework.
  • One-tap PDF/image sharing with attachment, subject, and message prepared.
  • System printing with page-range support.
  • Monochrome light/dark UI, system/English/Czech language selection, safe insets, and accessible touch targets.
  • No account, first-party analytics, ads, user-visible history, database, or broad storage permission.
  • Optional Gemini image cleanup with explicit consent, encrypted user-owned API key, immutable original, and before/after review.

Install

  1. Open the GitHub stable release.
  2. Download ScanIt-v1.0.0-preview.1.apk.
  3. Allow installation from the app used to download the file, then open the APK.

The GitHub stable APK is the frozen legacy sideload build. It remains debug-signed so its existing artifact and checksum do not change. The experimental Google Play build uses the permanent com.majkeylab.scanit package and installs separately; settings, API keys, and temporary cache do not migrate between the two. Files already saved to Gallery, Downloads, or a selected folder remain.

Requirements:

  • Android 15 or newer (minSdk 35, targetSdk 36)
  • At least 1.7 GB total device RAM, required by ML Kit Document Scanner
  • Google Play services for the scanner module
  • Internet on first scanner use if Google Play services needs to download that module

How it works

flowchart LR
    A["Launch ML Kit scanner"] --> B["Private bounded cache"]
    B --> C["Gallery + PDF"]
    B --> D["Sharesheet / Print"]
    B -. "optional" .-> E["Gemini AI copy"]
    E --> F["Original vs AI review"]
    F -->|Accept| G["Separate _AI files"]
    F -->|Discard| B
Loading

The original ML Kit scan is never overwritten. ScanIt retains at most eight temporary scan directories so an already-open mail draft does not immediately lose its attachment. It has no user-visible document history or document database.

Advanced AI mode

AI cleanup is experimental, optional, disabled by default, and has not been live-verified with a Gemini API key. The user must enable it, accept the cloud-transfer warning, and provide a key. Every page in the current scan is sent to Gemini sequentially. The key is encrypted with Android Keystore, and requests use the stable Interactions API with store=false.

Generated output can alter text, numbers, signatures, stamps, or layout. ScanIt therefore requires an explicit original/AI review before saving separate _AI files. A public Google Play release should replace the client-side key path with Firebase AI Logic plus App Check/Play Integrity or a backend.

Privacy and security

  • Local copies are saved to Gallery and Downloads by default; sharing, printing, and optional AI transfer require an explicit action.
  • ScanIt includes no first-party analytics or advertising. Google Play services and ML Kit may collect diagnostic, usage, device, app, identifier, and API-configuration data described in Google's ML Kit data disclosure.
  • ScanIt does not send scanned content to its own server.
  • FileProvider exposes only the bounded cache/share/ directory and grants read access to selected files.
  • No CAMERA, legacy storage, contacts, account, location, or notification permission is requested.
  • Android backup and device transfer are disabled for app data.
  • Gemini requests use explicit connect/read timeouts, do not follow redirects, and disconnect on cancellation.

Read the complete privacy notes and security policy.

Build

JDK 17 and Android SDK 36 are required.

./gradlew clean :app:testDebugUnitTest :app:lintDebug :app:assembleDebug :app:assembleRelease :app:bundleRelease

Windows users can run the checked helpers:

.\tools\build.ps1
.\tools\verify-apk.ps1 .\app\build\outputs\apk\release\app-release.apk
CLI tool Purpose
tools/build.ps1 Runs the full local test, lint, APK, and AAB gate with JDK 17 validation.
tools/verify-apk.ps1 Verifies the non-debuggable signed Play package, 16 KiB alignment, signature, and SHA-256.

Release signing reads the ignored local keystore.properties file when present. Signing keys and passwords never enter Git. GitHub Actions runs the test/lint/build gate with unsigned CI artifacts on every push to main and every pull request. Dependabot checks Gradle and Actions dependencies weekly.

Technical choices

Area Choice
UI One Activity, Jetpack Compose, Material 3
Scanner Google ML Kit Document Scanner
Storage MediaStore, Storage Access Framework, bounded app cache
PDF Android PdfDocument / PrintedPdfDocument
Sharing Android Sharesheet + scoped FileProvider
Settings SharedPreferences
Secret storage AES-GCM key held by Android Keystore
Optional AI Gemini Interactions API, store=false

Known limits

  • Android decides which compatible apps appear in the Sharesheet; it cannot guarantee an email-only list while also reliably attaching the file.
  • Android 17 has no maxSdk block and should remain installable, but it has not been device-tested yet.
  • The experimental Gemini workflow has not been live-verified with an API key.
  • The current Google Play build is an internal alpha and is not a public production release.
  • Hard process termination during multi-file AI publication can leave an already-published _AI file; the immutable original remains safe.
  • The repository does not contain a production signing key or Gemini API key.

Feedback

Suggestions and reproducible bug reports are welcome through GitHub Issues or at majkeylab@gmail.com. Never send private documents, API keys, or other sensitive data.

License

Released under the MIT License.

About

Simple, ad-free Android document scanner: scan, save, and share PDF.

Topics

Resources

Security policy

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages