tracpulse/AGENTS.md
2026-04-30 16:46:27 +07:00

44 lines
No EOL
3 KiB
Markdown

# 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=...&timestamp=...&is_moving=0`. The `is_moving` threshold is `speed > 1.0 m/s`.