Skip to content

Repository files navigation

Snapit — Android

Platform Flutter License

The official Android app for Snapit — a universal clipboard sync system. Everything you copy is captured automatically, encrypted locally with AES-256-GCM, and synced end-to-end encrypted to the Snapit backend so your clipboard history is available on every device you own.


Features

  • Automatic clipboard capture via Android foreground service and opt-in Accessibility Service
  • AES-256-GCM local encryption with PBKDF2-SHA256 key derivation (200k iterations)
  • Full-text search across clipboard history (SQLite FTS4)
  • Pin, tag, and organise clips
  • Cross-device sync over end-to-end encrypted channels (Pro)
  • Background sync every 30 minutes via WorkManager
  • Real-time plan-change notifications over SSE
  • Firebase Cloud Messaging push support
  • Receive clips via Android share sheet
  • Freemium: unlimited local history free; cross-device sync requires Pro

Tech Stack

Layer Technology
Framework Flutter 3.44.1 / Dart ^3.12.1
State management Riverpod 2 (AsyncNotifier, StreamProvider)
Navigation go_router 15 with auth-guarded ShellRoute
Local database sqflite + FTS4 full-text search
Secure storage flutter_secure_storage (Android Keystore)
Encryption PointyCastle — AES-256-GCM, PBKDF2-SHA256
Background capture Android foreground service + Accessibility Service
Background sync WorkManager (30-min periodic task)
Realtime SSE stream for plan changes and sync events
Push notifications Firebase Cloud Messaging
HTTP client Dio
Share target receive_sharing_intent

Prerequisites

Tool Version
Flutter SDK 3.44.1
Dart SDK ^3.12.1
Android Studio Hedgehog (2023.1) or newer
Android SDK API 23 (Android 6) minimum, API 34+ recommended
Java / JDK 17 (bundled with Android Studio)

You can use VS Code with the Flutter and Dart extensions instead of Android Studio.


Quickstart

1. Clone the repository

git clone https://github.com/coderbenny/snap_mobile
cd snap_mobile

2. Install dependencies

flutter pub get

3. Configure Firebase

The app requires a google-services.json file for Firebase Cloud Messaging (not committed — keep it out of version control):

  1. Open your Firebase project at console.firebase.google.com.
  2. Go to Project settings → Your apps and find the Android app registered with package name ink.snapit.mobile.
  3. Download google-services.json and place it at android/app/google-services.json.

If you are self-hosting Snapit and want FCM push notifications, register a new Android app in your own Firebase project with the same package name.

4. Point at your backend

The app connects to https://api.snapit.ink/snap in release mode automatically. For local development, pass the API host at run time:

Android emulator (emulator localhost = 10.0.2.2):

flutter run --dart-define=API_HOST=10.0.2.2

Physical device (replace with your machine's LAN IP):

flutter run --dart-define=API_HOST=192.168.1.x

Make sure the device and machine are on the same Wi-Fi network.

5. Run the app

flutter run

Accessibility Service Setup (Android 12+)

Android 12 and later restrict reading the clipboard in the background. To capture clips automatically, Snapit uses Android's Accessibility Service.

To enable it on your device:

  1. Open Settings → Accessibility.
  2. Find Downloaded apps or Installed services.
  3. Tap Snapit Clipboard Service and toggle it On.

The app's onboarding screen includes a deep-link button that takes users directly to the Accessibility settings page. The service is strictly opt-in; clipboard capture falls back to a foreground service polling approach if the user declines.

The Accessibility Service declaration is in android/app/src/main/AndroidManifest.xml. The service implementation is in lib/core/services/clipboard_monitor_service.dart.


Environment / Config Reference

Variable How to set Default Description
API_HOST --dart-define=API_HOST=<value> 10.0.2.2 Backend API hostname or IP (no scheme, no port). Port is fixed at 5559.
PBKDF2_ITERATIONS Build constant 200000 Key derivation iteration count

Secrets (JWT tokens, encryption keys) are stored exclusively in flutter_secure_storage, which maps to Android Keystore — never in SharedPreferences or plain files.


Project Structure

lib/
  main.dart                  # Entry point, Riverpod ProviderScope
  app.dart                   # MaterialApp.router, go_router setup
  core/
    constants/               # App-wide constants (API base, iteration counts, etc.)
    models/                  # Core data models (ClipItem, User, SyncRecord, …)
    providers/               # Global Riverpod providers
    router/                  # go_router definition, auth redirect guard
    services/                # Platform services
      api_client.dart        # Dio-based HTTP client, token refresh interceptor
      clipboard_monitor_service.dart  # Foreground service + Accessibility bridge
      database_service.dart  # sqflite schema, migrations, FTS4 helpers
      device_registration_service.dart
      encryption_service.dart  # AES-256-GCM, PBKDF2-SHA256
      event_stream_service.dart  # SSE client for realtime sync + plan events
      fcm_service.dart
      notification_service.dart
      secure_storage_service.dart
      share_intent_service.dart
      sync_service.dart
    theme/                   # ThemeData, color tokens
  features/
    account/                 # Account management screens
    auth/                    # Login, registration, token handling
    clipboard/               # Clipboard capture UI and state
    history/                 # Clip history list and detail
    notifications/           # In-app notification centre
    onboarding/              # First-run flow, permission prompts
    pinned/                  # Pinned clips collection
    search/                  # Full-text search UI
    settings/                # App settings, Pro upgrade, sync config
    theme/                   # Theme switcher feature
  shared/
    widgets/                 # Reusable UI components
android/                     # Android-specific config, manifest, build scripts
test/                        # Unit and widget tests

Related Repositories

Repo Description
snap_mobile This repo — Flutter Android app
snap_BE Flask REST API, SSE event stream, WebSocket file-transfer relay
snap_FE Next.js web dashboard and marketing site
snap_PC Flutter desktop app (macOS)

License

MIT — see LICENSE.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages