How to automatically update gps coordinate values in flutter using geolocator package?

840 Views Asked by At

I want to create an app page in flutter where the gps values of longitude and latitude are updated continously as i move around in the streets, like how it happens in google maps.

I imported the following libraries in the code.

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:geolocator/geolocator.dart';
import 'dart:async';

Next i created my basic skeleton of LocationPage Widget

class LocationPage extends ConsumerWidget {
  String longitude = "";
  String latitude = "";

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return MaterialApp(
        home: Scaffold(
            body: Center(
                child: Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Text("Longitude:: $longitude"),
        Text("Latitude:: $latitude"),
      ],
    ))));
  }
}

I added a constructor to the LocationPage and put the following code

LocationPage() {
    final LocationSettings locationSettings = LocationSettings(
      accuracy: LocationAccuracy.high,
      distanceFilter: 100,
    );
    StreamSubscription<Position> positionStream =
        Geolocator.getPositionStream(locationSettings: locationSettings)
            .listen((Position? position) {
      longitude = position!.longitude.toString();
      latitude = position.latitude.toString();
    });
  }

I know I am doing something wrong, but am unable to understand how to make this work!! I gave many other attempts in using riverpod to make this happen and failed terribly. I know that Geolocator.getPositionStream returns a Stream<Position>, I don't know what to do next!

Here is the link to geolocator package https://pub.dev/packages/geolocator

1

There are 1 best solutions below

5
On

You should move the StreamSubscription code out of the constructor and into the initState method of the LocationPage widget. This will ensure that the stream is only set up when the widget is first created and not every time the widget is rebuilt.

You also need to set the state of the longitude and latitude variable when you receive the new location in the stream, so that the widget can rebuild with the new values.

Here is an example of how you can implement this:

class LocationPage extends StatefulWidget {
  @override
  _LocationPageState createState() => _LocationPageState();
}

class _LocationPageState extends State<LocationPage> {
  String longitude = "";
  String latitude = "";
  StreamSubscription<Position> _positionStream;

  @override
  void initState() {
    super.initState();
    final LocationSettings locationSettings = LocationSettings(
      accuracy: LocationAccuracy.high,
      distanceFilter: 100,
    );
    _positionStream = Geolocator.getPositionStream(locationSettings: locationSettings)
            .listen((Position? position) {
      setState(() {
        longitude = position!.longitude.toString();
        latitude = position.latitude.toString();
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(
            body: Center(
                child: Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Text("Longitude:: $longitude"),
        Text("Latitude:: $latitude"),
      ],
    ))));
  }

  @override
  void dispose() {
    _positionStream.cancel();
    super.dispose();
  }
}

This should work for you. Let me know if this works!