Flutter: Why app doesn't start listen for stream only if I run with hot restart?

Viewed 644

I'm new to flutter and trying to build application to get user's speed and listen to it using streams with Geolocator plugin but, the thing is when the user accepts accessing to their location, the app doesn't start listening for his location but if I press hot restart it work perfect. I've tried using async function in initState and used setState function but nothing works .. please could anyone help me with this I've been struggling for days

This's my piece of code:

import 'package:my_testing/Components/constants.dart';
import 'package:my_testing/Screens/setting_screen.dart';
import 'package:my_testing/Services/weather.dart';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:my_testing/Services/user_location.dart';
import 'package:provider/provider.dart';
import 'package:syncfusion_flutter_gauges/gauges.dart';
import 'package:flutter_glow/flutter_glow.dart';
import 'package:geolocator/geolocator.dart';
import 'package:my_testing/Services/road_map.dart';
import 'dart:async';

///1- this class is for the main screen:
class SpeedScreen extends StatefulWidget {

  @override
  _SpeedScreenState createState() => _SpeedScreenState ();
}

class _SpeedScreenState extends State<SpeedScreen>{

  StreamController<double> speedController = StreamController<double>.broadcast();
  Stream<double> get speedStream => speedController.stream;
  StreamSubscription<Position>? streamSubscription1;
  double randomNumber = 240.0; 
  String? speedUnit = 'MPH';
  double? speedInMPH;


  void detectFastSpeedWithAlert(double? userSpeed) {
    double fastSpeed = 50.0;

    while (userSpeed! >= fastSpeed && SettingDrawer.isSwitched == true) {
      SettingDrawer.playAlertSound();
      break;
    }
    SettingDrawer.stopAlertSound();
  }

  void getSpeedInMPH() { ///HERE IS MY PROBLEM (p-1) //TODO:
    speedInMPH= 0.0;
   // Geolocator.requestPermission().then((value) {
      //if (value== LocationPermission.always || value == LocationPermission.whileInUse){
        Geolocator.getPositionStream(
            intervalDuration: Duration(milliseconds: 2000), 
            desiredAccuracy: LocationAccuracy.bestForNavigation).listen((position) { 
          speedController.add(speedInMPH!);
          setState(() {
            speedInMPH = position.speed * (2.23693629); 
            print('the Speed Stream are $speedInMPH'); 
          });
          detectFastSpeedWithAlert(speedInMPH);
            });
  }

  @override
  void initState() { ///ALSO HERE IS MY PROBLEM (p-2) //TODO:
    super.initState();
    speedInMPH=0.0;
    getSpeedInMPH();
  
  }

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

  ///this function for passing the lat and long to RoadMap
  void passingLatLongData() async {

    UserLocation loc= UserLocation();
    await loc.getUserLocation();
    var roadLat= loc.lat;
    var roadLong= loc.long;

    Navigator.push(context,MaterialPageRoute(
        builder: (context){
          return RoadMap(
            userLat: roadLat, 
            userLong: roadLong,
          );
        }),
    );
  }

  @override
  Widget build(BuildContext context) {
    return StreamProvider<double>(
      create: (_)=> speedStream, //in new version of StreamProvider, use create instead of builder
      initialData: 0.0,
      child: SafeArea(
        child: Scaffold(
          appBar: AppBar(
            elevation: 0.0,
            centerTitle: true, 
            title: Text('  MY TESTING APP',
              style: TextStyle(
                fontSize: 15.0,
                color: Color(0xFF868DB4),
              ),
            ),
            leading: Builder(
              builder: (BuildContext context) {
                return IconButton(
                  icon: Icon(
                    FontAwesomeIcons.cogs,
                    size: 30.0,
                    color: kIconColor,
                  ),
                  onPressed: () {
                    Scaffold.of(context).openDrawer();
                  },
                );
              },
            ),
          ),
          body: Container(
            margin: EdgeInsets.symmetric(vertical: 20.0, horizontal: 20.0),
            child: Column(
                mainAxisAlignment: MainAxisAlignment.start,
                children: [
                  Expanded(
                    flex: 3,
                    child: GestureDetector(
                      onTap: (){
                        print('Gauge has been pressed'); 
                      },
                      child: Stack(children: [
                        Positioned(
                          height: 320.0,
                          left: 0,
                          right: 0,
                          bottom: -15.0,
                          child: SfRadialGauge(
                            enableLoadingAnimation: true,
                            animationDuration: 2000,
                            axes: <RadialAxis>[
                              RadialAxis(minimum: 0,maximum: 240,
                                showLabels: false,
                                showTicks: true, 
                                radiusFactor: 0.70,
                                axisLineStyle: AxisLineStyle(
                                  cornerStyle: CornerStyle.bothCurve,
                                  color: Color(0x363F467E),
                                  thickness: 13.5,
                                ),
                                majorTickStyle: MajorTickStyle(
                                  length: 1,
                                  thickness: 0.0,
                                  color: kTextColor,
                                ),
                                annotations: <GaugeAnnotation>[
                                  GaugeAnnotation(
                                    widget: GlowText('${speedInMPH!.toInt()}',
                                      glowColor: kGaugeColor,
                                      blurRadius: 15.0,
                                      offset: Offset(0.0,0.0),
                                      style: TextStyle(
                                        fontSize: 28.0,
                                        fontWeight: FontWeight.w900,
                                        color: Colors.tealAccent.shade100,
                                      ),
                                    ),
                                    positionFactor: 0.9,
                                    angle: 102,
                                  ),
                                  GaugeAnnotation(
                                    widget: Text(' $speedUnit', 
                                      style: TextStyle(
                                        fontSize: 15.0,
                                        color: kTextColor,
                                      ),
                                    ),
                                    positionFactor: 0.98,
                                    angle: 70.0,
                                  ),
                                ],
                                pointers: [
                                  RangePointer(
                                    animationType: AnimationType.elasticOut,
                                    value: randomNumber,
                                    animationDuration: 2000,
                                    enableAnimation: true,
                                    width: 13.5,
                                    cornerStyle: CornerStyle.bothCurve,
                                    color: kGaugeColor,
                                  ),
                                  NeedlePointer(
                                    animationType: AnimationType.elasticOut,
                                    value: speedInMPH!.roundToDouble(),
                                    animationDuration: 2000,
                                    enableAnimation: true,
                                    needleColor: kGaugeColor,
                                    needleStartWidth: 0.6,
                                    needleEndWidth: 8.0,
                                    knobStyle: KnobStyle(
                                      knobRadius: 0.07,
                                      color: kGaugeColor,
                                    ),
                                  ),
                              
                                ],
                              ),
                            ],
                          ),),
                      ]),
                    ),
                  ),
                  Expanded(
                    flex: 2,
                    child: Row(
                        children: [
                          Expanded(
                            child: Weather(),
                          ),
                          SizedBox(
                            width: 5.0,
                          ),
                          Expanded(
                            child: myContainerButton( 
                              containerIcon: FontAwesomeIcons.locationArrow,
                              containerOnPressed: () {
                                passingLatLongData();
                              },
                            ),
                          ),
                        ]),
                  ),
                  SizedBox(
                    height: 5.0,
                  ),
                  Expanded(
                    child: myContainerButton(
                      containerIcon: Icons.error_outline, 
                      containerText: 'Information',
                    ),
                  ),
                ]
            ),
          ),
          drawer: SettingDrawer(),
        ),
      ),
    );
  }
}

Widget myContainerButton({@required IconData? containerIcon,String? containerText, Function()? containerOnPressed}){

  return Container(
    child: TextButton(
      onPressed: containerOnPressed, 
      child: Column(
          children: [
            Padding(
              padding: EdgeInsets.symmetric(horizontal: 9.0, vertical: 7.0),
              child: Row(
                  children: [
                    Icon(
                      containerIcon,
                      color: kIconColor,
                      size: 30.0,
                      //or Color(0xFF7179B9),
                    ),
                    Text('  $containerText',
                      style: TextStyle(
                        color: kTextColor,
                        fontSize: 12.0,
                      
                      ),
                    ),
                  ]
              ),
            ),
          ]
      ),
    ),
    decoration: kBoxDecoration,
  );
}
1 Answers

The problem is initState() is called only once, when widget is inserted into the widget-tree as shown in official documentation. and since you are hot reloading initState() will not called.

update:-

you can actually use didUpdateWidget() for hot reload to work

@override
  void didUpdateWidget(oldWidget) {
    super.didUpdateWidget(oldWidget);
    //your code for stream
  }
Related