docs: add traccar client design spec
This commit is contained in:
commit
f1c076d71a
1 changed files with 274 additions and 0 deletions
274
docs/superpowers/specs/2026-04-30-traccar-client-design.md
Normal file
274
docs/superpowers/specs/2026-04-30-traccar-client-design.md
Normal file
|
|
@ -0,0 +1,274 @@
|
|||
# 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 identifier
|
||||
- `lat` - Latitude
|
||||
- `lon` - Longitude
|
||||
- `timestamp` - Unix timestamp (milliseconds)
|
||||
- `speed` - Speed in km/h
|
||||
- `bearing` - Heading in degrees
|
||||
- `accuracy` - GPS accuracy in meters
|
||||
- `altitude` - Altitude in meters
|
||||
- `is_moving` - 1 if moving, 0 if stationary
|
||||
|
||||
**Authentication**: HTTP Basic Auth if password is set.
|
||||
|
||||
---
|
||||
|
||||
## 7. Offline Buffering
|
||||
|
||||
**When offline**:
|
||||
1. Location is captured and passes filters
|
||||
2. Location is saved to Room `locations` table with `synced=0`
|
||||
3. App continues tracking and buffering
|
||||
|
||||
**When connectivity restored**:
|
||||
1. WorkManager triggers sync
|
||||
2. All buffered locations are sent to server
|
||||
3. 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)
|
||||
```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)
|
||||
```groovy
|
||||
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
|
||||
|
||||
```xml
|
||||
<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
|
||||
|
||||
1. **Phase 1**: Project Setup - Flutter project, Android permissions, dependencies
|
||||
2. **Phase 2**: Native Android Layer - Location service, Room database, HTTP client
|
||||
3. **Phase 3**: Flutter UI Layer - Main screen, settings screen, status screen
|
||||
4. **Phase 4**: Platform Channel Bridge - MethodChannel, EventChannel
|
||||
5. **Phase 5**: Integration & Testing
|
||||
Loading…
Add table
Add a link
Reference in a new issue