In Flutter development, accessing the device’s current location is a common requirement for various applications such as mapping, navigation, and location-based services. The geolocator package is a popular and powerful tool that simplifies the process of retrieving the device’s geographical location. This article will guide you through the process of using the geolocator package in Flutter to get the device’s current location.
What is the geolocator Package?
The geolocator package is a Flutter plugin for accessing location services on Android and iOS platforms. It provides a simple and consistent API to retrieve the device’s current location, monitor location changes, and calculate distances between geographical coordinates.
Why Use geolocator?
- Cross-Platform: Works seamlessly on both Android and iOS.
- Easy to Use: Simple and intuitive API for location services.
- Feature-Rich: Supports various functionalities such as retrieving current location, continuous location updates, and distance calculations.
- Well-Maintained: Actively maintained with good community support.
How to Use the geolocator Package in Flutter
To use the geolocator package, follow these steps:
Step 1: Add the geolocator Dependency
Add the geolocator package to your Flutter project’s pubspec.yaml file:
dependencies:
flutter:
sdk: flutter
geolocator: ^10.1.1
After adding the dependency, run flutter pub get to install the package.
Step 2: Configure Permissions
Before retrieving the device’s location, you need to configure the necessary permissions in both Android and iOS:
Android Configuration
Add the following permissions to your AndroidManifest.xml file located in android/app/src/main:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
...
For Android API level 31 and above, you need to declare the ACCESS_BACKGROUND_LOCATION permission if you plan to access location in the background:
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
Also, for Android 12 (API level 31) and higher, you may need to explicitly declare that your app targets this API level by setting the android:targetSdkVersion attribute in your android/app/build.gradle file:
android {
compileSdkVersion 33
defaultConfig {
applicationId "your.package.name"
minSdkVersion 21
targetSdkVersion 33
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
...
}
iOS Configuration
Add the following keys to your Info.plist file located in ios/Runner:
<key>NSLocationWhenInUseUsageDescription</key>
<string>This app needs access to your location when open to provide location-based services.</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>This app needs access to your location in the background to provide continuous location updates.</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>This app needs access to your location when in use and in the background.</string>
Note: It is recommended to include all three keys (NSLocationWhenInUseUsageDescription, NSLocationAlwaysUsageDescription, and NSLocationAlwaysAndWhenInUseUsageDescription) for comprehensive coverage.
Step 3: Request Location Permissions
Before accessing the device’s location, you should request location permissions from the user. This can be done using the Geolocator.requestPermission() method:
import 'package:geolocator/geolocator.dart';
Future<bool> handleLocationPermission() async {
bool serviceEnabled;
LocationPermission permission;
// Test if location services are enabled.
serviceEnabled = await Geolocator.isLocationServiceEnabled();
if (!serviceEnabled) {
// Location services are not enabled don't continue
// accessing the position and request users of the
// App to enable the location services.
print('Location services are disabled.');
return false;
}
permission = await Geolocator.checkPermission();
if (permission == LocationPermission.denied) {
permission = await Geolocator.requestPermission();
if (permission == LocationPermission.denied) {
// Permissions are denied, next time you could try
// requesting permissions again (this is also where
// Android's shouldShowRequestPermissionRationale
// returned true. According to Android guidelines
// your App should show an explanatory UI now.
print('Location permissions are denied');
return false;
}
}
if (permission == LocationPermission.deniedForever) {
// Permissions are denied forever, handle appropriately.
print('Location permissions are permanently denied, we cannot request permissions.');
return false;
}
// When we reach here, permissions are granted and we can
// continue accessing the position of the device.
print('Location permissions are granted');
return true;
}
Step 4: Get Current Location
To retrieve the device’s current location, use the Geolocator.getCurrentPosition() method:
import 'package:geolocator/geolocator.dart';
Future<Position?> getCurrentLocation() async {
final hasPermission = await handleLocationPermission();
if (!hasPermission) {
return null;
}
try {
Position position = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.high,
);
print('Latitude: ${position.latitude}, Longitude: ${position.longitude}');
return position;
} catch (e) {
print('Error getting location: $e');
return null;
}
}
In this example, Geolocator.getCurrentPosition() is called with desiredAccuracy set to LocationAccuracy.high to retrieve the most accurate location. Adjust the accuracy as needed for your use case.
Step 5: Integrate into Your Flutter App
Here’s how you can integrate the location retrieval process into a simple Flutter app:
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Location Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
String _location = 'Press the button to get location';
Future<void> _getCurrentLocation() async {
Position? position = await getCurrentLocation();
if (position != null) {
setState(() {
_location = 'Latitude: ${position.latitude}, Longitude: ${position.longitude}';
});
} else {
setState(() {
_location = 'Could not get location';
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter Location Demo'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
_location,
style: TextStyle(fontSize: 16),
textAlign: TextAlign.center,
),
SizedBox(height: 20),
ElevatedButton(
onPressed: _getCurrentLocation,
child: Text('Get Current Location'),
),
],
),
),
);
}
}
Additional Tips
- Handle Errors: Implement proper error handling to gracefully manage scenarios where location retrieval fails (e.g., location services disabled, permissions denied).
- Background Location Updates: For applications requiring continuous location tracking, consider using the
Geolocator.getPositionStream()method to listen for location changes. Be mindful of battery consumption and user privacy. - Optimize Accuracy: Adjust the
desiredAccuracyparameter inGeolocator.getCurrentPosition()based on your app’s needs to balance accuracy and battery usage. - User Education: Provide clear and concise explanations to users about why your app needs location permissions and how the location data will be used.
Conclusion
The geolocator package simplifies the process of retrieving the device’s current location in Flutter. By following the steps outlined in this article, you can easily integrate location services into your Flutter applications, providing enhanced functionality and user experiences. Remember to handle permissions gracefully, optimize accuracy, and educate users about location usage to build a robust and user-friendly app.