Flutter Google Maps and Live Location Tracking
Lets Learn about a new functionality today and build a very simple application that tracks a users location in real time. Lets start
Github Link to the repository:
https://github.com/Aayushbajaj505/Live_locationtracking_flutter.git
We need three packages for pubdev:
google_maps_flutter: ^2.0.6
location: ^4.2.0
provider: ^5.0.0
The flutter google maps and location package.
Steps :
These steps are also mentioned on the google maps plugin page as well
- Go to google developer console
2. Create a new project
3. Go to API
4. Enable maps sdk for android and maps sdk for ios
5. Go to credentials and create a new api key
6. Make the changes specified on the google maps plugin page and add all the dependencies mentioned.
7. Go to Info.plist in ios/Runner/info.plist and add a new key
<key>io.flutter.embedded_views_preview</key><string>YES</string>
8. Create a stateful widget as such and call it from the main .dart:
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
class GoogleMapsPage extends StatefulWidget {
const GoogleMapsPage({Key? key}) : super(key: key);
@override
_GoogleMapsPageState createState() => _GoogleMapsPageState();
}
class _GoogleMapsPageState extends State<GoogleMapsPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.purpleAccent,
title: Text("Live Tracking Demo"),
),
body: Column(
children: <Widget>[
Expanded(
child: GoogleMap(
mapType: MapType.normal,
initialCameraPosition: CameraPosition(
target: LatLng(28.5985, 77.6546),
zoom: 15,
),
// onMapCreated: GoogleMapController controller,
),
)
],
),
);
}
}
And we have the google maps enabled to a static location we entered.
Now onto the Live location part.
Create A provider file with the following code:
import 'package:flutter/material.dart';
import 'package:location/location.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
class LocationProvider with ChangeNotifier {
// create a location varibale
late Location _location;
//create a getter so that its not exposed
Location get location => _location;
LatLng _locationPosition=LatLng(28.5546,29.5546);
LatLng get locationPosition => _locationPosition;
bool locationServiceActive = true;
LocationProvider() {
_location = new Location();
}
initialization() async {
getuserLocation();
}
getuserLocation() async {
bool _serviceenabled;
PermissionStatus _permissionGranted;
// check if user is having permission or not
_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 ||
_permissionGranted == PermissionStatus.grantedLimited) return;
}
location.onLocationChanged.listen((LocationData currentlocation) {
_locationPosition = LatLng(
currentlocation.latitude!.toDouble(),
currentlocation.longitude!.toDouble(),
);
});
print(_locationPosition);
notifyListeners();
}
}
And then we modify the original stateful widget to this:
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:practiseproject/Provider/location_provider.dart';
import 'package:provider/provider.dart';
class GoogleMapsPage extends StatefulWidget {
const GoogleMapsPage({Key? key}) : super(key: key);
@override
_GoogleMapsPageState createState() => _GoogleMapsPageState();
}
class _GoogleMapsPageState extends State<GoogleMapsPage> {
@override
void initState() {
super.initState();
Provider.of<LocationProvider>(context, listen: false).initialization();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.purpleAccent,
title: Text("Live Tracking Demo"),
),
body: googleMapUI());
}
}
Widget googleMapUI() {
return Consumer<LocationProvider>(
builder: (consumerContext, model, child) {
if (model.locationPosition != null) {
return Column(
children: <Widget>[
Expanded(
child: GoogleMap(
mapType: MapType.normal,
initialCameraPosition: CameraPosition(
target: model.locationPosition,
zoom: 15,
),
myLocationEnabled: true,
myLocationButtonEnabled: true,
onMapCreated: (GoogleMapController controller) {},
),
)
],
);
}
return Container(
child: Center(
child: CircularProgressIndicator(),
),
);
},
);
}
we also modify the main.dart to :
import 'package:flutter/material.dart';
import 'package:practiseproject/Provider/location_provider.dart';
import 'package:practiseproject/google_maps.dart';
import 'package:provider/provider.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(
create: (context) => LocationProvider(),
child: GoogleMapsPage(),
),
],
child: MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: GoogleMapsPage(),
),
);
}
}
Thanks.