Personal, on-device Android media vault. Hide photos & videos from the system gallery, rate them 1–3 hearts, favorite, play playlists (built-in or VLC), and lock the app with pattern / PIN + biometric. Dark theme only. Sideload-only — media stays local; no cloud storage, accounts, or analytics.
Author: kcng0 · License: MIT · Support: Buy Me a Coffee.
This is a personal project; simplicity is favored over features.
Privi is not on Google Play. Download a release APK and sideload it:
- Open the latest Release.
- Download
privi-<version>.apk(and optionallySHA256SUMS). - Verify the download (desktop):
sha256sum -c SHA256SUMS
- On your phone, allow install from your browser/file manager if prompted.
- Open the APK and install.
Each release includes:
| Asset | Purpose |
|---|---|
privi-<version>.apk |
Sideload install |
SHA256SUMS / .sha256 / CHECKSUMS.txt |
Integrity check |
| Source code (zip / tar.gz) | Auto-attached by GitHub for the tag |
Requirements: Android 8.0+ (API 26). Optional: VLC for external video playback. All media stays on-device.
Official GitHub Release APKs are release-signed with a permanent keystore (same signature across versions). First-time installs of a new signature may still get a Play Protect “unknown app” prompt until Google has seen the binary — use Install anyway and leave harmful-app detection enabled.
Starting with v1.0.4, updates are fully user-controlled. Open Settings → Check updates to check the latest stable GitHub Release first, then the Shorebird hot-update channel for the installed base. A newer full release is shown with a confirmation action that opens its GitHub Release page. When a signed Dart patch is available, Privi asks before downloading it. Starting with v1.0.5, a successful patch download restarts Privi automatically so the patch is active immediately. The About dialog shows the base version/build and applied patch number.
Android/native code, plugins, permissions, bundled assets, and Flutter engine changes still require a new APK. v1.0.3 contained the first updater but used its automatic mode, so install v1.0.5 once to enable consent-based updates with automatic restart. Network access occurs only after the manual check; vault media stays on-device.
- Visible | Invisible home — browse system gallery albums or the private vault
- Independent mosaic/list views — each home tab remembers its own layout
- Directory hide — media removed from the system gallery while kept on disk
- Consistent HD posters — the same 768 px video frame before and after Hide
- Stable date order — folders keep original capture chronology after Hide
- Hearts (0–3) + favorites, album sorting, and manual drag-to-arrange
- Collections — create, rename, organize members, and dissolve without deleting media
- Built-in viewer/player + result-tracked external media apps
- Pattern / PIN + biometric lock, optional
FLAG_SECURE(block screenshots) - Root resume lock — covers every tab/route; only tracked media-app Back bypasses it
- Share-to-Privi import intents for images and videos
- On-device media storage; signed update checks are user-triggered
android photo vault · hide photos from gallery · private gallery app ·
video vault · offline media locker · pattern lock gallery ·
biometric photo lock · sideload apk vault · flutter media vault ·
hide videos android · no cloud gallery · vlc private player
GitHub topics: flutter android photo-vault video-vault private-gallery
hide-photos biometric-lock privacy offline sideload apk vlc mit-license
Captured from the current Privi v1.0.14 Flutter UI using synthetic folders, albums, collections, and the bundled app icon. No personal media or connected device is used; the dark theme and latest Visible/Invisible/collection flows are shown as they ship.
Maintainers can regenerate them without an Android device:
flutter test tool/readme_screenshots_test.dart --update-goldens.
| Visible mosaic | Visible list | Invisible mosaic |
|---|---|---|
![]() |
![]() |
![]() |
| Invisible list | Collection mosaic | Collection list |
|---|---|---|
![]() |
![]() |
![]() |
| Collection management | Settings | Lock setup |
|---|---|---|
![]() |
![]() |
![]() |
- Visible mosaic/list — the new tab-isolated home presentation toggle.
- Invisible mosaic/list — vault albums, ratings, counts, and collections.
- Collection screens — member mosaic/list views and CRUD management actions.
- Settings / lock — security, display, playback, and first-run pattern setup.
| Tool | Notes |
|---|---|
| Flutter 3.44.6 | Prefer FVM (.fvmrc pins the exact version) |
| JDK 17+ | Android Gradle |
| Android SDK | platform 37, build-tools, cmdline-tools, licenses accepted |
| Device / emulator | Android 8.0+ (API 26) |
git clone https://github.com/kcng0/privi.git
cd privi
# Optional: install Flutter + Android SDK + licenses
./scripts/install-toolchain.sh && source ~/.bashrc
# Generate native scaffold (if needed), deps, codegen
./scripts/bootstrap.sh
# Run on a connected device
make runmake run # launch on a connected device
make test # unit + widget tests
make analyze # static analysis
make format # dart format lib test
make gen # build_runner (Drift + Riverpod)
make watch # codegen in watch mode
make apk # release APK for sideloading
make help # list targetsWithout make, use fvm flutter … (or plain flutter if FVM is not installed).
Full environment notes, troubleshooting, and CI details: DEVELOPMENT.md.
├── lib/ # Dart source (feature-first)
├── test/ # unit + widget tests
├── android/ # Android host project
├── assets/ # branding / icons / screenshots
├── scripts/ # bootstrap + toolchain installer
├── .github/ # CI + release workflows
├── pubspec.yaml
├── Makefile
└── DEVELOPMENT.md
| Workflow | Trigger | What it does |
|---|---|---|
| CI | push / PR to main |
format, codegen, analyze, test only |
| Release | tag v* or manual dispatch |
Shorebird base APK + checksums + GitHub Release |
| Patch | manual dispatch on main |
signed Dart patch for an existing base release |
To cut a release from a clean main:
# bump version in pubspec.yaml (e.g. 0.1.0+1 → 0.1.1+2), commit, then:
git tag v0.1.1
git push origin v0.1.1Or run Actions → Release APK → Run workflow. For Dart-only fixes that do
not require a new APK, merge the change through a PR without bumping the app
version, then run Actions → Shorebird Patch with the exact base version
(for example 1.0.4+5).
If Privi is useful to you, you can support development here:








