smart_location_plus 0.2.0 copy "smart_location_plus: ^0.2.0" to clipboard
smart_location_plus: ^0.2.0 copied to clipboard

A unified Flutter location package combining geolocator, geocoding, and native geofencing into one simple, powerful API. Battery-efficient, platform-native geofencing. Zero boilerplate, full customization.

smart_location_plus #

A unified Flutter location package that combines geolocator, geocoding, and native geofencing into one clean, easy-to-use API — powered by platform-native geofencing APIs (CLLocationManager on iOS, GeofencingClient on Android) for battery-efficient, reliable geofencing.

Zero boilerplate by default. Full customization when you need it.


Why smart_location_plus? #

Without smart_location_plus With smart_location_plus
3 packages to learn 1 API
50+ lines of boilerplate 1–3 lines
Manual permission checks Auto-handled
Geocoding is a separate async step Auto-resolved
Complex geofence setup watchZone() with simple callbacks

Installation #

dependencies:
  smart_location_plus: ^0.1.0

Android — AndroidManifest.xml #

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- Required for background / geofencing -->
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WAKE_LOCK" />

Also add the following receivers inside the <application> tag for native geofencing support (geofence event handling and re-registration after device reboot):

<application ...>
    <!-- native_geofence receivers -->
    <receiver android:name="com.chunkytofustudios.native_geofence.NativeGeofenceBroadcastReceiver"
        android:exported="true">
        <intent-filter>
            <action android:name="com.chunkytofustudios.native_geofence.ACTION_GEOFENCE_EVENT" />
        </intent-filter>
    </receiver>
    <receiver android:name="com.chunkytofustudios.native_geofence.NativeGeofenceRebootBroadcastReceiver"
        android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </receiver>
</application>

Note: Android requires minSdkVersion 23 or higher for native geofencing.

iOS — Info.plist #

<key>NSLocationWhenInUseUsageDescription</key>
<string>This app needs location access to show relevant features.</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>This app uses background location for geofencing.</string>

Note: For geofencing to work when the app is in the background or terminated, users must grant "Always Allow" location permission.


Quick Start #

import 'package:smart_location_plus/smart_location_plus.dart';

// Get location + address in one call
final loc = await SmartLocation.locateOnce();
print(loc.address);   // "MG Road, Mumbai, Maharashtra, India"
print(loc.city);      // "Mumbai"
print(loc.latitude);  // 19.2183

API Reference #

locateOnce() #

// Zero config
final loc = await SmartLocation.locateOnce();

// Fully customized
final loc = await SmartLocation.locateOnce(
  locationConfig: LocationConfig(
    accuracy: LocationAccuracy.best,
    timeLimit: Duration(seconds: 8),
    activityType: ActivityType.automotiveNavigation,
  ),
  geocodingConfig: GeocodingConfig(
    localeIdentifier: 'hi',   // Hindi address
    maxResults: 3,
  ),
);

locateAndWatch() #

// Basic stream
SmartLocation.locateAndWatch().listen((loc) {
  print('${loc.latitude}, ${loc.longitude}');
});

// High accuracy, skip address for performance
SmartLocation.locateAndWatch(
  locationConfig: LocationConfig(
    accuracy: LocationAccuracy.high,
    distanceFilter: 10,
  ),
  geocodingConfig: GeocodingConfig(resolveAddress: false),
).listen((loc) => updateMap(loc));

reverseGeocode() and forwardGeocode() #

// Coordinates → address
final result = await SmartLocation.reverseGeocode(
  latitude: 19.2183,
  longitude: 73.0587,
  config: GeocodingConfig(localeIdentifier: 'en_IN'),
);
print(result.address);

// Address → coordinates
final result = await SmartLocation.forwardGeocode(
  address: 'Gateway of India, Mumbai',
);
print('${result.latitude}, ${result.longitude}');

watchZone() — Native Geofencing #

Geofencing is powered by the native_geofence package, which uses platform-native APIs (CLLocationManager on iOS, GeofencingClient on Android) for battery-efficient monitoring — even when the app is in the background or terminated.

await SmartLocation.watchZone(
  zones: [
    LocationZone(
      id: 'home',
      latitude: 19.2183,
      longitude: 73.0587,
      config: GeofenceConfig(
        radius: 100,
        loiteringDelay: 30000,
        listenFor: {GeofenceEvent.enter, GeofenceEvent.exit, GeofenceEvent.dwell},
      ),
      onEnter: (zone) => print('Home!'),
      onExit:  (zone) => print('Left home'),
      onDwell: (zone) => print('Still home'),
    ),
  ],
  globalConfig: GeofenceConfig(
    onError: (e) => print(e),
  ),
);

// Dynamically add a zone
await SmartLocation.addZone(LocationZone(
  id: 'office',
  latitude: 19.3000,
  longitude: 73.0700,
  config: GeofenceConfig(radius: 200),
  onEnter: (zone) => print('Arrived at office!'),
));

// Remove a specific zone
await SmartLocation.stopWatchingZone(id: 'office');

// Stop all geofencing
await SmartLocation.stopWatchingZones();

Geofencing requires "Always Allow" location permission. Use a package like permission_handler to request it before calling watchZone().

Utilities #

// Distance between two points
final metres = SmartLocation.distanceBetween(
  startLat: 19.2183, startLng: 73.0587,
  endLat: 19.3000,   endLng: 73.0700,
);

// Bearing
final degrees = SmartLocation.bearingBetween(...);

// Is point inside zone?
final inside = SmartLocation.isInsideZone(
  latitude: 19.2185, longitude: 73.0589,
  zone: LocationZone(id: 'home', latitude: 19.2183, longitude: 73.0587),
);

Error Handling #

try {
  final loc = await SmartLocation.locateOnce();
} on LocationServiceDisabledException {
  // GPS is off
} on LocationPermissionDeniedException {
  // User denied permission
} on LocationPermissionPermanentlyDeniedException {
  await SmartLocation.openAppSettings();
} on LocationTimeoutException {
  // Took too long
} on AddressNotFoundException {
  // Geocoding failed
}

Powered By #

License #

MIT

2
likes
140
points
24
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A unified Flutter location package combining geolocator, geocoding, and native geofencing into one simple, powerful API. Battery-efficient, platform-native geofencing. Zero boilerplate, full customization.

Repository (GitHub)
View/report issues

Topics

#location #geocoding #geofencing #gps #tracker

License

MIT (license)

Dependencies

flutter, geocoding, geolocator, native_geofence

More

Packages that depend on smart_location_plus