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
FusedLocationProviderClientand partial wake locks to ensure reliability without excessive drain. - 🧠 Intelligent Filtering (JCB Logic):
- Spiderweb Prevention: Automatically "Locks" location when stationary (e.g., inside a building) to prevent random GPS jumps.
- Breakout Detection: Uses a sequence of verified moves to resume tracking, ensuring accuracy in rural or urban canyon areas.
- Impossible Speed Filter: Rejects impossible jumps in location (e.g., GPS glitching 500m in 1 second).
- 📡 Robust Syncing:
- Batch Uploads: Sends multiple locations (up to 100) in a single HTTP request to save battery and reduce server load.
- Offline Buffer: Automatically saves coordinates to a local SQLite database when the network is unavailable.
- Exponential Backoff: Retries failed syncs with increasing delays (2s, 4s, 8s...) to handle server downtime gracefully.
- ⚠️ Status Reporting: Automatically reports to a specific URL when the user turns GPS on or off.
- 🏁 Clean Checkout: Dedicated method to flush all pending data before stopping the service.
- 🌐 Dual Mode: Supports both HTTP/REST and WebSockets for real-time tracking.
🚀 Installation
Add the package to your pubspec.yaml:
dependencies:
adaptive_location_tracker: ^0.1.0
Android Setup
The plugin handles most permissions, but ensure your AndroidManifest.xml doesn't conflict. The plugin requires:
ACCESS_FINE_LOCATIONACCESS_BACKGROUND_LOCATION(Mandatory for background tracking)FOREGROUND_SERVICEFOREGROUND_SERVICE_LOCATIONACTIVITY_RECOGNITION(for Motion Detection)REQUEST_IGNORE_BATTERY_OPTIMIZATIONS(Highly recommended)
⚠️ Important: Android Background Restrictions
🔋 Battery Optimizations
Android OS is very aggressive at killing background services to save power. Recommendation:
- The app should request to ignore battery optimizations:
Permission.ignoreBatteryOptimizations.request(). - Guide users to set the app to "Don't Optimize" or "Unrestricted" in system settings.
📱 Location "Always"
On Android 11+, users must manually select "Allow all the time" in the app's location settings. Background tracking will fail or be severely throttled if only "While using the app" is selected.
📖 Usage
1. Start Tracking
Call start() with your configuration. It returns a bool indicating if the service was successfully initiated.
bool success = await AdaptiveLocationTracker.start(
url: 'https://your-api.com/v1/trace',
reportLocationUrl: 'https://your-api.com/v1/report-location',
headers: {'Authorization': 'Bearer YOUR_TOKEN'},
intervalSeconds: 15,
extraData: {'user_id': 101},
);
2. Checkout (Safe Stop)
Flushes all locally stored points to the server before shutting down. Use this for "End Shift" buttons.
bool checkoutStarted = await AdaptiveLocationTracker.checkout();
3. Immediate Stop
Stops the service immediately without flushing the database.
await AdaptiveLocationTracker.stop();
📡 Backend Implementation
A. Tracking Endpoint (url)
Receives an Array of location objects.
[
{
"latitude": 12.9716,
"longitude": 77.5946,
"timestamp": 1715065200000,
"accuracy": 15.2,
"user_id": 101
}
]
B. Status Report Endpoint (reportLocationUrl)
Receives a single status Object.
{
"latitude": 12.9716,
"longitude": 77.5946,
"remarks": "Location disabled by user"
}
⚙️ Core Logic (State Machine)
- MOVING State: Records points if they are >10m apart and meet accuracy thresholds.
- STATIONARY State: The service "locks" to a clean point and ignores GPS drift until a significant move (30m+) is detected.
- Sync Scheduler: Runs every
intervalSeconds. It fetches pending data, sends a batch, and deletes them only after a200 OKresponse.
❤️ Credits
Built for high-reliability field operations with advanced jitter filtering and offline resilience.