I am new to flutter and I am trying to build an app which shows the current location by using Google Maps API. There is no error in this code but this error is coming after running: Exception has occurred. LateError (LateInitializationError: Field 'currentLocation' has not been initialized.)
Can someone please provide an example code of what's needed to solve for this error?
import 'package:geolocator/geolocator.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:location/location.dart';
void main() => runApp(const MyApp());
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
late GoogleMapController mapController;
final Set<Marker> markers = {};
// static const LatLng showLocation =
late LatLng currentLocation;
// late Widget googleMap;
@override
void initState() {
super.initState();
getCurrentPosition();
}
void getCurrentPosition() async {
late Location location = Location();
location.getLocation().then(
(location) {
currentLocation = location as LatLng; //as Future<APILocation>
},
);
}
void _onMapCreated(GoogleMapController controller) {
mapController = controller;
}
Future<Position> _determinePosition() async {
bool serviceEnabled;
LocationPermission permission;
// Test if location services are enabled.
serviceEnabled = await Geolocator.isLocationServiceEnabled();
if (!serviceEnabled) {
// Location services are not enabled don't continue
// accessing the position and request users of the
// App to enable the location services.
return Future.error('Location services are disabled.');
}
permission = await Geolocator.checkPermission();
if (permission == LocationPermission.denied) {
permission = await Geolocator.requestPermission();
if (permission == LocationPermission.denied) {
// Permissions are denied, next time you could try
// requesting permissions again (this is also where
// Android's shouldShowRequestPermissionRationale
// returned true. According to Android guidelines
// your App should show an explanatory UI now.
return Future.error('Location permissions are denied');
}
}
if (permission == LocationPermission.deniedForever) {
// Permissions are denied forever, handle appropriately.
return Future.error(
'Location permissions are permanently denied, we cannot request permissions.');
}
// When we reach here, permissions are granted and we can
// continue accessing the position of the device.
return await Geolocator.getCurrentPosition();
}
@override
Widget build(BuildContext context) {
return FutureBuilder<Position>(
future: _determinePosition(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return const CircularProgressIndicator();
}
return GoogleMap(
initialCameraPosition:
CameraPosition(target: currentLocation, zoom: 15.0),
markers: getmarkers(),
mapType: MapType.normal,
onMapCreated: (controller) {
setState(() {
mapController = controller;
});
},
);
});
}
Set<Marker> getmarkers() {
setState(() {
markers.add(
Marker(
markerId: MarkerId(currentLocation.toString()),
position: currentLocation,
infoWindow: const InfoWindow(
title: 'Current Location',
snippet: 'blabla',
),
icon: BitmapDescriptor.defaultMarker,
),
);
});
return markers;
}
}
CodePudding user response:
Change your getCurrentPosition
like
void getCurrentPosition() async {
late Location location = Location();
location.getLocation().then(
(location) {
currentLocation =
LatLng(location.latitude ?? 0, location.longitude ?? 0); //this
},
);
}
There are others issue like
- not using MaterialApp on root
- using SetState on Build Time.
- FutureBuilder on done returning CircularProgressBar
- not sure what else I've changed, compare with your snippet
import 'package:geolocator/geolocator.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:location/location.dart';
import 'package:flutter/material.dart';
void main() => runApp(MaterialApp(home: const MyApp()));
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
late GoogleMapController mapController;
final Set<Marker> markers = {};
// static const LatLng showLocation =
// LatLng(41.01358468198064, 28.86560382071653);
late LatLng currentLocation;
// late Widget googleMap;
@override
void initState() {
super.initState();
getCurrentPosition();
}
void getCurrentPosition() async {
late Location location = Location();
location.getLocation().then(
(location) {
currentLocation =
LatLng(location.latitude ?? 0, location.longitude ?? 0);
},
);
}
void _onMapCreated(GoogleMapController controller) {
mapController = controller;
}
Future<Position> _determinePosition() async {
bool serviceEnabled;
LocationPermission permission;
// Test if location services are enabled.
serviceEnabled = await Geolocator.isLocationServiceEnabled();
if (!serviceEnabled) {
// Location services are not enabled don't continue
// accessing the position and request users of the
// App to enable the location services.
return Future.error('Location services are disabled.');
}
permission = await Geolocator.checkPermission();
if (permission == LocationPermission.denied) {
permission = await Geolocator.requestPermission();
if (permission == LocationPermission.denied) {
// Permissions are denied, next time you could try
// requesting permissions again (this is also where
// Android's shouldShowRequestPermissionRationale
// returned true. According to Android guidelines
// your App should show an explanatory UI now.
return Future.error('Location permissions are denied');
}
}
if (permission == LocationPermission.deniedForever) {
// Permissions are denied forever, handle appropriately.
return Future.error(
'Location permissions are permanently denied, we cannot request permissions.');
}
// When we reach here, permissions are granted and we can
// continue accessing the position of the device.
return await Geolocator.getCurrentPosition();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: FutureBuilder<Position>(
future: _determinePosition(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const CircularProgressIndicator();
}
if (snapshot.hasError) return Text("Error");
if (snapshot.hasData) {
return GoogleMap(
initialCameraPosition:
CameraPosition(target: currentLocation, zoom: 15.0),
markers: getmarkers(),
mapType: MapType.normal,
onMapCreated: (controller) {
mapController = controller;
},
);
}
return CircularProgressIndicator();
}),
);
}
Set<Marker> getmarkers() {
markers.add(
Marker(
markerId: MarkerId(currentLocation.toString()),
position: currentLocation,
infoWindow: const InfoWindow(
title: 'Current Location',
snippet: 'blabla',
),
icon: BitmapDescriptor.defaultMarker,
),
);
return markers;
}
}
CodePudding user response:
LateInitializationError
occurs when you try to access a late variable before it's initialized.
in your case, your code is trying to access currentLocation
before it's assigned a value.
Now I don't know how your code works but could the reason be that you are showing a loading screen when you're loading in your build method?
Your code in build()
:
if (snapshot.connectionState == ConnectionState.done) {
return const CircularProgressIndicator();
}
CodePudding user response:
I had modified your code try using this and compare with yours I had checked not getting error
import 'package:geolocator/geolocator.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:location/location.dart';
import 'package:flutter/material.dart';
void main() => runApp(const MaterialApp(home: MyApp()));
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState( );
}
class _MyAppState extends State<MyApp> {
late GoogleMapController mapController;
final Set<Marker> markers = {};
// static const LatLng showLocation =
// LatLng(41.01358468198064, 28.86560382071653);
late LatLng currentLocation;
// late Widget googleMap;
// _MyAppState({this.currentLocation});
@override
void initState() {
super.initState();
// getCurrentPosition();
}
// void getCurrentPosition() async {
// late Location location = Location();
// await location.getLocation().then(
// (location) {
// currentLocation = location; //as Future<APILocation>
// },
// );
// }
void _onMapCreated(GoogleMapController controller) {
mapController = controller;
}
Future<Position> _determinePosition() async {
bool serviceEnabled;
LocationPermission permission;
// Test if location services are enabled.
serviceEnabled = await Geolocator.isLocationServiceEnabled();
if (!serviceEnabled) {
// Location services are not enabled don't continue
// accessing the position and request users of the
// App to enable the location services.
return Future.error('Location services are disabled.');
}
permission = await Geolocator.checkPermission();
if (permission == LocationPermission.denied) {
permission = await Geolocator.requestPermission();
if (permission == LocationPermission.denied) {
// Permissions are denied, next time you could try
// requesting permissions again (this is also where
// Android's shouldShowRequestPermissionRationale
// returned true. According to Android guidelines
// your App should show an explanatory UI now.
return Future.error('Location permissions are denied');
}
}
if (permission == LocationPermission.deniedForever) {
// Permissions are denied forever, handle appropriately.
return Future.error(
'Location permissions are permanently denied, we cannot request permissions.');
}
// When we reach here, permissions are granted and we can
// continue accessing the position of the device.
return await Geolocator.getCurrentPosition();
}
@override
Widget build(BuildContext context) {
return FutureBuilder<Position>(
future: _determinePosition(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const CircularProgressIndicator();
}
if (snapshot.connectionState == ConnectionState.done) {
currentLocation= LatLng(snapshot.data!.latitude,snapshot.data!.longitude);
print('ffr ${snapshot.data!.latitude}');
print('ffr ${snapshot.data!.longitude}');
}
return GoogleMap(
initialCameraPosition:
CameraPosition(target: LatLng(snapshot.data!.latitude,snapshot.data!.longitude), zoom: 15.0),
markers: getmarkers(),
mapType: MapType.normal,
onMapCreated: (controller) {
mapController = controller;
},
);
});
}
Set<Marker> getmarkers() {
markers.add(
Marker(
markerId: MarkerId(currentLocation.longitude.toString()),
position: LatLng(currentLocation.latitude,currentLocation.longitude),
infoWindow: const InfoWindow(
title: 'Current Location',
snippet: 'blabla',
),
icon: BitmapDescriptor.defaultMarker,
),
);
return markers;
}
}