diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..7bf31e6 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,44 @@ +# Agents — Traccar Client + +## Verify before claiming + +- Run `flutter analyze` before every commit — this project had 22 deprecated API violations (`.withOpacity()` → `.withValues(alpha:)`, `value` → `initialValue` on `DropdownButtonFormField`, `activeColor` → `activeThumbColor` on `Switch`) +- Always run `flutter build apk --debug` to confirm the APK builds after any Dart or Kotlin change + +## Commands + +```bash +flutter analyze # lint + typecheck (run before commit) +flutter build apk --debug # build Android APK +dart format . # format all Dart files +``` + +## Architecture + +- **Flutter** Android app with a **MethodChannel** (`com.traccar.client/tracking`) bridging to native Kotlin services +- **4 screens**: `PermissionScreen` → `MainScreen` → `SettingsScreen` / `StatusScreen` +- **LocationBridge** (`lib/bridge/location_bridge.dart`) — the only Dart→Native bridge; all tracking starts here +- **Native**: Kotlin services in `android/app/src/main/kotlin/com/traccar/traccar_client/` + - `BridgeModule.kt` — method channel handler + - `service/LocationTrackingService.kt` — foreground service + - `location/HeartbeatScheduler.kt` — AlarmManager-based heartbeat (not WorkManager — WorkManager runs in separate process and static callbacks are lost) + +## Key patterns & gotchas + +- **Permission flow**: `locationAlways` (background) requires `locationWhenInUse` to be granted first. Always request WhenInUse → then Always. Check `isPermanentlyDenied` and call `openAppSettings()` to direct user to app settings. +- **Battery optimization**: Use `PowerManager.isIgnoringBatteryOptimizations(packageName)` via `BridgeModule` to detect if app is excluded from Doze. Open settings with `ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS` intent. +- **Dark theme**: Set globally on `MaterialApp` (`scaffoldBackgroundColor`, `brightness: Brightness.dark`, `ColorScheme.dark`). Use `ZoomPageTransitionsBuilder` to avoid white flash on page transitions (not `FadeUpwardsPageTransitionsBuilder`). +- **Tracking config**: Config dict must be passed to `startTracking()` and also sent via `updateConfig()` separately. Both calls are needed. +- **`permission_screen.dart` state**: Permissions are checked at init via `_checkPermissions()`. State must be re-checked after each request call, not assumed from the request result. +- **`preferences.dart`**: Uses static `SharedPreferences` instance. `Preferences.init()` must be called before `runApp()`. + +## Style conventions + +- Monospace fonts, dark `#0d0d0d` background, teal `#00bcd4` accent, green `#00e676` for active/granted states +- All UI text uses `fontFamily: 'monospace'` +- Replace `Color.withOpacity(x)` → `Color.withValues(alpha: x)` (deprecated in recent Flutter) +- Remove unused imports before committing + +## Monorepo context + +The sibling `traccar-client-android` directory is the **original Java app** — reference it for expected server request format: POST to `serverUrl?id=deviceId&lat=...&lon=...×tamp=...&is_moving=0`. The `is_moving` threshold is `speed > 1.0 m/s`. \ No newline at end of file