Adaptive Location Tracker 📍
A "Gold Standard" location tracking plugin for Flutter, designed for battery efficiency, high accuracy, and offline resilience. It creates a foreground service on Android to track location reliably in the background, making it perfect for field force, delivery, and logistics applications.
✨ Features
- 🔋 Battery Efficient: Uses Google's
FusedLocationProviderClientto minimize battery drain. - 🧠 Intelligent Filtering:
- Kalman Filter: Stabilizes GPS coordinates, removing jitter when stationary and reducing lag when moving fast.
- Outlier Detection: Rejects impossible jumps in location (e.g., GPS drift).
- Stationary Logic: reduces update frequency when the device is not moving.
- 📡 Offline Support:
- Local Buffer: Automatically saves coordinates to a local SQLite database when the network is unavailable.
- Auto-Sync: data is automatically retried and uploaded in the correct chronological order when connectivity returns.
- 🛠️ Customizable:
- Configurable HTTP endpoint, headers, and update intervals.
- Customizable Notification title and text.
- Ability to send custom extra data (User ID, Task ID, etc.) with every payload.
- 🔌 Plug & Play: Handles permission checks, foreground services, and wake locks internally.
- 🌐 Dual Mode: Supports both HTTP/REST and WebSockets for real-time tracking.
🚀 Installation
Add the package to your pubspec.yaml. Since this is a private plugin, you might use a path or git dependency:
dependencies:
adaptive_location_tracker:
path: ../path/to/adaptive_location_tracker
# OR
# git:
# url: git@github.com:yourusername/adaptive_location_tracker.git
Android Setup
The plugin handles most permissions, but you should ensure your android/app/src/main/AndroidManifest.xml does not conflict. The plugin automatically adds:
FOREGROUND_SERVICEACCESS_FINE_LOCATIONACCESS_COARSE_LOCATIONINTERNET
📖 Usage
1. Import the package
import 'package:adaptive_location_tracker/adaptive_location_tracker.dart';
2. Start Tracking
Call start() with your API endpoint and configuration. The service will spin up and start posting JSON data to your URL.
HTTP Mode (Default):
await AdaptiveLocationTracker.start(
url: 'https://your-api.com/v1/trace',
headers: {'Authorization': 'Bearer YOUR_JWT_TOKEN'},
extraData: {
'driver_id': 12345,
'route_id': 'RT-9988',
},
notificationTitle: "Active Delivery",
notificationText: "Tracking location for safety",
intervalSeconds: 15,
);
WebSocket Mode:
Enable isWebSocket: true to stream real-time locations over a socket connection. If the socket fails, data falls back to the local database and is synced via HTTP later.
await AdaptiveLocationTracker.start(
url: 'wss://your-api.com/ws/locations', // Use wss://
isWebSocket: true, // <--- Enable Socket Mode
headers: {'Authorization': 'Bearer ...'},
extraData: {'user_id': 101},
);
3. Stop Tracking
To stop the background service and release resources:
await AdaptiveLocationTracker.stop();
📡 API Payload Format
The plugin sends a POST request (or Socket Message) with the following JSON:
{
"latitude": 37.774929,
"longitude": -122.419418,
"accuracy": 12.5, // in meters
"timestamp": 1679812345678, // Unix epoch milliseconds (GPS time)
// ... Plus any fields you passed in 'extraData'
"driver_id": 12345,
"route_id": "RT-9988",
"mode": "bike"
}
⚙️ How it works internally
- Hybrid Filter: The plugin runs incoming GPS points through a custom filter chain. It drops points with low accuracy or impossible speeds.
- Adaptive Filtering: A Kalman filter smoothes the path.
- If you are walking (slow speed), it stiffens to prevent "jitter".
- If you are driving (fast speed), it loosens to follow the car closely.
- Real-Time Transmission:
- HTTP Mode: POSTs JSON to your endpoint.
- Socket Mode: Streams JSON to your WebSocket.
- Local DB (Fallback): If an request fails (404, 500, socket error), the JSON payload is saved to a local
LocationHistory.db. - Sync: On the next successful location update, the service creates a background thread to upload queued offline events via HTTP, ensuring chronological order.
❤️ Credits
Built for high-reliability field operations.