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.
- 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
| 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 |
| 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.
git clone https://github.com/coderbenny/snap_mobile
cd snap_mobileflutter pub getThe app requires a google-services.json file for Firebase Cloud Messaging (not committed — keep it out of version control):
- Open your Firebase project at console.firebase.google.com.
- Go to Project settings → Your apps and find the Android app registered with package name
ink.snapit.mobile. - Download
google-services.jsonand place it atandroid/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.
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.2Physical device (replace with your machine's LAN IP):
flutter run --dart-define=API_HOST=192.168.1.xMake sure the device and machine are on the same Wi-Fi network.
flutter runAndroid 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:
- Open Settings → Accessibility.
- Find Downloaded apps or Installed services.
- 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 inlib/core/services/clipboard_monitor_service.dart.
| 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.
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
| 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) |
MIT — see LICENSE.