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,
);
}