How to fetch current location of user in Flutter?
Tags: flutter, dart, location
Published: 2021-11-17 19:59:26

## Introduction:
There are times when we want to access the end user's GPS location. Be it an E-commerce industry or a food delivery app, accessing the GPS location is needed to offer better user experience and provide better services.

In this article, we will see how to fetch a user's location and display the address in Flutter using the [location](https://pub.dev/packages/location) plugin.

## Setup
Go to `pubspec.yaml` file and add `location` plugin under dependencies and then run flutter pub get.
```
dependencies:
  location: ^4.2.0
```

### Android
If the project was created with Flutter 1.12 and above, all dependencies will be installed automatically. 

If the project was created before Flutter 1.12, follow the steps below.
Go to `android/app/src/main/AndroidManifest.xml` and add the following code inside the application tag. 
```xml
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
```

### iOS
Go to `ios/Runner/Info.plist` and add the following permission.
```swift
<key>NSLocationWhenInUseUsageDescription</key>
<key>NSLocationAlwaysUsageDescription</key>
```

With this, we are all set to use the `location` plugin in our Flutter application.

## Implementation
```dart
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:geocoder/geocoder.dart';
import 'package:location/location.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Location',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: getLocation(),
    );
  }
}

class getLocation extends StatefulWidget {
  @override
  _MyLocationState createState() => _MyLocationState();
}

class _MyLocationState extends State<getLocation> {
  LocationData _currentPosition;
  String _address;
  Location location = new Location();

  @override
  void initState() {
    super.initState();
    fetchLocation();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Flutter Location"),
      ),
      body: Container(
        child: SafeArea(
          child: Column(
            children: [
              if (_currentPosition)
                Text(
                  "Latitude: ${_currentPosition.latitude}",
                  style: TextStyle(fontSize: 22, fontWeight: FontWeight.w600),
                ),
              if (_currentPosition)
                Text(
                  "Longitude: ${_currentPosition.longitude}",
                  style: TextStyle(fontSize: 22, fontWeight: FontWeight.w600),
                ),
              if (_address)
                Text(
                  "Address: $_address",
                  style: TextStyle(
                    fontSize: 16,
                  ),
                ),
            ],
          ),
        ),
      ),
    );

  fetchLocation() async {}
  Future<List<Address>> getAddress(double lat, double lang) async {}
  }

```
Here, we have imported two libraries `location` and `geocoding` that will be used to fetch the GPS location and to convert a co-ordinate into Address respectively.

We have also created two functions at the bottom and invoked `fetchLocation` in the initState() method. When the app will start, it will fetch the GPS location of the user asynchronously and update the `Text` widget used in the Container.

Let's see how the `fetchLocation` method will be like.

### fetchLocation()
In order to request location, we need to manually check if `Location Service` status and `Permission` status are available every time.

If we have both the permissions then only we can fetch the location using the `getLocation()` method. We can also get continuous callbacks when the position changes using `onLocationChanged` event listener.

```dart
fetchLocation() async {
    bool _serviceEnabled;
    PermissionStatus _permissionGranted;

    _serviceEnabled = await location.serviceEnabled();
    if (!_serviceEnabled) {
      _serviceEnabled = await location.requestService();
      if (!_serviceEnabled) {
        return;
      }
    }

    _permissionGranted = await location.hasPermission();
    if (_permissionGranted == PermissionStatus.denied) {
      _permissionGranted = await location.requestPermission();
      if (_permissionGranted != PermissionStatus.granted) {
        return;
      }
    }

    _currentPosition = await location.getLocation();
    location.onLocationChanged.listen((LocationData currentLocation) {
      setState(() {
        _currentPosition = currentLocation;
        getAddress(_currentPosition.latitude, _currentPosition.longitude)
            .then((value) {
          setState(() {
            _address = "${value.first.addressLine}";
          });
        });
      });
    });
  }
```
### getAddress()
Once we get the geographic co-ordinates of the user, we use the `getAddress()` method to parse it into an address. 

The geocoder provides a `findAddressesFromCoordinates()` method for it.

```dart
  Future<List<Address>> getAddress(double lat, double lang) async {
    final coordinates = new Coordinates(latitude, longitude);
    List<Address> address =
        await Geocoder.local.findAddressesFromCoordinates(coordinates);
    return address;
  }
}
```
With this, we have added the `location` plugin in our Flutter Application. On running the application the output should look like this.

![Output](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ucx8hzwscce9drgvvor2.png)

Thanks for the read. I hope this article helped you to get started with Location plugin in Flutter.

You can connect with me on [Twitter](https://twitter.com/shubhHAM_) for any discussion.

Happy Coding!