DEV Community

Cover image for Flutter: wait user enable GPS permission & location
ahmedcharef
ahmedcharef

Posted on

Flutter: wait user enable GPS permission & location

Getting user’s current location is the most important task in apps those provides services like food ordering, transportation, health tracking, social networking or lot more. This location information mainly based on getting user’s latitude & longitude. Using latitude & longitude values, you can easily determine the exact location of a user.

What is Latitude and Longitude ?

Latitude and longitude are angles that uniquely define points on a sphere. Together, the angles comprise a coordinate scheme that can locate or identify geographic positions on the surfaces of planets such as the earth.

What is Flutter?

Flutter is a free and open-source mobile UI framework created by Google and released in May 2017.
It’s a cross-platform tool intended for creating Android and iOS apps from a single code base by using a modern, reactive framework.
To develop with Flutter, you will use a programming language called Dart. The language was created also by Google in October 2011, but it has improved a lot over these past years.

New Flutter project

Let’s start by creating a new flutter project, just copy&paste the following commnad lines in the terminal.

#New Flutter project
$ flutter create gpsproject

#Open the project with VisualStudio code
$ cd gpsproject && code .
Enter fullscreen mode Exit fullscreen mode

In the website pub.dev you can search and find useful packages to build Dartand flutter apps.
There is two plugins for GPS location that we can use it with Flutter, let’s get started by exploring them.

Flutter Location Plugin

This plugin for Flutter handles getting location on Android and iOS. It also provides callbacks when location is changed. Even it provides settings for optimizing performance or battery.
1.Add this to file pubspec.yamlfile:

dependencies:
  location: ^3.0.1
Enter fullscreen mode Exit fullscreen mode

Wait for flutter pub get finish downloading dependencies
flutter pub get
2.Add a permission to Android Manifest:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
Enter fullscreen mode Exit fullscreen mode

3.Add permissions to iOS Info.plist

<key>NSLocationAlwaysUsageDescription</key>
<string>Needed to access location</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Needed to access location</string>
Enter fullscreen mode Exit fullscreen mode

4.Now in your Dart code, you can use:

import 'package:location/location.dart';

Flutter Geolocator Plugin

This plugin provides a cross-platform (iOS, Android) API for generic location (GPS etc.) functions, it has some features as shown bellow:

  • Get the last known location;
  • Get continuous location updates;
  • Check if location services are enabled on the device;
  • Translate an address to geocoordinates and vice verse (a.k.a. Geocoding);
  • Calculate the distance (in meters) between two geocoordinates;
  • Check the availability of Google Play services (on Android only).

1.Add this to file pubspec.yaml file:

dependencies:
  geolocator: ^5.3.0
Enter fullscreen mode Exit fullscreen mode

Wait for flutter pub get finish downloading dependencies
flutter pub get
2.Add a permission to Android Manifest:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
Enter fullscreen mode Exit fullscreen mode

3.Add permissions to iOS Info.plist

<key>NSLocationAlwaysUsageDescription</key>
<string>Needed to access location</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Needed to access location</string>
Enter fullscreen mode Exit fullscreen mode

Add the following to your gradle.properties file:

android.useAndroidX=true
android.enableJetifier=true
Enter fullscreen mode Exit fullscreen mode

4.Make sure you set the compileSdkVersion in your android/app/build.gradle file to 28:

android {
 compileSdkVersion 28
 ...
}
Enter fullscreen mode Exit fullscreen mode

5.Now in your Dart code, you can use:

import 'package:geolocator/geolocator.dart';
Enter fullscreen mode Exit fullscreen mode

Flutter Permission handler Plugin

This plugin provides a cross-platform (iOS, Android) API to request and check permissions. Below you can find some features about this plugin:

  • Check if a permission is granted.
  • Request permission for a specific feature.
  • Open app settings so the user can enable a permission. We will use this plugin to check the permission status of location service.

1.Add this to file pubspec.yaml file:

dependencies:
  permission_handler: ^4.4.0+hotfix.2
Enter fullscreen mode Exit fullscreen mode

2.Now in your Dart code, you can use:
import 'package:permission_handler/permission_handler.dart';
The possible permission statuses are:
Granted: Your app has been given permission to use the feature in question.
Denied: Your app has been given permission to use the feature in question.
Disabled: Feature in question is disabled i.e. when the Location feature is disabled.
Restricted: (iOS only)OS has restricted access to a specific feature due to something like parental controls.
Unknown: Unknown state of permissions.

Android Intent Plugin

This plugin allows Flutter apps to launch arbitrary intents when the platform is Android. Not supported on iOS.
We will use this plugin to open settings -> location menu.

1.Add this to file pubspec.yaml file:

dependencies:
  android_intent: ^0.3.6+12.
Enter fullscreen mode Exit fullscreen mode

2.Now in your Dart code, you can use:
import 'package:android_intent/android_intent.dart';

Show me code!

First, I would like to give the difference for some variables:
ACCESS_FINE_LOCATION is the most precise location coordinates.
ACCESS_COARSE_LOCATION gives results equal to about a city block.
NSLocationWhenInUseUsageDescription needs access to location when open app.
NSLocationAlwaysUsageDescriptionneeds access to location when the app run in the background.
NSLocationAlwaysAndWhenInUseUsageDescriptionneeds access to location when the app is open and in the background.
ACCESS_COARSE_LOCATION gives results equal to about a city block.
ACCESS_FINE_LOCATION is the most precise location coordinates.
ACCESS_COARSE_LOCATION gives results equal to about a city block.

Main file:

Let’s start by making changes in the main.dart file to contain the new AskForPermission widget found within gpsLocation.dart:

import 'package:flutter/material.dart';
import 'package:gpsproject/gpsLocation.dart';
void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter GPS Location Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: AskForPermission(),
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

The gpsLocation.dart contains the following code :

import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:android_intent/android_intent.dart';
import 'package:geolocator/geolocator.dart';
class AskForPermission extends StatefulWidget {
 @override
 _AskForPermissionState createState() => _AskForPermissionState();
}
class _AskForPermissionState extends State<AskForPermission> {
 final PermissionHandler permissionHandler = PermissionHandler();
 Map<PermissionGroup, PermissionStatus> permissions;
void initState() {
  super.initState();
  requestLocationPermission();
  _gpsService();
}
 Future<bool> _requestPermission(PermissionGroup permission) async {
final PermissionHandler _permissionHandler = PermissionHandler();
var result = await _permissionHandler.requestPermissions([permission]);
if (result[permission] == PermissionStatus.granted) {
  return true;
}
return false;
}
/*Checking if your App has been Given Permission*/
Future<bool> requestLocationPermission({Function onPermissionDenied}) async {
var granted = await _requestPermission(PermissionGroup.location);
if (granted!=true) {
  requestLocationPermission();
}
debugPrint('requestContactsPermission $granted');
return granted;
}
/*Show dialog if GPS not enabled and open settings location*/
Future _checkGps() async {
 if (!(await Geolocator().isLocationServiceEnabled())) {
  if (Theme.of(context).platform == TargetPlatform.android) {
showDialog(
   context: context,
   builder: (BuildContext context) {
    return AlertDialog(
     title: Text("Can't get gurrent location"),
     content:const Text('Please make sure you enable GPS and try again'),
     actions: <Widget>[
       FlatButton(child: Text('Ok'),
       onPressed: () {
         final AndroidIntent intent = AndroidIntent(
          action: 'android.settings.LOCATION_SOURCE_SETTINGS');
       intent.launch();
       Navigator.of(context, rootNavigator: true).pop();
       _gpsService();
      })],
     );
   });
  }
 }
}

/*Check if gps service is enabled or not*/
Future _gpsService() async {
if (!(await Geolocator().isLocationServiceEnabled())) {
  _checkGps();
  return null;
} else
return true;
}
@override
Widget build(BuildContext context) {
 return Scaffold(
  appBar: AppBar(
  title: Text('Ask for permisions'),
  backgroundColor: Colors.red,
 ),
 body: Center(
 child: Column(
 children: <Widget>[
  Text("All Permission Granted"),
 ],
 ))
);
}
}

Enter fullscreen mode Exit fullscreen mode

I hope you have learned something new ! ;)

Top comments (4)

Collapse
 
willyfejio profile image
fejio willy diland

très très utile même

Collapse
 
ahmedalshebeni profile image
Ahmed alshebeni

thank you , that was very helpful

Collapse
 
ahmedsbeta profile image
Ahmed Sbeta

thank you , that was very helpful :) , can i use this to get the device location even if there is no signal and no internet access ?

Collapse
 
florentin89 profile image
Florentin Lupascu

No you can't. You need GPS data, so the SIM from your phone need to have access to a satellite to provide you that location. And the internet is used if you want to store online that coordinates somewhere on a server.