8.9 KiB
8.9 KiB
Traccar Client Rewrite - Specification
Date: 2026-04-30 Project: traccar_client Type: Fresh Flutter + Native Android GPS tracking app
1. Project Overview
- Purpose: Reliable background GPS location tracking app for Android that reports to a self-hosted Traccar server
- Target Platform: Android only
- Traccar Protocol: Standard HTTP-based protocol (compatible with any self-hosted Traccar server)
2. Architecture
2.1 Technology Stack
| Layer | Technology | Responsibility |
|---|---|---|
| UI | Flutter | Settings screen, main screen, status/log viewer |
| Bridge | Platform Channels | MethodChannel + EventChannel between Flutter and Android |
| Service | Kotlin Android | Foreground service for reliable background tracking |
| Location | FusedLocationProviderClient (Google Play Services) | GPS location acquisition |
| Storage | Room (SQLite) | Offline location buffer + event log |
| Network | OkHttp | HTTP POST to Traccar server |
| Background | WorkManager | Heartbeat scheduling, periodic sync |
2.2 Data Flow
[FusedLocationProvider]
↓
[DistanceFilterProcessor] → (discard if within threshold)
↓
[LocationTrackingService] → [Room: locations buffer] ← (if offline)
↓
[TraccarHttpClient] → POST to server → [Room: mark synced]
↑ (when online)
[WorkManager] → periodic sync attempt
3. Components
3.1 Flutter UI Layer
| Screen | Purpose |
|---|---|
main_screen.dart |
Toggle tracking on/off, display last location, speed, timestamp |
settings_screen.dart |
All configuration options |
status_screen.dart |
Event log viewer for debugging |
preferences.dart |
SharedPreferences wrapper for settings persistence |
3.2 Platform Bridge
| Class | Type | Purpose |
|---|---|---|
location_bridge.dart |
Flutter | Platform channel wrapper |
BridgeModule.kt |
Kotlin | Registers MethodChannel + EventChannel |
3.3 Android Service Layer
| Class | Purpose |
|---|---|
LocationTrackingService |
Foreground service with persistent notification |
FusedLocationProvider |
Google Play Services location API wrapper |
DistanceFilterProcessor |
Distance/interval/angle filtering with Haversine |
HeartbeatScheduler |
Stationary heartbeat via WorkManager |
AppDatabase |
Room database |
LocationDao |
CRUD for buffered locations |
EventLogDao |
CRUD for event log entries |
TraccarHttpClient |
HTTP POST with retry and auth |
ConnectivityReceiver |
Network change listener |
Location |
Data model |
4. Settings
| Setting | Type | Default | Description |
|---|---|---|---|
serverUrl |
String | https://demo.traccar.org |
Traccar server URL |
deviceId |
String | Auto-generated 8-digit | Device identifier |
accuracy |
String | HIGH |
GPS accuracy: HIGH/HIGH_ACCURACY/BALANCED/LOW |
distanceFilter |
int | 75 |
Min distance between reports (meters) |
interval |
int | 300 |
Time-based fallback filter (seconds) |
heartbeat |
int | 60 |
Stationary heartbeat interval (seconds) |
offlineBuffer |
bool | true |
Queue locations when offline |
stopDetection |
bool | true |
Auto-stop tracking when stationary |
password |
String | "" |
Basic auth password for server |
5. Foreground Notification
Layout:
┌─────────────────────────────────────────┐
│ 📍 Traccar Client [ON/OFF] │
├─────────────────────────────────────────┤
│ Lat: 37.7749 Lon: -122.4194 │
│ Speed: 45 km/h │
│ Last: 09:41:23 │
└─────────────────────────────────────────┘
Updates: Notification content updates in real-time as locations are captured and sent.
6. Traccar Protocol
Endpoint: {serverUrl}/?id={deviceId}&lat={lat}&lon={lon}×tamp={ts}&speed={speed}&...
Parameters:
id- Device identifierlat- Latitudelon- Longitudetimestamp- Unix timestamp (milliseconds)speed- Speed in km/hbearing- Heading in degreesaccuracy- GPS accuracy in metersaltitude- Altitude in metersis_moving- 1 if moving, 0 if stationary
Authentication: HTTP Basic Auth if password is set.
7. Offline Buffering
When offline:
- Location is captured and passes filters
- Location is saved to Room
locationstable withsynced=0 - App continues tracking and buffering
When connectivity restored:
- WorkManager triggers sync
- All buffered locations are sent to server
- Locations marked as
synced=1
8. Heartbeat Behavior
| State | Behavior |
|---|---|
| Moving | Normal location updates based on distance/interval filters |
| Stationary | Heartbeat fires every N seconds (configurable), triggers single location fix |
| Stop detected | Tracking auto-stops if stopDetection=true, heartbeat continues |
9. Event Log
Logged Events:
| Event Type | When Logged |
|---|---|
LOCATION |
Location captured and accepted |
FILTERED |
Location filtered (reason: distance/interval/angle) |
SYNC |
Location successfully sent to server |
HEARTBEAT |
Heartbeat event fired |
NETWORK_CHANGE |
Network went online/offline |
ERROR |
Any error condition |
Log Entry Fields: timestamp, event_type, message
10. File Structure
traccar_client/
├── lib/
│ ├── main.dart
│ ├── main_screen.dart
│ ├── settings_screen.dart
│ ├── status_screen.dart
│ ├── preferences.dart
│ └── bridge/
│ └── location_bridge.dart
├── android/app/src/main/
│ ├── kotlin/com/traccar/traccar_client/
│ │ ├── MainActivity.kt
│ │ ├── BridgeModule.kt
│ │ ├── service/
│ │ │ └── LocationTrackingService.kt
│ │ ├── location/
│ │ │ ├── FusedLocationProvider.kt
│ │ │ ├── DistanceFilterProcessor.kt
│ │ │ └── HeartbeatScheduler.kt
│ │ ├── storage/
│ │ │ ├── AppDatabase.kt
│ │ │ ├── LocationDao.kt
│ │ │ └── EventLogDao.kt
│ │ ├── network/
│ │ │ ├── TraccarHttpClient.kt
│ │ │ └── ConnectivityReceiver.kt
│ │ └── model/
│ │ └── Location.kt
│ └── AndroidManifest.xml
├── docs/
│ └── superpowers/
│ └── specs/
│ └── 2026-04-30-traccar-client-design.md
└── pubspec.yaml
11. Dependencies
Flutter (pubspec.yaml)
dependencies:
flutter:
sdk: flutter
shared_preferences: ^2.2.0
workmanager: ^0.5.0
sqflite: ^2.3.0
http: ^1.1.0
permission_handler: ^11.0.0
flutter_local_notifications: ^16.0.0
Android (app/build.gradle)
implementation 'androidx.room:room-runtime:2.5.0'
implementation 'com.google.android.gms:play-services-location:21.0.1'
implementation 'androidx.work:work-runtime:2.8.0'
implementation 'androidx.appcompat:appcompat:1.6.1'
12. Android Permissions
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
13. Verification Criteria
| Test | Expected Result |
|---|---|
| Home→Office route (10km) | 20+ coordinate points captured |
| Offline mode | Locations queued, synced when connection restored |
| Stationary 5+ minutes | Heartbeat fires every N seconds (configurable) |
| Arrival detection | Tracking stops, heartbeat continues |
| App restart | Settings persist, tracking resumes |
| Notification | Shows ON/OFF status, coordinates, speed, timestamp |
14. Implementation Phases
- Phase 1: Project Setup - Flutter project, Android permissions, dependencies
- Phase 2: Native Android Layer - Location service, Room database, HTTP client
- Phase 3: Flutter UI Layer - Main screen, settings screen, status screen
- Phase 4: Platform Channel Bridge - MethodChannel, EventChannel
- Phase 5: Integration & Testing