In Development — Alpha

Cloud sync on your phone.
Same engine. Android-native.

The same bidirectional sync engine from UniDrive CLI — rebuilt for Android. SFTP prototype. Svelte Material 3 UI. Dark theme. Minimal permissions.

Kotlin · Android SDK 35 · WorkManager · Jetpack Compose

Alpha — Active Development

The shell project builds and runs. Core screens (Accounts, Add Account, Settings) are wired. File browser and Account Detail are in progress. The sync engine and SFTP provider are shared directly from the JVM unidrive modules via Gradle composite builds.

Concept

Not a wrapper — the same engine, on your phone

UniDrive Android shares the core, sync, and provider modules from the JVM unidrive codebase via Gradle composite builds. The Android app provides only the Android-specific adaptation layer: FileObserver instead of inotify, sidecar placeholder files instead of sparse files, WorkManager instead of the daemon. The sync logic itself is identical.

App layer

Compose UI

Accounts, File Browser, Settings, Activity

WorkManager

Periodic & event-triggered sync

DataStore

Preferences, config

Android

AndroidPlaceholderManager

.unidrive-placeholder sidecars

FileObserver + ContentObserver

Local change detection

MediaStoreBridge

Gallery integration

Shared

SyncEngine + Reconciler

3-phase bidirectional sync

SftpProvider

Apache MINA SSHD

StateDatabase

SQLite state tracking

Features

What UniDrive Android does today

🔑

SFTP Account Setup

Key or password authentication. Inline connection test before saving. Keys stored in app-private storage, not shared preferences.

Bidirectional Sync

Same 3-phase engine: Gather → Reconcile → Apply. Incremental delta via SFTP LIST.

🗃

Placeholder Files

Cloud-only files shown as 0-byte sidecar markers with JSON metadata. Real content downloaded on demand.

MediaStore Bridge

Downloaded photos and videos inserted into the Gallery via scoped storage APIs. No broad permissions needed.

WorkManager Scheduling

Periodic 15-minute sync with network constraints. Debounced FileObserver triggers for immediate sync on local changes.

🔒

Credential Storage

SSH keys in app-private storage. Password auth support wired. Android Keystore integration planned.

🌓

Dark Theme Only

AMOLED-friendly dark theme. Material 3 design system. Indigo accent color throughout.

3-Tab Navigation

Accounts (home), Activity (sync log), Settings. File browser within account detail. No bottom-bar bloat.

Prototype Provider

SFTP — the first and only provider

🔑

SFTP / SSH

Sync any SFTP server: Synology NAS, Hetzner Storage Box, a Raspberry Pi, a root server. The JVM provider is battle-tested — validated against 39 files across 19 unicode encodings.

Tech Stack

Built with modern Android primitives

Min SDK 30 (Android 11)
Target SDK 35 (Android 15)
Kotlin 2.3.20
Jetpack Compose BOM 2026.03
Material 3
Navigation Compose
WorkManager
DataStore Preferences
Apache MINA SSHD
Gradle composite builds
No Room
No Retrofit/OkHttp

What's reused from JVM unidrive

  • SyncEngine (3-phase orchestrator)
  • Reconciler (conflict resolution, move detection)
  • PlaceholderManager (base class)
  • SftpProvider (full implementation)
  • CloudProvider interface
  • CloudItem, DeltaPage models
  • StateDatabase schema

What Android replaces

  • LocalWatcher (inotify) → FileObserver + ContentObserver
  • Sparse files → .unidrive-placeholder sidecar files
  • StateDatabase (JDBC) → android.database.sqlite wrapper
  • Daemon → WorkManager CoroutineWorker
  • Config TOML → DataStore Preferences
  • CLI UI → Jetpack Compose
Roadmap

What's done, what's in progress, what's planned

Gradle Shell Done

  • JVM modules consumed via includeBuild
  • Logback excluded, slf4j-timber wired
  • MINA SSHD MINA security registrar fix
  • compileSdk 36, JDK 21 bytecode target
  • Shell project builds to APK

Placeholder Manager Done

  • AndroidPlaceholderManager extends JVM base
  • 0-byte sidecar + .meta JSON files
  • createPlaceholder, dehydrate, isSparse
  • Unit tests for all operations

Account Config Done

  • AccountProfile data class (JSON serializable)
  • AccountConfigStore (save, load, list, delete)
  • SFTP account creation flow
  • Key file picker + app-private storage

Core UI Screens Done

  • AccountsScreen (account cards + FAB)
  • AddAccountScreen (SFTP form + test connection)
  • SettingsScreen (DataStore-backed preferences)
  • 3-tab bottom navigation

Sync Worker Done

  • WorkManager CoroutineWorker
  • Periodic 15-minute sync scheduling
  • FileObserver event trigger
  • Unit tests for worker logic

MediaStore Bridge Done

  • ContentResolver.insert for images/video
  • RELATIVE_PATH to Pictures/UniDrive
  • Scoped storage compliant (no MANAGE_EXTERNAL_STORAGE)

Account Detail Screen Done

  • AccountDetailViewModel (loads profile, stats)
  • ProviderFactory (reconstruct SftpProvider from profile)
  • Test Connection button (authenticate + listChildren)
  • Pause / Resume toggle (syncEnabled flag)
  • Remove Account (delete JSON + key file)

File Browser Done

  • FileBrowserViewModel (profile + path navigation)
  • LazyColumn file listing
  • Folder drill-down navigation
  • File metadata bottom sheet
  • Error handling for permission/network errors

AndroidFileObserver Planned

  • FileObserver wrapper class
  • ContentObserver for MediaStore
  • Debouncing logic (5-second window)
  • Echo suppression (skip events from sync)

Conflict Resolution UI Planned

  • Conflict screen per-account
  • Keep Local / Keep Remote / Keep Both actions
  • Conflict badge on account card
  • Conflict history with restore

Android Keystore Planned

  • SSH private key import into AndroidKeyStore
  • EncryptedSharedPreferences for passwords
  • Biometric unlock for vault

Additional Providers Future

  • WebDAV (via provider-webdav module)
  • S3 (via provider-s3 module)
  • OneDrive (OAuth flow adaptation)
  • HiDrive, Internxt

Full Sync Engine Wiring Future

  • Connect SyncWorker to AccountConfigStore
  • Run full SyncEngine.runOnce per profile
  • Sync status ↔ UI communication
  • Force Full Sync button
  • Download/hydrate from file browser
UniDrive CLI vs Android

Same engine, different surfaces

UniDrive CLI (Linux)

  • Headless, runs on servers
  • Daemon mode with inotify
  • 8 providers (OneDrive, HiDrive, Internxt, S3, SFTP, WebDAV, rclone, Local FS)
  • Sparse placeholder files on ext4/btrfs
  • Credential vault
  • IPC Unix socket for real-time events
  • Conflicts, pin patterns, bandwidth control
  • Profile management, benchmark tool
  • Production-ready

UniDrive Android

  • Graphical UI (Material 3, Compose)
  • WorkManager background sync
  • 1 provider (SFTP prototype)
  • Sidecar placeholder files
  • Android Keystore integration (planned)
  • Scoped storage via MediaStoreBridge
  • File browser, conflict resolution (planned)
  • Account management UI
  • Alpha — in development