Search every PDF on your device — instantly, privately, without the cloud.
Lumen indexes the PDFs stored on your device and lets you search their full text in milliseconds. Tap any result to open the PDF at the exact matched page with the keyword highlighted.
Search is the app, not a feature. Open Lumen, type, see results. That's it.
Lumen has no INTERNET permission. The Android OS physically prevents it from making network requests — this is enforced at the manifest level, not just policy.
- No accounts or sign-in
- No file uploads
- No analytics or crash reporting
- No ads or tracking SDKs
- No cloud of any kind
Your PDFs stay on your device. The search index stays on your device. Everything stays on your device.
Verify this yourself in Settings → Privacy Audit inside the app.
- Full-text search across your entire PDF library with keyword-highlighted snippets
- Opens PDFs at the exact matched page with the search term highlighted
- OCR support for scanned (image-based) PDFs via on-device ML Kit
- In-viewer search with match navigation
- Reading progress — resumes where you left off per document
- Night mode and brightness control for the PDF viewer
- Library management — add folders, track indexing status, see per-document errors
- Privacy Audit screen — inspect every permission and confirm zero network access
- Light and dark theme (Material 3)
- Works on Android 8.0+ (API 26)
| Concern | Choice |
|---|---|
| Language | Kotlin |
| UI | Jetpack Compose + Material 3 |
| Architecture | MVVM + Repository |
| DI | Hilt |
| Database | Room + FTS4 (full-text search) |
| PDF text extraction | PdfBox-Android (Apache-2.0) |
| PDF rendering (viewer · OCR · thumbnails) | MuPDF fitz (AGPL) |
| OCR | ML Kit Text Recognition v2 (bundled, offline) |
| OCR fallback | Tesseract4Android |
| File access | Storage Access Framework (SAF) — no dangerous permissions |
| Background indexing | WorkManager |
| PDF viewer | MuPDF fitz + custom single-canvas Android View |
| Preferences | DataStore |
Requires Android Studio Ladybug (2024.2) or newer.
# Debug build
./gradlew assembleDebug
# Release bundle (for Play Store)
./gradlew bundleRelease
# Run unit tests
./gradlew test
# Run lint
./gradlew lintMinimum SDK: API 26 (Android 8.0). Target SDK: API 35.
app/src/main/java/com/lumen/app/
├── data/
│ ├── db/ — Room database, entities, DAOs, FTS4 query sanitizer
│ ├── pdf/ — PdfTextExtractor (PdfBox), PdfPageRenderer (bitmap for OCR)
│ ├── ocr/ — OcrEngine interface, MlKitOcrEngine, TesseractOcrEngine
│ ├── fs/ — SafRepository (SAF folder management), PdfScanner
│ └── repository/ — LibraryRepository, SearchRepository
├── domain/
│ ├── model/ — Document, SearchResult, SearchFilters
│ └── usecase/ — IndexLibraryUseCase, SearchUseCase, AddFolderUseCase
├── worker/ — IndexWorker (WorkManager foreground service)
└── ui/
├── theme/ — Color, Type, Theme (LumenTheme)
├── navigation/ — LumenNavGraph
├── search/ — SearchScreen, SearchViewModel
├── library/ — LibraryScreen, LibraryViewModel
├── settings/ — SettingsScreen, PrivacyAuditScreen
├── viewer/ — PdfViewerScreen, PdfViewerViewModel
└── onboarding/ — OnboardingScreen, OnboardingViewModel
- User picks a folder via SAF → URI persisted in DataStore with
takePersistableUriPermission() IndexWorker(WorkManager) walks the tree, extracts text per page via PdfBox or OCR, writes to Room FTS4- Search queries hit the FTS4 virtual table, joined with pages and documents tables
- Results flow as
StateFlow<List<SearchResult>>debounced at 200 ms
READ_EXTERNAL_STORAGE — API 26–32 only; auto-removed on API 33+
FOREGROUND_SERVICE — background indexing notification
FOREGROUND_SERVICE_DATA_SYNC
RECEIVE_BOOT_COMPLETED — reschedule indexing after reboot
WAKE_LOCK — keep CPU awake during indexing
INTERNET — intentionally absent
MANAGE_EXTERNAL_STORAGE — intentionally absent
Issues and pull requests are welcome. Please open an issue before starting significant work so we can discuss the approach.
- Follow the existing code style (Kotlin, Compose, MVVM)
- Do not add any SDK that requires network access
- Do not add the INTERNET permission under any circumstances
- Keep the APK size reasonable — avoid bundling large assets
Releases are tagged in git. master holds the latest released build; active
development happens on the develop branch.
| Version | Tag | Highlights |
|---|---|---|
| 1.2 | v1.2 |
Exact-phrase search with quotes and searchable bookmark notes, multi-word text selection in the viewer, embedded PDF metadata titles and author (DB v14), reading progress on recents and library cards, rename-the-file-on-device, file location with open-folder shortcut in document details, a 2-tab merged layout option with a seamless switch, launcher shortcuts / search widget / "Search in Lumen" on selected text, folder quick-picks in onboarding, sharp rendering and working OCR for very tall single-page PDFs, and a large stability pass across rename, indexing, and viewer lifecycle. |
| 1.1 | v1.1 |
Page-level FTS index (DB v7) with relevance ranking and grouped results, search filters (folders, OCR-only, sort, indexed date) with always-visible reset, incremental rescan, viewer zoom pill with live percentage, print and save-a-copy, notification permission flow, and release signing under the new io.github.royalgillz.lumen application ID. |
| 1.0 | v1.0 |
First complete build — offline FTS4 full-text search, MuPDF PDF viewer with occurrence-level in-document search and keyword highlighting, OCR highlight boxes for scanned pages, Drive-style fast-scroll thumb, device-aware viewer memory bounds, and the privacy-first Library/Settings design. |
1.2
- Search: exact phrases with double quotes ("invoice 4471" means those words together), bookmark notes included in results with a note badge, consistent counts and highlights for phrase matches
- Viewer: multi-word text selection with drag handles and copy/share, sharp region rendering for very tall single-page pages (scanned notes exports), password retry feedback, resume and highlight fixes
- Library: rename can now also rename the file on device (with safe two-step case-only renames), document details show pages/size/author and the file's location with an open-folder shortcut, reading progress ("p. 34 of 120 · 28%") on recents and cards
- Titles: embedded PDF metadata title and author feed the display-title pipeline through a junk-filtering gate (DB v13/v14)
- Navigation: optional 2-tab merged Documents layout with an instant, flicker-free switch; back handling keeps the bar's home consistent in both modes
- Getting started: Downloads/Documents quick-pick chips in onboarding and the empty library
- Launcher: static Search shortcut, home-screen search widget, "Search in Lumen" on text selected anywhere, and recent documents as app-icon shortcuts
- Very tall pages now index correctly via strip-based OCR with accurate search highlights
- Stability: dozens of fixes across rename, folder removal, index wipe atomicity, viewer render lifecycle, and search-result snippets
1.1
- Search rebuilt on a page-level FTS index (DB v7): results grouped by document with per-page hit counts, relevance ranking with filename boost, fixed AND-literal queries
- Search filters: folder, OCR-only, sort order, and indexed-date (Any time / Today / This week / This month) with an always-visible Reset and active-filter chips
- Incremental library rescan and smarter OCR page selection during indexing
- Viewer: zoom pill with live percentage (tap to reset to 100%), print, save-a-copy, word selection via long-press, page snapping, accessibility announcements, highlight auto-pan and state-leak fixes
- Bottom navigation: bold forest-green selected state; terracotta accent refinements across the app
- Android 13+ notification permission request for indexing progress; INTERNET permission force-removed from merged manifest (ML Kit transport dependency) so the app physically cannot go online
- Release signing config and new application ID
io.github.royalgillz.lumen
1.0
- Full-text search across indexed PDFs (filename · page · snippet)
- PDF viewer: in-document search stepping every occurrence, amber keyword highlights, internal/external links, resume-at-last-page, brightness, scroll-mode toggle, share via overflow menu
- Highlighting on scanned pages from OCR word boxes captured at index time
- Fast-scroll thumb with page bubble (vertical mode)
- Bounded viewer memory (single render gate, device-aware bitmap cache, trim-on-pressure)
- Library: stats, Error Center for failed/encrypted files, force re-index
- Privacy Audit screen; no
INTERNETpermission
Apache-2.0 — see LICENSE.