Scan → save → send.
A deliberately simple Android document scanner for people who do not want to manage files.
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.
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.
- Direct launch into Google ML Kit Document Scanner; no redundant home-screen button.
SCANNER_MODE_FULLfor 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.
- Open the GitHub stable release.
- Download
ScanIt-v1.0.0-preview.1.apk. - 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
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
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.
- 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.
JDK 17 and Android SDK 36 are required.
./gradlew clean :app:testDebugUnitTest :app:lintDebug :app:assembleDebug :app:assembleRelease :app:bundleReleaseWindows 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.
| Area | Choice |
|---|---|
| UI | One Activity, Jetpack Compose, Material 3 |
| Scanner | Google ML Kit Document Scanner |
| Storage | MediaStore, Storage Access Framework, bounded app cache |
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 |
- 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
maxSdkblock 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
_AIfile; the immutable original remains safe. - The repository does not contain a production signing key or Gemini API key.
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.
Released under the MIT License.






