OneWay 428749d8a8 Show the gallery folder name from the first frame
- Carry the folder name through GalleryRoute into the ViewModel's
  SavedStateHandle, so the TopBar title is correct immediately on
  navigation, before any directory listing completes
- Seed a provisional name from the SAF URI segment in loadPhotos as a
  fallback for entry points without a name (after-camera navigation)
- Drop the 'Gallery' fallback title and the unused gallery_title string
2026-10-15 13:50:31 +08:00
2026-10-13 10:17:03 +08:00
2026-10-13 10:17:03 +08:00
2026-10-13 10:17:03 +08:00
2026-10-13 10:17:03 +08:00
2026-10-13 10:17:03 +08:00
2026-10-13 10:17:03 +08:00
2026-10-13 10:17:03 +08:00
2026-10-13 10:17:03 +08:00
2026-10-13 10:17:03 +08:00

OneCamera

Take photos straight into the right folder.

Features • Capture & storage • Responsiveness • Tech stack • Build

OneCamera is an Android app for taking photos directly into the folder you choose. Pick a folder, tap the camera button, and a camera app takes the shot. The captured photo is saved straight into the selected folder.

Features

  • Folder-first shooting — choose a folder before taking a photo.
  • Camera handoff — fires MediaStore.ACTION_IMAGE_CAPTURE; the system resolves it to the default camera app (no camera picker inside OneCamera).
  • No broad storage permissions — only a user-selected SAF root folder; everything else is off-limits to the app.
  • Folder management — create, rename, move, and delete folders in the SAF tree.
  • ZIP archives — one-tap pack a folder as original files or as JPG quality 85, then share via any app.
  • Gallery — adaptive grid/list view, sort by name, fullscreen viewer with zoom and subsampling of huge photos, multi-select, share via system intents.
  • Draggable floating camera button with position persisted across restarts.
  • Material 3 UI with dynamic color, light, dark, and system themes.
  • No tracking, no ads, fully open source.

Capture & Storage

OneCamera never asks for broad storage access. All file work goes through a single user-picked Storage Access Framework tree.

Capture flow:

  1. The user grants a folder tree through the system picker; the grant is persisted.
  2. The app creates a temp file exposed through FileProvider and fires ACTION_IMAGE_CAPTURE with EXTRA_OUTPUT; the system routes the intent to the default camera app.
  3. The camera app writes the shot into the temp file; the app moves it into the selected SAF folder.
  4. A photo event bus refreshes the gallery without a restart; thumbnails are decoded subsampled and cached on disk.

Folder operations — rename, delete, move — go through SAF documents, so the UI and the file system always agree. ZIP packaging runs off the main thread with progress; if a file cannot be read, the partial archive is deleted and the outcome carries an error message. Archive entry names are UTF-8 encoded to preserve non-ASCII names. Revoking tree access is handled explicitly instead of crashing.

Responsiveness

Photo libraries can be large, so heavy work stays off the main thread:

  • SAF queries, folder scanning, and ZIP packaging run on background dispatchers;
  • gallery content loads incrementally, and folder statistics are computed separately from the photo list;
  • thumbnails load through Coil with a bounded memory cache and a disk cache capped by LRU eviction, and oversized photos are subsampled in the fullscreen viewer;
  • grid and list are lazy; sort order and view mode changes reuse loaded state instead of rescanning the tree;
  • rotation recreates the Activity by design — scroll position, sort order, and the FAB position live in ViewModel state and DataStore, not in composables;
  • Baseline Profile rules ship in the APK to speed up cold start.

Tech Stack

  • Kotlin 2.4.21
  • Jetpack Compose (BOM 2026.09.00), Material 3
  • Hilt 2.60.1 (dependency injection)
  • Navigation Compose 2.10.2
  • DataStore Preferences 1.2.1
  • Coil 3.6.3 + ZoomImage 1.7.0 (image loading and fullscreen zoom)
  • kotlinx.serialization 1.11.0
  • Androidx tracing with a committed Baseline Profile
  • Android Gradle Plugin 9.4.1, Gradle 9.8.1, JDK 21

Build

./gradlew :app:assembleRelease

The release APK targets arm64-v8a.

License

MIT

S
Description
Android app that takes photos straight into the folder you choose
Readme MIT
461 KiB
0 Stars 1 Watchers 0 Forks
Languages
Kotlin 100%