VID is a private, dark-first Android app for dates that must not get lost: anniversaries, deadlines, health checks, payments, and personal milestones.
Download the latest signed APK →
The app is local-first and intentionally has no INTERNET permission, account, ads, analytics, or permanent background service. A date can be added in seconds, searched instantly, backed up to a portable file, and restored transactionally.
- fast timeline with countdowns, search, critical/30-day filters, and pinned dates;
- events, deadlines, and anniversaries with importance and categories;
- daily, weekly, monthly, and yearly recurrence anchored to the original date;
- editable recurrence intervals plus explicit behavior for February 29 and short months;
- completion/acknowledgement of each current occurrence;
- up to eight reminder offsets, exact daily alarms with delayed-work catch-up, notification diagnostics, and duplicate-delivery protection;
- archive, recoverable trash with a 30-day window, restore, and confirmed permanent deletion;
- manual portable export/import through Android Storage Access Framework;
- optional AES-256-GCM encryption with PBKDF2-HMAC-SHA256;
- checksum validation for readable backups and a safety snapshot before import;
- graphite, AMOLED, and system themes;
- sensitive-notification redaction and optional screenshot blocking;
- Russian and English UI resources; on Android 13+ the language can be selected per app in system settings;
- reproducible CI and signed APK releases from SemVer tags.
VID is a single-activity Kotlin/Compose application. It deliberately avoids a network stack, dependency-injection framework, and always-on services.
Compose UI → MainViewModel → DatesRepository → Room / SQLite
↘ SettingsStore → DataStore
Exact alarm / WorkManager fallback → ReminderWorker → delivery ledger → notifications
Storage Access Framework → BackupService → authenticated backup codec
Core choices:
- Android Gradle Plugin 9.3, Gradle 9.5, Kotlin 2.4, JDK 17;
compileSdk/targetSdk37 andminSdk26;- Compose BOM
2026.06.01, Room 2.8.4, WorkManager 2.11.2; - WAL database, indexed next occurrences, lazy recurrence calculation;
- R8 resource/code shrinking for releases;
- Android system scheduler instead of polling.
See architecture notes, product decisions, and the backup format.
Requirements: JDK 17 and Android SDK Platform 37.
export JAVA_HOME=/path/to/jdk-17
export ANDROID_HOME=/path/to/android-sdk
./gradlew testDebugUnitTest lintDebug assembleDebugThe debug APK is written to app/build/outputs/apk/debug/.
Release builds are fail-closed and require all signing variables:
export SIGNING_KEYSTORE_FILE=/absolute/path/release.jks
export SIGNING_KEYSTORE_PASSWORD='...'
export SIGNING_KEY_ALIAS='...'
export SIGNING_KEY_PASSWORD='...'
./gradlew lintRelease assembleReleaseNever commit a keystore or password. See release instructions.
Every push and pull request runs lint, unit tests, and a debug build. A tag such as v0.1.0-alpha.1 builds a signed APK, verifies its certificate, application ID, and embedded version, generates SHA-256 checksums and provenance attestations, and publishes a GitHub Release.
versionName must equal the tag without v; increase versionCode for every release.
All application data stays inside the Android app sandbox unless the user explicitly exports a backup. Android implicit cloud backup is disabled. A portable encrypted backup can only be opened with its password; the password is never stored.
See PRIVACY.md and SECURITY.md.
The repository is in active alpha development. The current implementation is a complete local-first vertical slice; exact alarms, automated SAF-folder rotation, ICS/CSV imports, Macrobenchmark gates, and widgets remain on the roadmap.
Apache-2.0. See LICENSE.