In this Flutter Tutorial we will learn how to use Google Maps in Flutter and track location by retrive current location from the device using Flutter Location package and display it on Google Maps using Marker Icon. This example track the liva location of the user and display on device on every 1 second. For this example we will use two packages Google Maps and Location packages. Check my previous example Integrate Google Maps in Flutter
What we will cover
Let's get started
Step 1: Create Flutter application
Step 2: Add required packages in pubspec.yaml file and run flutter pub add
dev_dependencies: flutter_test: sdk: flutter location: ^4.3.0 google_maps_flutter: ^2.0.6
|
Step 3: Now lets open Android directory if you are going to be implementing for Android and if you are going to implement ios relevant iOS side and read package description how to setup native side. Here we will be implementing Android side in this tutorial
Now add required permissions in the manifest file
uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> |
Add Maps Api in meta data
meta-data android:name="com.google.android.geo.API_KEY" android:value=""/> |
Refer my previous post about How to fetch Maps API key
Step 4: Load Google Maps
Let's add below code to load Google Maps
GoogleMap(
initialCameraPosition: _kGooglePlex,
onMapCreated: (GoogleMapController controller) {
_controller.complete(controller);
},
),
|
GoogleMap widget wil load different types of Maps, we will load this by handle the mapType property
enum MapType { /// Do not display map tiles. none, /// Normal tiles (traffic and labels, subtle terrain information). normal, /// Satellite imaging tiles (aerial photos) satellite, /// Terrain tiles (indicates type and height of terrain) terrain, /// Hybrid tiles (satellite images with some labels/overlays) hybrid, }
|
Add Markers to Google Maps?
To create marker object we need to create MarkerId to handle the markers
MarkerId markerId1=MarkerId("Current"); Marker marker1=Marker( markerId: markerId1, position: LatLng(17.385044, 78.486671), icon: BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueRed), infoWindow: InfoWindow( title: "Hytech City",onTap: (){ },snippet: "Snipet Hitech City" )); |
here is the code to add Markers to Map
GoogleMap( mapType: MapType.normal, initialCameraPosition: _kGooglePlex, onMapCreated: (GoogleMapController controller) { _controller.complete(controller); }, markers: Set.of(markers.values), )
|
Step 5: Fetch Current Location
Now we are able to load Google Maps on device. Now we need to fetch the current location of the device. To fetch current location we need to take location permissions and check the Enable Location services in the device.
Check the Location services enabled by
initPlatformState() async { await _locationService.changeSettings(accuracy: LocationAccuracy.high, interval: 1000); LocationData? locationData; try { bool serviceEnabled = await _locationService.serviceEnabled(); if (serviceEnabled) { PermissionStatus p; _permissionGranted = (await _locationService.requestPermission()); if (_permissionGranted!.index==0) { locationData = await _locationService.getLocation(); } } else { bool serviceRequestGranted = await _locationService.requestService(); if(serviceRequestGranted) { initPlatformState(); } } } on PlatformException catch (e) { print(e); if (e.code == 'PERMISSION_DENIED') { error = e.message!; } else if (e.code == 'SERVICE_STATUS_ERROR') { error = e.message!; } } } |
After that now we need to check location updates by using the below code
enableLocationSubscription() async { _locationSubscription = _locationService.onLocationChanged.listen((LocationData result) async { if(mounted){ setState(() { _currentLocation = result; }); } }); } |
Step 6: Now run application and you can see the location updates of the device. To track location in background mode we need to enable enableBackgroundMode({bool enable}) API service and add required permissions in manifest file
|
Complete code
import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:location/location.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; void main() { runApp(new MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Google Maps Demo', home: MapSample(), ); } } class MapSample extends StatefulWidget { @override State createState() => MapSampleState(); } class MapSampleState extends State { Completer _controller = Completer(); static final CameraPosition _kGooglePlex = CameraPosition( target: LatLng(17.385044, 78.486671), zoom: 18, ); Map markers = {}; late MarkerId markerId1; late Marker marker1; Location _locationService = new Location(); LocationData? initialLocation; LocationData? _currentLocation; late MapType maptype; bool updateStarted=false; late StreamSubscription _locationSubscription; PermissionStatus? _permissionGranted ; String error=""; @override void initState() { super.initState(); maptype=MapType.normal; markerId1=MarkerId("Current"); marker1=Marker( markerId: markerId1, position: LatLng(17.385044, 78.486671), icon: BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueGreen), infoWindow: InfoWindow( title: "Hytech City",onTap: (){ },snippet: "Snipet Hitech City" )); markers[markerId1]=marker1; } @override Widget build(BuildContext context) { return new Scaffold( appBar: AppBar(elevation:0, backgroundColor: Colors.teal,title: Text("Flutter Track Location", style: TextStyle(color: Colors.white),), actions: [ PopupMenuButton( itemBuilder: (builder){ return >[ PopupMenuItem( value: 0, child: Text('Hybrid'), ), PopupMenuItem( value: 1, child: Text('Normal'), ), PopupMenuItem( value: 2, child: Text('Satellite'), ),PopupMenuItem( value: 3, child: Text('Terrain'), ), ]; },onSelected: (value){ switch(value) { case 0: setState(() { maptype=MapType.hybrid; }); break; case 1: setState(() { maptype=MapType.normal; }); break; case 2: setState(() { maptype=MapType.satellite; }); break; case 3: setState(() { maptype=MapType.terrain; }); break; } },) ], ), body: Padding( padding: const EdgeInsets.only(top:8.0), child: Stack( children: [ GoogleMap( mapType: maptype, initialCameraPosition: _kGooglePlex, onMapCreated: (GoogleMapController controller) { _controller.complete(controller); }, markers: Set.of(markers.values), ), Align(alignment: Alignment.topCenter, child: Container( color: Colors.white60, child: new Text(_currentLocation != null ? 'Current location: \nlat: ${_currentLocation!.latitude}\n long: ${_currentLocation!.longitude} ' : 'Error: $error\n', textAlign: TextAlign.center,style: TextStyle(color: Colors.pink,fontSize: 20),), )) ], ), ), floatingActionButton: FloatingActionButton.extended( backgroundColor: !updateStarted?Colors.blue:Colors.red, onPressed: !updateStarted?_startTrack:_stopTrack, label: Text(!updateStarted?'Start Track!':'Stop Track'), icon: Icon(Icons.directions_boat,), ), ); } initPlatformState() async { await _locationService.changeSettings(accuracy: LocationAccuracy.high, interval: 1000); LocationData? locationData; try { bool serviceEnabled = await _locationService.serviceEnabled(); if (serviceEnabled) { PermissionStatus p; _permissionGranted = (await _locationService.requestPermission()); if (_permissionGranted!.index==0) { locationData = await _locationService.getLocation(); enableLocationSubscription(); } } else { bool serviceRequestGranted = await _locationService.requestService(); if(serviceRequestGranted) { initPlatformState(); } } } on PlatformException catch (e) { print(e); if (e.code == 'PERMISSION_DENIED') { error = e.message!; } else if (e.code == 'SERVICE_STATUS_ERROR') { error = e.message!; } //locationData = null; } setState(() { initialLocation = locationData!; }); } enableLocationSubscription() async { _locationSubscription = _locationService.onLocationChanged.listen((LocationData result) async { if(mounted){ setState(() { _currentLocation = result; markers.clear(); MarkerId markerId1=MarkerId("Current"); Marker marker1=Marker( markerId: markerId1, position: LatLng(17.385044, 78.486671), icon: BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueRed), ); markers[markerId1]=marker1; animateCamera(marker1); }); } }); } slowRefresh() async { if(_locationSubscription!=null) _locationSubscription.cancel(); await _locationService.changeSettings(accuracy: LocationAccuracy.balanced, interval: 10000); enableLocationSubscription(); } Future<void> _startTrack() async { initPlatformState(); setState(() { updateStarted=true; }); } Future<void> _stopTrack() async { if(_locationSubscription!=null) _locationSubscription.cancel(); setState(() { updateStarted=false; }); } animateCamera(marker1) async { final GoogleMapController controller = await _controller.future; controller.animateCamera(CameraUpdate.newCameraPosition(marker1)); } } |
Conclusion: In this tutorial we learned how to load Google Maps and fetch current location and track current location of the user device and update it on Google Maps with Marker.
More Flutter Google Maps Examples
Show Multiple Markers on Maps Flutter
How to fetch current location Address
How do i share current location address with flutter
Article Contributed By :
|
|
|
|
3863 Views |