XReader is a native Android e-reader focused on a fast, private reading loop for DRM-free personal libraries. It imports books through Android's Storage Access Framework, copies them into app-owned storage, and keeps reading state, notes, bookmarks, search data, dictionary lookup, and analytics local to the device.
The 2026-09-09 code and documentation review covers the current persistence, import, performance, and UI polish pass. Its verification is build-only; historical device results do not validate these changes.
This repository is an early personal APK build. The core reader path is real and device-tested, but the app is not packaged for Play Store distribution yet.
Implemented:
- EPUB and PDF reading through Readium Kotlin.
- TXT import converted into chaptered EPUB when headings are present, with legacy text decoding and the same private-library and reader path.
- CBZ import converted into fixed-layout EPUB so comic/image archives use the same private-library and reader path.
- FB2 and zipped
.fb2.zipimport converted into EPUB with FictionBook metadata, chapters, series, and embedded cover support. - RTF import converted into EPUB with title/author metadata and searchable text extraction.
- DRM-free legacy MOBI/PRC/PalmDOC import converted into EPUB with title/author metadata and searchable text extraction.
- ODT import converted into EPUB with OpenDocument metadata, headings, paragraphs, lists, tables, and searchable text extraction.
- DOCX import converted into EPUB with document metadata, headings, paragraphs, lists, tables, and searchable text extraction.
- HTML, HTM, and XHTML import converted into EPUB with page metadata, headings, lists, tables, blockquotes, and searchable text extraction.
- MHTML and MHT web-archive import converted into EPUB with page metadata, embedded image assets including lazy/responsive image references, headings, lists, tables, blockquotes, and searchable text extraction.
- Markdown import converted into EPUB with front matter metadata, headings, lists, blockquotes, code blocks, and searchable text extraction.
- Private app-library imports from selected files, SAF folders, Android Open with/Share actions, direct supported book URLs, or optional redirect-aware OPDS Atom/JSON catalog URLs, with checksum duplicate detection, missing private-file recovery on re-import, and an
Openaction after single-book imports or duplicate re-imports. - Library organization by books, authors, series, genres, formats, years, custom collections, recent, unread, in progress, finished, and favorites, with group-aware ordering and a persisted selected group.
- Home-screen series continuation that suggests the next unfinished title after the most recently finished book in a series.
- Persisted library sort and comfortable/compact density controls that apply in grouped and ungrouped views.
- Compact book actions for custom collections, favorites, manual finished/not-finished state, metadata edits, save-copy export, and undoable removal.
- Per-book "save copy" export through Android's document picker, writing the actual private reader file without broad storage access.
- Metadata editing for title, author, year, genre, series, series order, compact existing-value suggestions, automatic author/genre/series canonicalization, same-author series/order inference from common title patterns, opt-in bulk cleanup, and Settings repair for obvious same-series genre drift.
- Covers, including EPUB guide/title-page cover references, metadata extraction, manual cover replacement, per-book health checks, and repair/reindex actions.
- Resume from persisted Readium locators with percent read and progress state.
- Swipe, calibrated tap-zone, hardware-key, optional volume-button, searchable TOC/bookmark/note navigation, search-result, find-next/find-previous, and scrubber navigation.
- Reader themes: light, dark, sepia, and OLED black.
- Reader typography and behavior controls: spacing presets, font size, font weight, line height, margins, alignment, hyphenation, publisher styles, PDF fit/layout, page direction, reader-only orientation, fullscreen, keep-screen-awake, app-local reader dimming, page animation toggle, tap-zone sizing, optional volume-button page turns, real Readium/CSS-resolvable font choices including OpenDyslexic, and per-book appearance overrides.
- Read aloud from the visible reading position through Android TextToSpeech using page-aligned local indexed book text, with persisted spoken position, pause/resume, previous/next passage controls, speech speed, visible sleep timer countdown, installed offline voice selection, audio-focus handling, Android media-session transport controls, and a media-playback foreground notification for headset/Bluetooth/play-pause/next/previous/stop actions while outside the reader.
- Searchable grouped Settings screen for reader appearance, typography, reading behavior, library display, and maintenance.
- Bookmarks, highlights, tagged notes, global notes with tag filtering, in-book annotation lists, human-readable Markdown notes export, legacy notes/library JSON compatibility tools, and a primary bounded
.xreader-backupZIP with per-section size, count, and SHA-256 validation. The archive covers catalog metadata, collections, progress, sessions, settings, per-book appearance, notes, highlights, tags, bookmarks, imported-audiobook metadata/playback state, and narration preferences without embedding private media files or paths. - Offline English dictionary backed by bundled Princeton WordNet data, with phrase, hyphenated-word, plural, possessive, comparative, superlative, adverb, and common irregular lookup.
- Local full-text search index for imported book text where extraction is supported, including punctuation-safe queries, cleaned PDF text extraction for wrapped words, source-book labels, query-centered snippets, and expandable library search results.
- Reading analytics for sessions, active reading time, progress, estimated WPM, reader/home ETA, 7-day/30-day/13-week/all-time activity, streaks, book/author/genre summaries, and local CSV/JSON export.
- Embedded Kokoro v1.0 audiobook generation is under active hardening: preview and full-book generation are constrained to one packaged strict QNN HTP/NPU provider, with prepared fixed-bucket artifacts gated by device proof and a strict compatibility manifest rather than fallback providers. Long jobs persist heartbeat progress, ETA, partial playback state, and stop/retry controls while the app continues to target faster-than-realtime hardware generation.
- Imported audiobook persistence and playback are in the current development checkpoint: MP3, M4B/M4A/AAC, OGG/Opus, FLAC, and WAV can be validated with Android's media parser, checksum-grouped, copied into app-private storage, chaptered from supported container metadata, resumed, and controlled through a separate MediaSession/foreground-service lifecycle. The Audiobooks surface includes seek, persisted 0.5–3× playback speed, a 15/30/45/60-minute sleep timer, chapter selection, and deletion confirmation. Android Open with/Share failures are shown explicitly. Codec, notification, and foldable UI acceptance remain pending on hardware.
- Neural narration preparation now preserves non-adjacent repeated passages, removes only structurally evidenced boilerplate, reports exclusions with reasons, blocks unsupported non-English neural generation honestly, applies bounded exact-phrase pronunciation rules, and provides a per-book pre-generation source review whose decisions are persisted and backed up.
.acsmfiles are recognized as Adobe license instructions and handed off externally with an explicit no-DRM-removal explanation; they are never imported as ebooks.- Clear unsupported-format feedback for modern Kindle AZW/AZW3/KF8/KFX and other deferred formats, without surfacing fake conversion controls in the app.
- Public-domain book fixture coverage for TXT/EPUB import paths.
Full-backup imports now accept the exported ZIP MIME type and retain a per-section report under Settings → Maintenance → Show last restore details. Reimport the original missing books/audio and retry the same backup to restore remaining references. Archives contain metadata and reading state, not the original media.
Not implemented in the UI:
- AZW/AZW3/KF8/KFX conversion.
- CBR/DJVU/legacy binary DOC import.
- DRM handling.
- Cloud sync.
- Ads, subscriptions, or social features.
- macOS, Linux, or Windows with Android SDK tooling.
- JDK 21.
- Android Studio or command-line Android SDK.
- Android device or emulator running API 26 or newer.
The project uses Gradle 9.5.1 wrapper, Android Gradle Plugin 9.2.1, Kotlin 2.3.21, compileSdk 36, and minSdk 26.
./gradlew clean :app:lintDebug :app:testDebugUnitTest :app:assembleDebug :app:assembleDebugAndroidTest :app:lintRelease :app:assembleRelease :app:verifyReleasePackaging --console=plainassembleDebugAndroidTest proves the migration tests compile. Running those tests still requires an emulator or device. verifyReleasePackaging inspects the actual unsigned release APK, enforces the 210 MiB ceiling, checks the explicit QNN duplicate allowlist, and rejects prohibited GPU/OpenCL fallback runtimes.
Latest completed release gate (2026-08-30, current paused audiobook/backup checkpoint): 622 JVM tests passed with no failures or skips, both lint variants completed with zero errors and 41 warnings, all three APK assemblies passed, and the unsigned release APK passed packaging verification at 210,485,914 bytes against the 220,200,960-byte ceiling. No new device, visual, accessibility, Readium-runtime, foreground-service, codec, migration-runtime, thermal, or QNN throughput acceptance is claimed for the checkpoint.
The debug APK is written to:
app/build/outputs/apk/debug/app-debug.apk
Install on a connected device:
adb install -r app/build/outputs/apk/debug/app-debug.apk
adb shell am start -n com.xreader.app/.MainActivityHardware target for future runtime acceptance:
- Samsung SM-F966U foldable phone, Android 16 / API 36.
- Debug APK install and launch through
adb install -rplus explicitMainActivitystart. - Crash buffer check after launch with
adb logcat -b crash.
Release builds are currently unsigned:
./gradlew :app:lintRelease :app:assembleRelease --console=plainThe bundled dictionary is built from Princeton WordNet 3.0:
python3 tools/build_wordnet_asset.pyThis writes:
app/src/main/assets/dictionary/wordnet.dbapp/src/main/assets/dictionary/LICENSE_WORDNET.txt
WordNet attribution is included in NOTICE and in the bundled license file.
XReader is local-first:
- Books are imported through Android's file picker and copied into app-owned private storage.
- The app does not request broad all-files access.
- Network access is only used when you explicitly open a Catalog URL import; there is no background sync, telemetry, account service, or automatic network scan.
- Reading analytics, notes, bookmarks, dictionary lookup, and search indexes stay local.
- Architecture
- Audiobook Generation
- Competitive Research
- Performance
- Roadmap
- Current paused-work checkpoint
- Contributing
- Changelog
- Security
- Notices
XReader is licensed under the MIT License. See LICENSE.
