Im just building a google maps with flutter 2.8.1 and google_maps_flutter: ^2.1.4, everytime i save/hot reload it give me this error not always but quite often and im afraid this will cause big problem in future.
note: i cannot change the flutter and maps version because i have to use this version
throw PlatformException(code: errorCode, message: errorMessage as String?, details: errorDetails, stacktrace: errorStacktrace);
this is the full error code
#override
dynamic decodeEnvelope(ByteData envelope) {
// First byte is zero in success case, and non-zero otherwise.
if (envelope.lengthInBytes == 0)
throw const FormatException('Expected envelope, got nothing');
final ReadBuffer buffer = ReadBuffer(envelope);
if (buffer.getUint8() == 0)
return messageCodec.readValue(buffer);
final Object? errorCode = messageCodec.readValue(buffer);
final Object? errorMessage = messageCodec.readValue(buffer);
final Object? errorDetails = messageCodec.readValue(buffer);
final String? errorStacktrace = (buffer.hasRemaining) ? messageCodec.readValue(buffer) as String? : null;
if (errorCode is String && (errorMessage == null || errorMessage is String) && !buffer.hasRemaining)
throw PlatformException(code: errorCode, message: errorMessage as String?, details: errorDetails, stacktrace: errorStacktrace);
else
throw const FormatException('Invalid envelope');
}
this is my full code
class MapScreen extends StatefulWidget {
const MapScreen({Key? key}) : super(key: key);
#override
State<MapScreen> createState() => _MapScreenState();
}
class _MapScreenState extends State<MapScreen> {
late GoogleMapController mapController;
final LatLng _center = const LatLng(45.521563, -122.677433);
static const CameraPosition _initialCameraPosition = CameraPosition(
target: LatLng(37.42796133580664, -122.085749655962),
zoom: 14.4746,
);
#override
void dispose() {
// TODO: implement dispose
super.dispose();
mapController.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: _buildAppBarr(),
floatingActionButton: _buildCustomFab(),
body: GoogleMap(
mapType: MapType.normal,
myLocationButtonEnabled: false,
zoomControlsEnabled: false,
initialCameraPosition: _initialCameraPosition,
onMapCreated: (controller) => mapController = controller,
),
);
}
}
Related
I'm working with the google map widget, when I render the map for the first time with static markers it displays all the markers, but when I get the data from API and try to add new markers to the map, it won't display them.
below the code that i'm using :
class Map extends StatefulWidget {
final Position initialPosition;
final List<Marker> allSitesMarkers;
final List<Site> placesSite;
final List<String> mapMarkersCategories;
const Map(this.initialPosition, this.allSitesMarkers, this.placesSite,
this.mapMarkersCategories,
{Key key})
: super(key: key);
#override
State<StatefulWidget> createState() => MapState();
}
class MapState extends State<Map> {
Completer<GoogleMapController> _controller = Completer();
String currentCategoryFilter;
bool filtred = false;
Set<Marker> _markers = Set();
List<Marker> markersToShow;
#override
void initState() {
super.initState();
refreshMarkers();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: (widget.placesSite.isNotEmpty)
? Stack(
children: [
GoogleMap(
initialCameraPosition: const CameraPosition(
target: LatLng(36.798, 10.1717), zoom: 15),
mapType: MapType.normal,
myLocationEnabled: true,
markers: _markers,
onMapCreated: (GoogleMapController controller) {
controller.setMapStyle(
'[ //... ]');
_controller.complete(controller);
},
),
_chips()
],
)
: const NoListMap(),
);
}
Widget _chips() {
//..
}
filterSites(String category) {
setState(() {
_markers.clear();
filtred = true;
markersToShow = widget.allSitesMarkers
.where((element) => element.infoWindow.title == category)
.toList();
});
refreshMarkers();
}
refreshMarkers() {
if (filtred) {
setState(() {
_markers.clear();
_markers.addAll(markersToShow);
});
} else {
setState(() {
_markers.clear();
_markers.addAll(widget.allSitesMarkers);
});
}
}
}
I'm using:
Flutter 2.10.2
Dart 2.16.1
google_maps_flutter : 2.0.9
Your _markers is a Set, and in setState you use clear and addAll to empty it and to add new items to the set. But the value of _markers does not change when you do so, therefore it will not trigger a rebuild.
This happens because _markers holds a reference to the Set (like lists, objects etc.).
You need to assign a new value to _markers to trigger a rebuild, for example:
setState(() {
_markers = markersToShow.toSet();
});
This will actually change the reference kept in _markers.
I'm trying to have a page in my app display a user's location on a google map, which works in debug mode, but when I run it in release mode it simply loads indefinitely. The strange thing is that if I click on a different page on my app and go back to the map page it will immediately show. Does anyone know what could be going on here?
I also get the following error: [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: MissingPluginException(No implementation found for method camera#animate on channel plugins.flutter.io/google_maps_0)
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:mapapp/provider/location_provider.dart';
import 'package:provider/provider.dart';
class Map extends StatefulWidget {
const Map({Key? key}) : super(key: key);
#override
_State createState() => _State();
}
class _State extends State<Map> {
#override
void initState() {
super.initState();
Provider.of<LocationProvider>(context, listen: false).initalization();
}
//Sets map style once app is resumed to reload the map
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state == AppLifecycleState.resumed) {
dynamic controller;
controller.setMapStyle("[]");
}
}
#override
Widget build(BuildContext context) {
return Scaffold(body: googleMapUI());
}
Widget googleMapUI() {
return Consumer<LocationProvider>(builder: (
consumerContext,
model,
child,
) {
while (model.locationPosition != null) {
return Column(
children: [
Expanded(
child: GoogleMap(
mapType: MapType.normal,
padding: const EdgeInsets.only(top: 40.0),
initialCameraPosition:
CameraPosition(target: model.locationPosition!, zoom: 18),
myLocationEnabled: true,
myLocationButtonEnabled: true,
onMapCreated: (GoogleMapController controller) async {
Provider.of<LocationProvider>(context, listen: false);
},
),
)
],
);
}
return const Center(
child: CircularProgressIndicator(),
);
});
}
}
i start with this code but all what i get white screen
how i can use google map to get current location or choose location.I am using GoogleMap package in flutter to get the required current location.
import 'dart:async'; import 'package:flutter/material.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart';
void main() => runApp(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(37.42796133580664, -122.085749655962), zoom: 14.4746, );
static final CameraPosition _kLake = CameraPosition( bearing:
192.8334901395799, target: LatLng(37.43296265331129,
-122.08832357078792), tilt: 59.440717697143555, zoom:
19.151926040649414);
#override Widget build(BuildContext context) { return new Scaffold(
body: GoogleMap(
mapType: MapType.hybrid, initialCameraPosition: _kGooglePlex,
onMapCreated: (GoogleMapController controller) {
_controller.complete(controller);
},
),
floatingActionButton:
FloatingActionButton.extended(
onPressed: _goToTheLake,
label:
Text('To the lake!'),
icon: Icon(Icons.directions_boat), ),
);
}
Future _goToTheLake() async {
final GoogleMapController controller = await _controller.future;
controller.animateCamera(CameraUpdate.newCameraPosition(_kLake));
}
}
If you're using Url properly(no spelling/parameter mistakes) with API key and there's no error from the server which happens a lot due to restrictions. Then there are other steps you need to, ask Location permission on app loading using https://pub.dev/packages/permission_handler package like this.
Code can be something like this.
Create an app_persmission_provider file.
class AppPermissionProvider with ChangeNotifier {
PermissionStatus _locationStatus = PermissionStatus.denied;
LatLng? _locationCenter;
final location_package.Location _location =
location_package.Location();
location_package.LocationData? _locationData;
// Getter
get locationStatus => _locationStatus;
get locationCenter => _locationCenter;
get location => _location;
void getLocationStatus() async {
final status = await Permission.location.request();
_locationStatus = status;
notifyListeners();
print(_locationStatus);
}
void getLocation() async {
_locationData = await _location.getLocation();
_locationCenter = LatLng(
_locationData!.latitude as double, _locationData!.longitude as double);
notifyListeners();
}
}
Then declare the provider on the root maybe, and In my case, I'm initializing some functions onInit. By doing so, android will ask for permission for location when your page loads.
#override
void initState() {
super.initState();
appPermission = Provider.of<AppPermissionProvider>(context, listen: false);
appPermission.getLocationStatus();
appPermission.getLocation();
}
And then using consumer.
SafeArea(
child: Consumer<AppPermissionProvider>(
builder: (context, appPermissionProvider, _) => appPermission
.locationCenter ==
null
? const Center(child: CircularProgressIndicator())
:
GoogleMap( myLocationButtonEnabled:
appPermissionProvider.locationStatus ==
PermissionStatus.granted
? true
: false,
myLocationEnabled: true,
initialCameraPosition: CameraPosition(
target: appPermission.locationCenter,
zoom: 14,
),
onMapCreated: onMapCreated,
mapType: MapType.normal,
compassEnabled: true,
),
),
)
Here, I am checking if permission is granted, also I am only enabling myLocationButton if location permission is granted.
You can use google_maps_flutter package ,
A short example how you can use it.
For more clearity you can visit
Here or you can use geolocator.
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
LatLng _initialcameraposition = LatLng(20.5937, 78.9629);
GoogleMapController _controller;
Location _location = Location();
void _onMapCreated(GoogleMapController _cntlr)
{
_controller = _cntlr;
_location.onLocationChanged.listen((l) {
_controller.animateCamera(
CameraUpdate.newCameraPosition(
CameraPosition(target: LatLng(l.latitude, l.longitude),zoom: 15),
),
);
});
}
I am displaying my current location on google maps using this library: package:location/location.dart. Pub Dev Link
The problem is whenever I open the app in release mode it crashes and shows:
LateInitializationError: Field 'currentLatLng' has not been
initialized
It does not crash in debug mode on an Android Device.
It does, however, crash on iOS (release and debug mode).
I am not sure what I am doing wrong. Here's my widget and attempt:
class TestGoogle extends StatefulWidget {
const TestGoogle({Key? key}) : super(key: key);
#override
_TestGoogleState createState() => _TestGoogleState();
}
class _TestGoogleState extends State<TestGoogle> {
late LatLng currentLatLng;
late GoogleMapController mapController;
Location location = new Location();
var latitude;
var longitude;
late LocationData _locationData;
get() async {
_locationData = await location.getLocation();
latitude = _locationData.latitude;
longitude = _locationData.longitude;
setState(() {
currentLatLng = new LatLng(latitude, longitude);
});
}
#override
initState() {
super.initState();
get();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: GoogleMap(
myLocationEnabled: true,
onCameraMove: (CameraPosition cameraPosition) {
print(cameraPosition.zoom);
},
initialCameraPosition:
CameraPosition(target: currentLatLng, zoom: 15.0),
),
);
}
}
The below codes should fix your problem. Your problem reason, try use variable before initializing.
class TestGoogle extends StatelessWidget {
TestGoogle({Key? key}) : super(key: key);
late GoogleMapController mapController;
Location location = Location();
Future<LatLng> get() async {
final _locationData = await location.getLocation();
return LatLng(_locationData.latitude, _locationData.longitude);
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: FutureBuilder<LatLng>(
future: get(),
builder: (context, snapshot) {
if (snapshot.hasData) {
final locationModel = snapshot.data!;
final latitude = locationModel.latitude;
final longitude = locationModel.longitude;
return GoogleMap(
myLocationEnabled: true,
onCameraMove: (CameraPosition cameraPosition) {
print(cameraPosition.zoom);
},
initialCameraPosition: CameraPosition(target: locationModel, zoom: 15.0),
);
}
return const CircularProgressIndicator();
},
),
);
}
}
I Fixed this by
class TestGoogle extends StatefulWidget {
const TestGoogle({Key? key}) : super(key: key);
#override
_TestGoogleState createState() => _TestGoogleState();
}
class _TestGoogleState extends State<TestGoogle> {
LatLng? currentLatLng;
late GoogleMapController mapController;
Location location = new Location();
var latitude;
var longitude;
late LocationData _locationData;
get() async {
_locationData = await location.getLocation();
latitude = _locationData.latitude;
longitude = _locationData.longitude;
setState(() {
currentLatLng = new LatLng(latitude, longitude);
});
}
#override
initState() {
super.initState();
get();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: currentLatLng == null
? Center(child: PlatformCircularProgressIndicator())
: GoogleMap(
myLocationEnabled: true,
onCameraMove: (CameraPosition cameraPosition) {
print(cameraPosition.zoom);
},
initialCameraPosition:
CameraPosition(target: currentLatLng, zoom: 15.0),
),
);
}
}
I am newbie in flutter, I am trying to set my location as the center point of the map that the app draw on the screen
I am using statefulwidget as the root of my app and add this code :
class MyMap extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return MyMapState();
}
}
class MyMapState extends State<MyMap> {
GoogleMapController googleMapController;
LocationData currentLocation;
LocationData distinationLocation;
Location location;
#override
void initState() {
location = Location();
setInitSourceAndDestination();
super.initState();
}
setInitSourceAndDestination() async {
currentLocation = await location.getLocation();
}
#override
Widget build(BuildContext context) {
CameraPosition initialCameraPosition = CameraPosition(
target: LatLng(currentLocation.latitude, currentLocation.longitude),);
return GoogleMap(
initialCameraPosition: initialCameraPosition,
onMapCreated: (GoogleMapController controller) => googleMapController = controller,
mapType: MapType.normal,
tiltGesturesEnabled: false,
compassEnabled: true,
myLocationEnabled: true,
);
}
}
But there are a problem I can not solve:
the map is drawn in the screen before currentLocation is set
I tried setState and the problem has not been solved.
How can I make the app draw the map after setInitSourceAndDestination method finish excuting?
What make me confused is that the code at this form the build method will be excuted before setInitSourceAndDestination method finished, but if I add setState and change the currentLocation value inside it to rebuild the screen I noticed that setState executed before build function but it still dont show my location
Add a condition to check the state. If the state is null, then draw a loading indicator. If not null, draw the maps
it can be look like this :
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:location/location.dart';
class MapScreen extends StatefulWidget {
#override
_MapScreenState createState() => _MapScreenState();
}
class _MapScreenState extends State<MapScreen> {
double lat;
double long;
LatLng _pickedLoc;
Future _getLocation() async {
LocationData location = await Location().getLocation();
setState(() {
lat = location.latitude;
long = location.longitude;
});
}
_selectLocation(LatLng location) {
_pickedLoc = location;
}
#override
void initState() {
super.initState();
_getLocation();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: lat == null || long == null
? Center(
child: CircularProgressIndicator(),
)
: GoogleMap(
initialCameraPosition: CameraPosition(
zoom: 16,
target: LatLng(lat, long),
),
onTap: _selectLocation,
onCameraMove: (object) => {debugPrint(object.target.toString())},
markers: {
Marker(
markerId: MarkerId("m1"),
position: _pickedLoc,
)
},
),
);
}
}