Reputation: 455
I'm trying to get the user current location with the geolocator plugin, and I'm using the provider package to handle the state. But I"m getting "initial location is null" error message. I'm using the flutter_maps package, not google maps.
I tried to look for a solution using the provider package, but i found none.
Here's my code:
main.dart:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import './maps_module/map_states.dart';
import 'home_page.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
return runApp(
MultiProvider(
providers: [
ChangeNotifierProvider.value(value: AppState())
],
child: MyApp(),
)
);
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: HomePage(),
);
}
}
home_page.dart:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:latlong/latlong.dart';
import 'package:geolocator/geolocator.dart';
import './maps_module/map_states.dart';
import './maps_module/maps_screen.dart';
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final appState = Provider.of<AppState>(context);
return Scaffold(
body: appState.initialPosition == null?
Center(
child: CircularProgressIndicator(),
)
:MapScreen(),
);
}
}
map_screen.dart:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:latlong/latlong.dart';
import 'map_states.dart';
class MapScreen extends StatefulWidget {
@override
_MapScreenState createState() => new _MapScreenState();
}
class _MapScreenState extends State<MapScreen> {
@override
Widget build(BuildContext context) {
final appState = Provider.of<AppState>(context);
return SafeArea(
child: Scaffold(
// appBar: AppBar(),
body: FlutterMap(
mapController: appState.mapController,
options: MapOptions(
center: LatLng(appState.initialPosition.latitude, appState.initialPosition.longitude),
minZoom: 10.0
),
layers: [
TileLayerOptions(
urlTemplate: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
subdomains: ['a','b','c']
),
MarkerLayerOptions(
markers: [
Marker(
width: 80.0,
height: 80.0,
point: appState.initialPosition,
builder: (context) =>
Container(
child: IconButton(
icon: Icon(Icons.location_on),
color: Colors.redAccent,
iconSize: 45.0,
onPressed: (){print("hey");}
),
)
)
]
)
],
),
)
);
}
}
map_states:
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:geolocator/geolocator.dart';
import 'package:latlong/latlong.dart';
class AppState with ChangeNotifier {
bool locationServiceActive = true;
MapController _mapController;
MapController get mapController => _mapController;
static var _initialPosition;
var _lastPosition = _initialPosition;
LatLng get initialPosition => _initialPosition;
LatLng get lastPosition => _lastPosition;
AppState(){
checkGPS();
_getUserLocation();
}
checkGPS() async{
bool conn = await Geolocator().isLocationServiceEnabled();
if(conn == false){
locationServiceActive = false;
} else {
locationServiceActive = true;
}
notifyListeners();
}
void _getUserLocation() async{
Position position = await Geolocator().getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
print("/////////////////////////////////////////////////////////////////////////////////position");
print(position);
_initialPosition = LatLng(position.latitude, position.longitude);
notifyListeners();
}
}
Upvotes: 4
Views: 2339
Reputation: 2664
Your problem is that your are need to await
checkgps()
and _getUserLocation()
in your class constructor the problem is your can't run asynchronous functions from the constructor of a class so you would need to do something like this. First of all you need to remove void from _getUserLocation()
or make it Future<void>
then add.
//Add to your class
initalization() async {
await _checkGPS();
await getUserLocation();
}
//This in a widget will prove it works
@override
void initState() {
AppState().initalization();
print('Location ${AppState().initialPosition}');
super.initState();
}
Upvotes: 2