smart_location 3.0.1 copy "smart_location: ^3.0.1" to clipboard
smart_location: ^3.0.1 copied to clipboard

Smart Location is a powerful, battery-conscious Flutter plugin for continuous background geolocation tracking, advanced geofencing, and motion-aware updates.

Smart Location #

Pub points License Platform

[Demo]

A developer-friendly, DX-first Flutter package for handling location. It internally wraps native OS location APIs with a clean, top-down designed interface that minimizes boilerplate and implements advanced client-side algorithms out of the box.

🤔 Why use smart_location over geolocator? #

  1. Zero Battery Drain Batched Syncing: Native integration with Android WorkManager and iOS BGTaskScheduler allows for headless, batched coordinate syncing without keeping the Dart VM alive.
  2. WebAssembly (WASM) Support: Fully compatible with Flutter Web WASM compilation.
  3. True Native Background Services Built-in: Includes out-of-the-box support for Android Foreground Services to ensure your app tracks continuously even when swiped away.
  4. Offline Persistence: Automatically saves locations locally if the network drops and syncs them when reconnected.

Features #

🌟 Core Capabilities #

  • One-line Location Fetching: Get the current location safely.
  • Continuous Tracking: Listen to location stream with simple configurations.
  • Smart Permission Handling: Checks GPS and prompts permissions automatically.
  • Pure Dart Models: Safe mapping from raw platform data to clean Dart classes.

🚀 Advanced Capabilities (New!) #

  • Client-Side Geofencing (Spatial Hash Optimized): Monitor geofences with entry, exit, and dwell triggers. Optimized with an $O(1)$ Spatial Hashing grid to support hundreds of fences without performance degradation.
  • Route Recorder & Compressors: Record paths with real-time stats. Compress routes using the Ramer-Douglas-Peucker (RDP) algorithm, export to Google Encoded Polyline format, or generate standard GeoJSON outputs.
  • Driver Safety (Speed & G-Force Monitor): Detect speed limit violations and identify sudden braking or acceleration events.
  • Privacy Guard: Fuzz location coordinates within a randomized radius or snap to a coarse grid resolution to safeguard user privacy.
  • Dead Reckoning Kinematic Engine: Extrapolate coordinates automatically using bearing and speed vector kinematics when GPS signals drop.
  • Battery & Network Eco-Optimizer: Recommend adaptive tracking configurations to prolong device battery life.
  • Anti-Spoofing & Fake GPS Engine: Automatically detects and filters mock locations, rooting apps, and physically impossible "teleportation" speed jumps. Ideal for ride-sharing and delivery tracking.
  • Route Deviation & Off-Route Detection: Emits alerts when a driver veers off their prescribed route by a configurable threshold.
  • Multi-Stop Journey Manager: Automates tracking progress along a multi-stop delivery or ride sequence, auto-advancing as waypoints are reached.
  • Live Streaming Adapter: Exposes an adapter to seamlessly push GPS streams directly to WebSockets or MQTT publishers at controlled rates.
  • OS Health Monitor: Continuously watches for silent OS permission downgrades or battery saver mode activations.
  • Severe Crash Detector: Identifies violent vehicular impacts by analyzing extreme G-force deceleration.
  • Indoor WiFi Centroid Locator: Estimate indoor coordinates by calculating a weighted centroid from surrounding access point RSSI strengths.

Getting Started #

Add the dependency to your pubspec.yaml:

dependencies:
  smart_location: ^3.0.0

🔥 Feature Spotlight: Headless Batched Sync #

Unlike basic location wrappers that die when the app is swiped away, smart_location acts as a true enterprise tracking engine:

  1. Unkillable Tracking: It natively binds to Android Foreground Services and iOS Background Tasks to track forever.
  2. Offline Resilience: If the user enters a tunnel, locations are seamlessly saved to an offline SQLite database.
  3. Battery-Optimized Headless Sync: Waking up the Dart VM constantly drains batteries. smart_location uses Android WorkManager and Apple BGTaskScheduler to wake up a hidden Dart Isolate once every 15 minutes. You register a Dart callback, we wake it up, and you bulk-upload your offline coordinates to Firebase or your REST API seamlessly!

Platform Setup #

Android #

In android/app/src/main/AndroidManifest.xml, add inside <manifest>:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

Background Location (optional):

<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>

iOS #

In ios/Runner/Info.plist, add:

<key>NSLocationWhenInUseUsageDescription</key>
<string>This app needs location access to provide better services.</string>

Background Location (optional):

<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>This app needs location access for background tracking.</string>

Background Sync (required for Headless Batching):

In ios/Runner/Info.plist, you must register the background task identifier:

<key>BGTaskSchedulerPermittedIdentifiers</key>
<array>
  <string>com.antigravity.smart_location.sync</string>
</array>
<key>UIBackgroundModes</key>
<array>
  <string>location</string>
  <string>fetch</string>
  <string>processing</string>
</array>

API Overview #

Primary Methods #

API Purpose
SmartLocation.ensureReady() Request permission + verify GPS is on
SmartLocation.current() One-time location fetch
SmartLocation.lastKnown() Last cached location (no GPS needed)
SmartLocation.stream Continuous live updates
SmartLocation.streamWithSettings(...) Live updates with custom accuracy/filter
SmartLocation.distanceBetween(...) Distance in meters between two points
SmartLocation.bearingBetween(...) Direction/heading between two points
SmartLocation.simplifyPath(...) Simplifies a list of coordinates using RDP

Advanced Sub-Managers #

Sub-Manager Class Purpose
SmartLocation.geofence GeofenceManager Client-side geofencing monitoring
SmartLocation.recorder RouteRecorder Path recording & live session stats
SmartLocation.speed SpeedMonitor Driver safety monitor (speeding, braking alerts)
SmartLocation.privacy PrivacyGuard Coordinate fuzzer and snapped grid utilities
SmartLocation.deadReckoning DeadReckoning Extrapolator watchdog during GPS signal drops
SmartLocation.matching MapMatching Path smoothing & road segment snapping
SmartLocation.eco EcoOptimizer Adaptive accuracy & distance configuration helper
SmartLocation.indoor IndoorEmulator WiFi / Bluetooth beacon RSSI centroid tracking
SmartLocation.antiSpoofing AntiSpoofingEngine Teleportation & OS-level mock location filter
SmartLocation.deviation OffRouteDetector Route deviation and off-route detection monitor
SmartLocation.liveStream LiveStreamingAdapter WebSockets / MQTT live tracking publisher adapter
SmartLocation.journey JourneyManager Multi-stop delivery tracking sequence auto-advancer
SmartLocation.health OSHealthMonitor Background permission and battery saver degradation watcher
SmartLocation.crash CrashDetector Severe vehicular impact / G-force deceleration monitor

Usage #

1. Initialize & Ensure Permissions #

import 'package:smart_location/smart_location.dart';

// Checks GPS status and requests location permission from the user
await SmartLocation.ensureReady();

2. Get Current Location #

try {
  final loc = await SmartLocation.current();
  print('Location: ${loc.latitude}, ${loc.longitude}');
} on LocationDisabledException {
  print('Please turn on GPS');
} on PermissionDeniedException {
  print('Permission was denied');
}

3. Listen to Location Stream #

SmartLocation.stream.listen((loc) {
  print('Moving to: ${loc.latitude}, ${loc.longitude}');
});

Advanced Features Usage #

1️⃣ Client-Side Geofencing (Spatial Hash Optimized) #

Efficiently monitors multiple circular geofences using a spatial grid. Emits transition events when entering, exiting, or dwelling in a zone.

// 1. Create a geofence with enter, exit, and dwell triggers
final geofence = Geofence(
  id: 'office_HQ',
  latitude: 37.7749,
  longitude: -122.4194,
  radiusInMeters: 100.0,
  triggerTypes: {GeofenceTrigger.enter, GeofenceTrigger.exit, GeofenceTrigger.dwell},
  dwellDuration: const Duration(minutes: 5),
);

// 2. Register and start monitoring
SmartLocation.geofence.addGeofence(geofence);
SmartLocation.geofence.startMonitoring(SmartLocation.stream);

// 3. Listen to transition events
SmartLocation.geofence.events.listen((event) {
  print('Geofence Event [${event.geofenceId}]: ${event.triggerType}');
});

2️⃣ Route Recorder & Compression Utilities #

Record user journeys, gather statistics (duration, distance, coordinates count), and format paths for mapping and storage optimization.

// Start recording the route
SmartLocation.recorder.start(SmartLocation.stream);

// Read live session statistics
print('Recorded Distance: ${SmartLocation.recorder.totalDistanceInMeters} m');
print('Elapsed Time: ${SmartLocation.recorder.elapsedTime}');

// Stop recording and retrieve path coordinates
final List<LocationData> path = SmartLocation.recorder.stop();

// Simplify the route path to reduce storage size (Ramer-Douglas-Peucker algorithm)
final List<LocationData> simplified = SmartLocation.simplifyPath(path, 10.0); // 10m tolerance

// Convert path to Google Encoded Polyline format
final String polyline = SmartLocation.maps.encodePolyline(simplified);

// Export coordinates to standard GeoJSON maps
final Map<String, dynamic> pointGeoJson = GeoJsonExporter.toPointMap(path.last);
final Map<String, dynamic> lineGeoJson = GeoJsonExporter.toLineStringMap(simplified);

3️⃣ Driver Safety Monitor (Speeding & Sudden G-Force Events) #

Evaluates speed thresholds and detects sudden acceleration or harsh braking rates.

// Configure limits: speed limit and deceleration/acceleration rates
SmartLocation.speed.configure(
  speedLimitKmh: 80.0,
  suddenDecelThresholdKmhPerSec: 15.0, // harsh brake threshold
  suddenAccelThresholdKmhPerSec: 10.0, // harsh acceleration threshold
);

// Start monitoring the GPS stream
SmartLocation.speed.startMonitoring(SmartLocation.stream);

// Receive alerts
SmartLocation.speed.speedAlerts.listen((alert) {
  print('Speed Warning: ${alert.message}'); // Speed limit exceeded
});

SmartLocation.speed.gForceAlerts.listen((alert) {
  print('G-Force Warning: ${alert.message}'); // Harsh braking or acceleration
});

4️⃣ Privacy Guard (Location Obfuscation) #

Protects user identity and location patterns by adding a random displacement radius or snapping coordinates to a coarse degrees grid resolution.

final LocationData rawLocation = await SmartLocation.current();

// 1. Fuzz: Offset coordinates randomly within a 500-meter radius
final LocationData fuzzedLocation = PrivacyGuard.fuzz(rawLocation, radiusInMeters: 500.0);

// 2. Snap to Grid: Snaps coordinates to the nearest degree intersection (e.g. 0.01 degrees)
final LocationData snappedLocation = PrivacyGuard.snapToGrid(rawLocation, gridSizeDegrees: 0.01);

5️⃣ Dead Reckoning Fallback Engine #

Keeps navigation UI fluent and responsive during GPS drops or indoor transitions by automatically extrapolating coordinates based on previous velocity and bearing heading vectors.

// Start the dead reckoning engine
SmartLocation.deadReckoning.start(
  gpsStream: SmartLocation.stream,
  onUpdate: (location) {
    if (location.isMocked) {
      print('Extrapolated Position: ${location.latitude}, ${location.longitude}');
    } else {
      print('GPS Raw Position: ${location.latitude}, ${location.longitude}');
    }
  },
  staleThreshold: const Duration(seconds: 3), // triggers DR when GPS is stale for 3 seconds
  extrapolationInterval: const Duration(seconds: 1),
);

// Stop engine when done
SmartLocation.deadReckoning.stop();

6️⃣ Battery & Network Eco-Optimizer #

Implements power-saving strategies adaptively based on battery percent levels and connectivity states.

// Query optimal configuration recommendations
final LocationAccuracy accuracy = SmartLocation.eco.getOptimizedAccuracy(
  batteryLevelPercent: 25.0,
  hasNetwork: true,
);

final int filter = SmartLocation.eco.getOptimizedDistanceFilter(
  batteryLevelPercent: 25.0,
  hasNetwork: true,
);

// Listen to stream using recommended eco configurations
final ecoStream = SmartLocation.streamWithSettings(
  accuracy: accuracy,
  distanceFilter: filter,
);

7️⃣ Indoor WiFi / Beacon Centroid Locator #

Calculates the device position indoors using the weighted average signal strengths of surrounding beacons or Wi-Fi access points.

// 1. Register indoor beacon/Wi-Fi locations
SmartLocation.indoor.registerBeacons({
  'Lobby_AP': LocationData(latitude: 37.774900, longitude: -122.419400, accuracy: 2.0, altitude: 0, speed: 0, speedAccuracy: 0, heading: 0),
  'ConfRoom_AP': LocationData(latitude: 37.775200, longitude: -122.419000, accuracy: 3.0, altitude: 0, speed: 0, speedAccuracy: 0, heading: 0),
});

// 2. Estimate position based on scanned signal levels (dBm RSSI)
final LocationData? estimatedLocation = SmartLocation.indoor.locateBySignals({
  'Lobby_AP': -40.0,
  'ConfRoom_AP': -90.0,
});

8️⃣ Anti-Spoofing & Fake GPS Detection Engine (New!) #

Crucial for ride-sharing and delivery logistics. By default, SmartLocation.stream uses aggressive filtering and automatically drops spoofed coordinates. It detects mock flags and impossible teleportation jumps.

// Listen to spoofing alerts to warn the user or flag their account internally
SmartLocation.antiSpoofing.alerts.listen((alert) {
  print('Spoofing Detected: ${alert.reason}'); // "OS marked as mock" or "Teleportation detected"
});

// If you prefer to allow fake locations through the stream (e.g. for debug mode):
SmartLocation.antiSpoofing.isAggressiveFilteringEnabled = false;

9️⃣ Route Deviation & Off-Route Detection #

Crucial for ride-sharing safety and delivery tracking. Pass an expected route to the SDK, and it will emit alerts if the driver veers too far off course.

// Set the expected route (list of LocationData coordinates)
SmartLocation.deviation.expectedRoute = [
  LocationData(latitude: 37.7749, longitude: -122.4194, /* ... */),
  LocationData(latitude: 37.7750, longitude: -122.4180, /* ... */),
];

// Configure how far they can deviate before triggering an alert (e.g., 50 meters)
SmartLocation.deviation.deviationThresholdMeters = 50.0;

// Start monitoring against the live GPS stream
SmartLocation.deviation.startMonitoring(SmartLocation.stream);

// Listen to deviations
SmartLocation.deviation.alerts.listen((event) {
  print('Driver is OFF ROUTE! Deviated by ${event.deviationDistanceMeters}m');
});

🔟 Ultimate Enterprise Modules #

For bleeding-edge ride-sharing and logistics, we offer these 4 advanced modules out of the box:

// 1. Live Streaming Adapter (WebSockets / MQTT)
SmartLocation.liveStream.startStreaming(
  gpsStream: SmartLocation.stream,
  publisher: (location) => myWebSocket.sink.add(location.toJson()),
);

// 2. Multi-Stop Journey Manager
SmartLocation.journey.startJourney(stops: deliveryStops, gpsStream: SmartLocation.stream);
SmartLocation.journey.arrivals.listen((event) => print('Arrived at stop ${event.stopIndex}'));

// 3. OS Health Monitor (Silent Death Prevention)
SmartLocation.health.startMonitoring();
SmartLocation.health.degradationAlerts.listen((event) => print('OS constrained location: ${event.reason}'));

// 4. Severe Crash Detector
SmartLocation.crash.startMonitoring(SmartLocation.stream);
SmartLocation.crash.crashAlerts.listen((alert) => print('SOS! Crash detected! ${alert.decelerationGForce} Gs'));

Error Handling #

Always wrap location requests in a try-catch to handle disabled services and permission states:

try {
  await SmartLocation.ensureReady();
  final loc = await SmartLocation.current();
} on LocationDisabledException {
  // GPS is OFF → prompt user to enable
} on PermissionDeniedException {
  // Permission denied (can ask again)
} on PermissionPermanentlyDeniedException {
  // Denied forever → open app settings
} catch (e) {
  // Other unexpected errors
}

Best Practices #

  • Always call ensureReady() before accessing location data.
  • Use distanceFilter in streamWithSettings or utilize EcoOptimizer recommendations to save battery.
  • Use lastKnown() to populate the UI instantly on startup.
  • Always handle all three permission exception types explicitly.
  • Cancel stream subscriptions when they are no longer needed to prevent memory leaks.
5
likes
0
points
549
downloads

Publisher

unverified uploader

Weekly Downloads

Smart Location is a powerful, battery-conscious Flutter plugin for continuous background geolocation tracking, advanced geofencing, and motion-aware updates.

Repository (GitHub)
View/report issues

Topics

#geofencing #background #geolocation #location #tracking

License

unknown (license)

Dependencies

flutter, flutter_web_plugins, geolocator, http, plugin_platform_interface, web

More

Packages that depend on smart_location

Packages that implement smart_location