PriceLog (Android App)

Jetpack Compose purchase tracker with camera and backup support

A native Android app for logging purchases. Each item stores a name, price, notes, and a photo taken with the device camera. Data lives in a local Room (SQLite) database with a reactive list UI, and the entire database plus images can be exported to a ZIP file and restored later.

Download

PriceLog runs on Android devices. You can download the APK by clicking the button below:.

Download APK

Tech Stack

Kotlin
🎨Jetpack Compose
🗄️Room (SQLite)

Screenshots

Item list screenItem list screenItem list screenItem list screenItem list screenItem list screen

Item Tracking

  • •Add items with name and price (in Riyals)
  • •Reactive list that updates instantly via Kotlin Flow
  • •Detail page with view and edit modes
  • •Free-form notes per item
  • •Delete with confirmation dialog

Camera & Images

  • •Attach a photo to any item straight from the camera
  • •Images stored in app-private storage via FileProvider
  • •Placeholder image fallback for items without photos
  • •Image files cleaned up when an item is deleted

Backup & Restore

  • •Export database and all images into a single ZIP
  • •WAL checkpoint before export for a consistent snapshot
  • •User picks the save/open location via system file picker
  • •Safe restore using a temp file swap, then app restart
  • •Room auto-migrations across schema versions

App Architecture

Core Components

  • •Room Database: Entity + DAO layer with Flow queries for reactive reads and suspend functions for writes
  • •Navigation Compose: Two-screen NavHost (list → detail/{id}) passing the item ID as a route argument
  • •ActivityResult APIs: TakePicture contract for the camera, CreateDocument and OpenDocument for backup files
  • •Material 3 Theming: App-wide color scheme and typography from a shared AppTheme

Data Safety

  • •Consistent Backups: Forces a full WAL checkpoint so the exported database file contains every committed write
  • •Lock-Safe Restore: Writes the incoming database to a temp file first, since Room holds an open handle on the live one, then swaps and restarts cleanly