Google Maps and Geolocation in Flutter

Google Maps and Geolocation in Flutter

Adding Officially Supported Google Maps in a Flutter app. Remove the current marker if not null as there is now a new location it needs to be at. Add marker at latitude and longitude.

Working with a user’s location is a common task that many apps require, yet the steps to implement a well working solution in an app is often confusing and has too much boilerplate required to set up. Most Flutter packages abstract away most or all of the boilerplate required and directly give users the most optimised solution and less hassle to deal with. Often this means some fine grained control is lost through abstraction, but most times it is not needed anyway.

You can look through a tutorial for implementing location in native android to see the immense and often not needed amount of information presented to app developers who simply want the user’s location or want to track it.

Today, we’ll look through implementing getting location, location tracking and geocoding in Flutter for both Android and iOS using two different plugins which give us a varied amount of control over the underlying APIs and then see the implementation of location with maps where we’ll track a user using a marker on a map.

Let’s get started.

Plugin 1: ‘location’

The ‘location’ plugin is the simplest way to get and track a user’s location without the hassle of any boilerplate code.

Setting up is simple enough:

  1. Add plugin to the pubspec.yaml
dependencies:
  location: ^1.4.1
  1. Add a permission to Android Manifest:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
  1. Add permissions to iOS Info.plist
<key>NSLocationAlwaysUsageDescription</key>
<string>Needed to access location</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Needed to access location</string>

And you’re done.

In Android 6.0+, we need to ask access to location in runtime, which this package handles on its own.

Getting a one-time location

It allows us to get two things:

  1. A one-time location of the user
  2. A stream allowing us to listen to the location of the user.

Let’s create a simple app which gets the one-time location of the user like above.

Like we discussed, this package does not need much setup and the code is rather straightforward.

First, simply initialise a Location object.

var location = new Location();

location is not the location of the user itself but a class that helps us get it.

The location is returned as a map with keys like “latitude”, “longitude”, etc.

Map<String, double> userLocation;

And finally, getting the location is as simple as:

userLocation = await location.getLocation();

That’s it.

For the complete code:

class GetLocationPage extends StatefulWidget {
  @override
  _GetLocationPageState createState() => _GetLocationPageState();
}

class _GetLocationPageState extends State<GetLocationPage> {

  var location = new Location();

  Map<String, double> userLocation;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            userLocation == null
                ? CircularProgressIndicator()
                : Text("Location:" +
                    userLocation["latitude"].toString() +
                    " " +
                    userLocation["longitude"].toString()),
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: RaisedButton(
                onPressed: () {
                  _getLocation().then((value) {
                    setState(() {
                      userLocation = value;
                    });
                  });
                },
                color: Colors.blue,
                child: Text("Get Location", style: TextStyle(color: Colors.white),),
              ),
            ),
          ],
        ),
      ),
    );
  }

  Future<Map<String, double>> _getLocation() async {
    var currentLocation = <String, double>{};
    try {
      currentLocation = await location.getLocation();
    } catch (e) {
      currentLocation = null;
    }
    return currentLocation;
  }
}

GetLocationPage.dart

Here, we get the latitude and longitude. Other factors available are:

  currentLocation["latitude"];
  currentLocation["longitude"];
  currentLocation["accuracy"];
  currentLocation["altitude"];
  currentLocation["speed"];
  currentLocation["speed_accuracy"]; //Not for iOS

Listening to location updates

Listening to location updates is not that different from getting location, we simply use a stream object provided by the plugin to listen to updates.

location.onLocationChanged().listen((Map<String,double> currentLocation) {
  print(currentLocation["latitude"]);
  print(currentLocation["longitude"]);
  print(currentLocation["accuracy"]);
  print(currentLocation["altitude"]);
  print(currentLocation["speed"]);
  print(currentLocation["speed_accuracy"]); 
});

An example page of this would be:

import 'package:flutter/material.dart';
import 'package:location/location.dart';

class ListenPage extends StatefulWidget {
  @override
  _ListenPageState createState() => _ListenPageState();
}

class _ListenPageState extends State<ListenPage> {

  Location location = Location();

  Map<String, double> currentLocation;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    location.onLocationChanged().listen((value) {
      setState(() {
        currentLocation = value;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Column(
        children: <Widget>[
          currentLocation == null
              ? CircularProgressIndicator()
              : Text("Location:" + currentLocation["latitude"].toString() + " " + currentLocation["longitude"].toString()),
        ],
      ),
    );
  }
}

ListenPage.dart

Which gives a similar page to the one we made with the first example, but this time, we listen for location.

This plugin was a simple one to use without much setup or control and was straightforward in use and intention. Next, we’ll see another which gives more control over the APIs involved and also allows for geocoding.

Plugin 2: ‘geolocator’

Setup

The setup for this plugin is more or less the same as the location. If you plan to use coarse location as well, add

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

to AndroidManifest.xml .

First, we will do the same two tasks with this plugin, which is more or less the same:

Get location once

Use the Geolocator object instead of Location and instead of a Map<String,double> , we get back a Position object.

Geolocator geolocator = Geolocator();

Position userLocation;

And we do this to take location:

currentLocation = await geolocator.getCurrentPosition(
    desiredAccuracy: LocationAccuracy.best);

Here, we can also set the location accuracy depending on the accuracy we need.

import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
import 'dart:async';

class GeoListenPage extends StatefulWidget {
  @override
  _GeoListenPageState createState() => _GeoListenPageState();
}

class _GeoListenPageState extends State<GeoListenPage> {
  Geolocator geolocator = Geolocator();

  Position userLocation;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _getLocation().then((position) {
      userLocation = position;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            userLocation == null
                ? CircularProgressIndicator()
                : Text("Location:" +
                    userLocation.latitude.toString() +
                    " " +
                    userLocation.longitude.toString()),
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: RaisedButton(
                onPressed: () {
                  _getLocation().then((value) {
                    setState(() {
                      userLocation = value;
                    });
                  });
                },
                color: Colors.blue,
                child: Text(
                  "Get Location",
                  style: TextStyle(color: Colors.white),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }

  Future<Position> _getLocation() async {
    var currentLocation;
    try {
      currentLocation = await geolocator.getCurrentPosition(
          desiredAccuracy: LocationAccuracy.best);
    } catch (e) {
      currentLocation = null;
    }
    return currentLocation;
  }
}

GeolocatorListenPage.dart

Get Location Updates

Updates are similar to the ‘location’ package but with enhanced options.

geolocator.getPositionStream().listen((position) {
  // Do something here
});

We can set the accuracy, time interval between updates, whether we want to force usage of Android location manager, etc.

geolocator
    .getPositionStream(LocationOptions(
        accuracy: LocationAccuracy.best, timeInterval: 1000))
    .listen((position) {
  // Do something here
});

Working with Geocoding

Geocoding is essentially the process of getting physical map co-ordinates and details for an address.

List<Placemark> placemark = await Geolocator().placemarkFromAddress("Gronausestraat 710, Enschede");

You can get all the details about the place as:

print(placemark[0].country);
print(placemark[0].position);
print(placemark[0].locality);
print(placemark[0].administrativeArea);
print(placemark[0].postalCode);
print(placemark[0].name);
print(placemark[0].subAdministratieArea);
print(placemark[0].isoCountryCode);
print(placemark[0].subLocality);
print(placemark[0].subThoroughfare);
print(placemark[0].thoroughfare);

We can also get the details of a place from the coordinates:

List<Placemark> placemark = await Geolocator().placemarkFromCoordinates(52.2165157, 6.9437819);

Getting the distance between coordinates

This plugin also allows us to calculate the distance between two coordinates as:

double distanceInMeters = await Geolocator().distanceBetween(52.2165157, 6.9437819, 52.3546274, 4.8285838);
Integrating location updates with Google Maps

To integrate Google Maps with location updates, we need to use the google_maps_flutter package and your choice of location plugin.

Let’s just use the ‘location’ package for now.

A precursor to this part is my “Exploring Google Maps in Flutter” article and I highly recommend you use it to set up Maps in your app.

Exploring Google Maps in Flutter

To integrate maps with location tracking, we simply need to use both the plugins in conjunction.

Let’s move a marker as the user changes location.

First, we create our MapController and Location objects to manipulate maps and location. (Assign mapController when map is initialised, as given in the upper article)

GoogleMapController mapController;
Location location = Location();

Next, we add a marker to store the current marker:

Marker marker;

Now, we listen to location updates.

location.onLocationChanged().listen((location) async {
  // Do something here
});

This is how we will move the marker when location is updated:

  1. Remove the current marker if not null as there is now a new location it needs to be at.
  2. Add marker at latitude and longitude.
  3. Move camera to new marker location and set other characteristics like zoom, bearing and tilt. (Details about this given in GMaps article)
location.onLocationChanged().listen((location) async {
  // Step 1
  if(marker != null) {
    mapController.removeMarker(marker);
  }
  // Step 2
  marker = await mapController?.addMarker(MarkerOptions(
    position: LatLng(location["latitude"], location["longitude"]),
  ));
  //Step 3
  mapController?.moveCamera(
    CameraUpdate.newCameraPosition(
      CameraPosition(
        target: LatLng(
          location["latitude"],
          location["longitude"],
        ),
        zoom: 20.0,
      ),
    ),
  );
});

And now the marker will update location when the user moves!

Here’s the complete demo page code:

class GoogleMapsDemo extends StatefulWidget {
  @override
  _GoogleMapsDemoState createState() => _GoogleMapsDemoState();
}

class _GoogleMapsDemoState extends State<GoogleMapsDemo> {
  GoogleMapController mapController;
  Location location = Location();

  Marker marker;

  @override
  void initState() {
    super.initState();
    location.onLocationChanged().listen((location) async {
      if(marker != null) {
        mapController.removeMarker(marker);
      }
      marker = await mapController?.addMarker(MarkerOptions(
        position: LatLng(location["latitude"], location["longitude"]),
      ));
      mapController?.moveCamera(
        CameraUpdate.newCameraPosition(
          CameraPosition(
            target: LatLng(
              location["latitude"],
              location["longitude"],
            ),
            zoom: 20.0,
          ),
        ),
      );
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: <Widget>[
          Container(
            height: MediaQuery.of(context).size.height,
            width: MediaQuery.of(context).size.width,
            child: GoogleMap(
              onMapCreated: (GoogleMapController controller) {
                mapController = controller;
              },
              options: GoogleMapOptions(
                cameraPosition: CameraPosition(
                  target: LatLng(37.4219999, -122.0862462),
                ),
                myLocationEnabled: true,
              ),
            ),
          ),
        ],
      ),
    );
  }
}

GMapsPlusLocation.dart

That’s it for this article! I hope you enjoyed it, and leave a few claps if you did. Follow me for more Flutter articles and comment for any feedback you might have about this article.

How to Create Liquid Swipe Animation in Flutter | Liquid Swipe Flutter

How to Create Liquid Swipe Animation in Flutter | Liquid Swipe Flutter

Today tutorial, I am going to show you how to create Liquid Swipe Animation in Flutter. liquid Swipe animation is amazing and its Created for iOS Platform and f

Today tutorial, I am going to show you how to create Liquid Swipe Animation in Flutter. liquid Swipe animation is amazing and its Created for iOS Platform and for React Native Platform. this animation Or Liquid Swipe Animation is Inspired by Cuberto.

Cuberto Liquid Swipe Animation

For this animation, we are will Need liquid_swipe Package. Liquid Swipe is the Unveils a New Page like Liquid Animation Just like the Above animation.

📱 What we're going to Build

How to Create Liquid Swipe Animation in Flutter

Let's Start the Tutorial

If you Don't know how to Create a Flutter app, check out Getting started with Flutter official tutorial.

Read More

11 Best Flutter Development Tools You Will Need As A Beginner | AllTechSavvy

11 Best Flutter Development Tools You Will Need As A Beginner | AllTechSavvy

In this tutorial, I am going to show you some of the Best Flutter development tools available in the market which will help you to make Development Produc

In this tutorial, I am going to show you some of the Best Flutter development tools available in the market which will help you to make Development Productivity Faster and Build Better Applications. Flutter is a Framework from google for Creating Cross-platform mobile apps.

Flutter is a Google UI Framework for Developers to Create Native applications for Mobile, Web, and Desktop Just in a Single Codebase. Flutter is Used by Millions of Developer Worldwide to create beautiful UI for their applications.we’ll look at some of the Best flutter development tools that can greatly improve your workflow and help you reduce development time.

Okay Without wasting any time. Let’s start in and Discover lots of New & awesome Flutter tools to develop your flutter apps like a legend.

Best Flutter Development Tool

#11. panache
Panache will help you to create beautiful themes for your flutter apps, you can customize colors & shapes in the apps.

Website: https://rxlabz.github.io/panache

#10.Codemagic
Codemagic is another awesome tool that’ll boost your flutter app development process. Cinemagic will test and release your flutter apps without issue & with no configuration. with the help Codemagic, you can automate the whole build process, test and release process of your flutter apps

Website: codemagic.io

#9.Appetize
Appetize is an Online web-based android Emulator and iOS simulator. Appetize will run Native mobile Apps in the browser with HTML and Javascript. which is easy to maintain and tacks.

Website: appetize.io

#8.TestMagic
TestMagic is a Free Companion app just like Codmagic for Fast & Easy testing of your android and iOS builds. Testmagics helps to distribute your builds and Testing android and Ios Apps on real devices as well as provide Feedback to your projects.

Website: testmagic.io

#7. Screenshots
A screenshot is a command-line utility for capturing Screenshots into the status bar placed in the device frame. Screenshots can be integrated into flutter to work transparently into Android and iOS.

Website: https://github.com/mmcc007/screenshots

#6.Supernova
Supernova Recently Introduced Support For Flutter Platform in Flutter interact. Supernova is a tool that helps you to Generate UI Code for Flutter. it’s support for material Design widgets a style manage that can bring the concepts of token and style into a flutter, you can have flutter app running side by side with Supernova and Change happen real-time.

Supernova will save your time by importing your Sketch Or Adobe Xd file, Select flutter as your export platform which will convert UI design into Production-ready Code.

Website: supernova.io

#5. Adobe Plugins For Flutter
Adobe Recently Released Plugins for Adobe Xd in Flutter Interact, which will Generate Code for Creating apps with flutter which is based on UI design in Adobe XD. this is Collaboration Between Google and Adobe that will be Expected to Released Early 2020. So Plugins will be Open Source According to Adobe.

Website: theblog.adobe.com

Read more

How to Create Splash Screen in a Flutter App | Splash Screen Tutorial

How to Create Splash Screen in a Flutter App | Splash Screen Tutorial

Splash Screen help Brand to get Noticed Or Brand Awareness so Today I am going to show how to create Splash screen in a flutter Splash Screen Animation can b...

Splash Screen help Brand to get Noticed Or Brand Awareness so Today I am going to show how to create Splash screen in a flutter

Splash Screen Animation can be a Simple Logo Animation of your Brand. this Splashscreen animation can be done with the help of the splashscreen package.

💻Splash Screen:- https://alltechsavvy.com/splash-screen-in-flutter-app/

👩‍💻Github Code: https://github.com/sagarshende23/flutter_splashscreen_example

👉👉👉Visit At:- https://alltechsavvy.com/👈👈👈

⚡⚡Best Flutter Development Tools⚡⚡
https://alltechsavvy.com/best-flutter-development-tools/

🔥Github Profile: https://github.com/sagarshende23