Newer
Older
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_datetime_picker/flutter_datetime_picker.dart';
import 'dart:async';
import 'package:geolocator/geolocator.dart';
const AddEvent({Key? key}) : super(key: key);
@override
State<AddEvent> createState() => _AddEventPageState();
}
class _AddEventPageState extends State<AddEvent> {
late String long = "";
late String lat = "";
late String alt = "";
late StreamSubscription<Position> streamHandler;
Future startGNSS() async {
debugPrint("Check Location Permission");
bool serviceStatus = false;
bool hasPermission = false;
serviceStatus = await Geolocator.isLocationServiceEnabled();
if(serviceStatus){
LocationPermission permission = await Geolocator.checkPermission();
if (permission == LocationPermission.denied) {
permission = await Geolocator.requestPermission();
if (permission == LocationPermission.denied) {
}else if(permission == LocationPermission.deniedForever){
debugPrint('Location permissions are permanently denied');
if(hasPermission){
debugPrint('Location permissions granted');
if(mounted){
setState(() {
//refresh the UI
});}
debugPrint('Starting location stream');
streamHandler = Geolocator.getPositionStream(
locationSettings: const LocationSettings(
accuracy: LocationAccuracy.high,
distanceFilter: 0,
)).listen((Position position) {
debugPrint('Get Location: Lat:' + position.latitude.toString() +
' Long:' + position.longitude.toString() +
' Alt:' + position.altitude.toString());
long = position.longitude.toString();
lat = position.latitude.toString();
alt = position.altitude.toString();
accuracy = position.accuracy;
if (syncGNSSData == true) {
if(mounted){
setState(() {
//refresh UI on update
});}
}
});
debugPrint("GPS Service is not enabled, turn on GPS location");
setState(() {
//refresh the UI
});}
@override
void dispose() {
try {
streamHandler.cancel();
debugPrint('Cancel location stream');
}catch(e){
debugPrint('Canceling location stream failed');
}
super.dispose();
//TODO: only if initialized positionStream.cancel();
}
final EventStoreInstance eventsStore = EventStoreInstance();
eventsStore.currentEvent.status = "PENDING";
eventsStore.events.add(
eventsStore.currentEvent.id,
eventsStore.currentEvent.urn,
eventsStore.currentEvent.label,
eventsStore.currentEvent.type,
eventsStore.currentEvent.description,
eventsStore.currentEvent.status,
eventsStore.currentEvent.startDate,
eventsStore.currentEvent.endDate,
eventsStore.currentEvent.latitude,
eventsStore.currentEvent.longitude,
eventsStore.currentEvent.elevation
//TODO: add field validators for freetext fields. Check allowed characters in sensor.awi.de
@override
Widget build(BuildContext context) {
/* Get singletons to access relevant data here.*/
final EventStoreInstance eventsStore = EventStoreInstance();
final ConfigurationStoreInstance configuration = ConfigurationStoreInstance();
// Update current event coordinates from GNSS stream
eventsStore.currentEvent.latitude = lat;
eventsStore.currentEvent.longitude = long;
eventsStore.currentEvent.elevation = alt;
var date = DateTime.now().toUtc();
eventsStore.currentEvent.startDate = '$date';
eventsStore.currentEvent.endDate = '$date';
if(accuracy == 0.0){
gnssStatusText = "No-Fix";
else{
gnssStatusText = "Precision: "+ accuracy.toStringAsFixed(2) +"m";
}
gnssStatusText = "GNSS Disabled"; // Just display existing event coordinates
if (configuration.initialized == true) {
return Scaffold(
appBar: AppBar(title: const Text("Add Event")),
body:
Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
TextFormField(
initialValue: eventsStore.currentEvent.label,
autovalidateMode: AutovalidateMode.onUserInteraction,
decoration: const InputDecoration(
labelText: 'Label',
errorText: 'Only: a-z , A-Z , _ , 0-9 , ,(Comma) , ( , ) , + , - , . , :'
),
onChanged: (value) {
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
eventsStore.currentEvent.label = value;
},
validator: (value) {
if (!RegExp(r'^[a-z A-Z . \- 0-9 , ( ) + - _ :]+$').hasMatch(
value!)) {
return "Only: a-z , A-Z , _ , 0-9 , ,(Comma) , ( , ) , + , - , . , :";
} else {
eventsStore.currentEvent.label = value;
return ''; // Entered Text is valid
}
},
),
DropdownButtonFormField(
value: eventsStore.currentEvent.type,
isExpanded: true,
decoration: const InputDecoration(
labelText: 'Event Type',
),
items:
configuration.eventTypes.map((EventType event) {
return DropdownMenuItem(
value: event.name,
child: Text(event.name),
);
}).toList(),
onChanged: (value) {
eventsStore.currentEvent.type = value.toString();
}
),
DropdownButtonFormField(
value: eventsStore.currentEvent.urn,
isExpanded: true,
decoration: const InputDecoration(
labelText: 'URN',
),
items:
configuration.devices.map((Device device) {
return DropdownMenuItem(
value: device.urn,
child: Text(device.urn),
);
}).toList(),
onChanged: (value) {
eventsStore.currentEvent.urn = value.toString();
eventsStore.currentEvent.id =
configuration.getDeviceIdFromUrn(value.toString());
}
),
TextFormField(
initialValue: eventsStore.currentEvent.description,
decoration: const InputDecoration(
labelText: 'Description'
),
onChanged: (value) {
eventsStore.currentEvent.description = value;
},
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Flexible(child:
TextFormField(
controller: TextEditingController(
text: eventsStore.currentEvent.startDate),
readOnly: true,
decoration: const InputDecoration(
labelText: 'Timestamp',
//helperText: '', //Adds some space below field
border: OutlineInputBorder(),
),
onTap: () {
DatePicker.showDateTimePicker(context,
showTitleActions: true,
onConfirm: (date) {
//Only one field for start and end date.
eventsStore.currentEvent.startDate = '$date';
eventsStore.currentEvent.endDate = '$date';
debugPrint('Date set to : $date');
setState(() {});
},
currentTime: DateTime.now().toUtc(),
locale: LocaleType.en);
},
),
),
ElevatedButton(
onPressed: () {
var date = DateTime.now().toUtc();
eventsStore.currentEvent.startDate = '$date';
eventsStore.currentEvent.endDate = '$date';
debugPrint('Date set to : ' +
eventsStore.currentEvent.endDate.toString());
setState(() {});
},
child: Text('Now'),
]
),
TextFormField(
readOnly: false,
enabled: !syncGNSSData,
controller: TextEditingController(
text: eventsStore.currentEvent.latitude.toString()),
decoration: const InputDecoration(
labelText: 'Latitude',
border: OutlineInputBorder(),
onChanged: (value) {
eventsStore.currentEvent.latitude = value;
}
),
TextFormField(
readOnly: false,
enabled: !syncGNSSData,
controller: TextEditingController(
text: eventsStore.currentEvent.longitude.toString()),
decoration: const InputDecoration(
labelText: 'Longitude',
border: OutlineInputBorder(),
onChanged: (value) {
eventsStore.currentEvent.longitude = value;
}
),
TextFormField(
readOnly: false,
enabled: !syncGNSSData,
controller: TextEditingController(
text: eventsStore.currentEvent.elevation.toString()),
decoration: const InputDecoration(
labelText: 'Elevation',
border: OutlineInputBorder(),
onChanged: (value) {
eventsStore.currentEvent.elevation = value;
}
),
]),
bottomNavigationBar: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text(gnssStatusText),
const SizedBox(width: 10),
Switch(
value: syncGNSSData,
onChanged: (value) {
syncGNSSData = value;
debugPrint('Switched to:' + syncGNSSData.toString());
setState(() {
//refresh the UI
});
},
const SizedBox(width: 50),
FloatingActionButton(
heroTag: null,
onPressed: () {
_storeCurrentEvent();
HapticFeedback.vibrate();
},
tooltip: 'Add Event',
child: const Icon(Icons.check),
const SizedBox(width: 20),
],
),
);
}else {
return Scaffold(
appBar: AppBar(title: const Text("Add Event")),
body: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.end,
children: const <Widget>[
Text(
' Visit Configuration first.',
style: TextStyle(fontSize: 20)
),
],
),
);
}