smart_location_plus 0.2.0
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 23or 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_handlerto request it before callingwatchZone().
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 #
- geolocator — Location tracking
- geocoding — Address resolution
- native_geofence — Battery-efficient native geofencing
License #
MIT