besprechung
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
import 'package:fforte/screens/sharedMethods/send_file.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'l10n/app_localizations.dart';
|
import 'l10n/app_localizations.dart';
|
||||||
import 'screens/addCam/add_cam_main.dart';
|
import 'screens/addCam/add_cam_main.dart';
|
||||||
@@ -101,7 +102,7 @@ class HomePage extends StatelessWidget {
|
|||||||
minimumSize: const Size(250, 40),
|
minimumSize: const Size(250, 40),
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
// _sendFile();
|
SendFile.sendFile();
|
||||||
},
|
},
|
||||||
child: Text(AppLocalizations.of(context)!.sendfile),
|
child: Text(AppLocalizations.of(context)!.sendfile),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -16,16 +16,19 @@ import 'l10n/l10n.dart';
|
|||||||
void main() async {
|
void main() async {
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
|
// Set default values (Propably there is a better way to do this)
|
||||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
|
// isFirstLaunch decides whether the intro screen is shown or not
|
||||||
bool isFirstLaunch = prefs.getBool('isFirstLaunch') ?? true;
|
bool isFirstLaunch = prefs.getBool('isFirstLaunch') ?? true;
|
||||||
if (prefs.getString("kTage1")?.isEmpty ?? true) await prefs.setString('kTage1', "28");
|
if (prefs.getString("kTage1")?.isEmpty ?? true) await prefs.setString('kTage1', "28");
|
||||||
if (prefs.getString("kTage2")?.isEmpty ?? true) await prefs.setString('kTage2', "48");
|
if (prefs.getString("kTage2")?.isEmpty ?? true) await prefs.setString('kTage2', "48");
|
||||||
if (prefs.getString("fotofallenApiAddress")?.isEmpty ?? true) await prefs.setString('fotofallenApiAddress', 'http://192.168.1.170/www.dbb-wolf.de/data/app24.php');
|
// if (prefs.getString("fotofallenApiAddress")?.isEmpty ?? true) await prefs.setString('fotofallenApiAddress', 'http://192.168.1.170/www.dbb-wolf.de/data/app24.php');
|
||||||
if (prefs.getString("exkursionenApiAddress")?.isEmpty ?? true) await prefs.setString('exkursionenApiAddress', 'http://192.168.1.170/www.dbb-wolf.de/data/api_exkursion.php');
|
// if (prefs.getString("exkursionenApiAddress")?.isEmpty ?? true) await prefs.setString('exkursionenApiAddress', 'http://192.168.1.170/www.dbb-wolf.de/data/api_exkursion.php');
|
||||||
runApp(MyApp(isFirstLaunch: isFirstLaunch));
|
runApp(MyApp(isFirstLaunch: isFirstLaunch));
|
||||||
}
|
}
|
||||||
|
|
||||||
class MyApp extends StatelessWidget {
|
class MyApp extends StatelessWidget {
|
||||||
|
|
||||||
final bool isFirstLaunch;
|
final bool isFirstLaunch;
|
||||||
const MyApp({super.key, required this.isFirstLaunch});
|
const MyApp({super.key, required this.isFirstLaunch});
|
||||||
|
|
||||||
@@ -37,7 +40,9 @@ class MyApp extends StatelessWidget {
|
|||||||
darkTheme:
|
darkTheme:
|
||||||
FlexThemeData.dark(scheme: FlexScheme.greenM3, useMaterial3: true),
|
FlexThemeData.dark(scheme: FlexScheme.greenM3, useMaterial3: true),
|
||||||
themeMode: ThemeMode.system,
|
themeMode: ThemeMode.system,
|
||||||
|
// here the isFirstLaunch comes into play
|
||||||
initialRoute: isFirstLaunch ? '/introScreen' : '/home',
|
initialRoute: isFirstLaunch ? '/introScreen' : '/home',
|
||||||
|
// Localization settings
|
||||||
supportedLocales: L10n.all,
|
supportedLocales: L10n.all,
|
||||||
localizationsDelegates: const [
|
localizationsDelegates: const [
|
||||||
AppLocalizations.delegate,
|
AppLocalizations.delegate,
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import 'package:fforte/l10n/app_localizations.dart';
|
|||||||
import 'package:geolocator/geolocator.dart';
|
import 'package:geolocator/geolocator.dart';
|
||||||
import 'package:latlong2/latlong.dart';
|
import 'package:latlong2/latlong.dart';
|
||||||
import 'package:animations/animations.dart';
|
import 'package:animations/animations.dart';
|
||||||
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
import 'widgets/abbau_dat.dart';
|
import 'widgets/abbau_dat.dart';
|
||||||
import 'widgets/karte.dart';
|
import 'widgets/karte.dart';
|
||||||
@@ -164,11 +165,15 @@ class _AddCamMainState extends State<AddCamMain> {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// If it is not a template set default values
|
// If it is not a template set default values
|
||||||
rmap["Datum"]!["controller"]!.text = DateTime.now().toString();
|
rmap["Datum"]!["controller"]!.text = DateTime.now().toString().split(" ").first;
|
||||||
rmap["Status"]!["controller"]!.text = "aktiv";
|
rmap["Status"]!["controller"]!.text = "aktiv";
|
||||||
rmap["FotoFilm"]!["controller"]!.text = "Foto";
|
rmap["FotoFilm"]!["controller"]!.text = "Foto";
|
||||||
rmap["MEZ"]!["controller"]!.text = "Sommerzeit";
|
rmap["MEZ"]!["controller"]!.text = "Sommerzeit";
|
||||||
rmap["Platzung"]!["controller"]!.text = "";
|
rmap["Platzung"]!["controller"]!.text = "";
|
||||||
|
SharedPreferences.getInstance().then((SharedPreferences prefs) {
|
||||||
|
rmap["KTage1"]!["controller"]!.text = prefs.getString("kTage1");
|
||||||
|
rmap["KTage2"]!["controller"]!.text = prefs.getString("kTage2");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set initial default position
|
// Set initial default position
|
||||||
@@ -201,7 +206,6 @@ class _AddCamMainState extends State<AddCamMain> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return currentPosition;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -353,7 +357,7 @@ class _AddCamMainState extends State<AddCamMain> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mounted) return;
|
if (!context.mounted) return;
|
||||||
|
|
||||||
final result = await Navigator.of(context).push<LatLng>(
|
final result = await Navigator.of(context).push<LatLng>(
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
@@ -480,7 +484,7 @@ class _AddCamMainState extends State<AddCamMain> {
|
|||||||
initDatum: DateTime.parse(rmap["Datum"]!["controller"]!.text),
|
initDatum: DateTime.parse(rmap["Datum"]!["controller"]!.text),
|
||||||
onDateChanged: (value) {
|
onDateChanged: (value) {
|
||||||
setState(() {
|
setState(() {
|
||||||
rmap["Datum"]!["controller"]!.text = value.toString();
|
rmap["Datum"]!["controller"]!.text = value.toString().split(" ").first;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
name: AppLocalizations.of(context)!.pickDate,
|
name: AppLocalizations.of(context)!.pickDate,
|
||||||
@@ -705,8 +709,8 @@ class _AddCamMainState extends State<AddCamMain> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool empty = CheckRequired.checkRequired(rmap);
|
bool empty = CheckRequired.checkRequired(rmap);
|
||||||
// TODO for debugging always false
|
// for debugging always false
|
||||||
empty = false;
|
// empty = false;
|
||||||
|
|
||||||
if (empty == true) {
|
if (empty == true) {
|
||||||
AddEntriesDialogHelper.showTemplateDialog(
|
AddEntriesDialogHelper.showTemplateDialog(
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ class _ExcursionMainState extends State<ExcursionMain> {
|
|||||||
rmap["BLand"]!["controller"]!.text = prefs.getString('bLand') ?? "";
|
rmap["BLand"]!["controller"]!.text = prefs.getString('bLand') ?? "";
|
||||||
});
|
});
|
||||||
|
|
||||||
rmap["Datum"]!["controller"]!.text = DateTime.now().toString();
|
rmap["Datum"]!["controller"]!.text = DateTime.now().toString().split(" ").first;
|
||||||
rmap["Sent"]!["controller"]!.text = "0";
|
rmap["Sent"]!["controller"]!.text = "0";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,7 +205,7 @@ class _ExcursionMainState extends State<ExcursionMain> {
|
|||||||
Datum(
|
Datum(
|
||||||
initDatum: DateTime.now(),
|
initDatum: DateTime.now(),
|
||||||
onDateChanged: (date) {
|
onDateChanged: (date) {
|
||||||
rmap["Datum"]!["controller"]!.text = date.toString();
|
rmap["Datum"]!["controller"]!.text = date.toString().split(" ").first;
|
||||||
},
|
},
|
||||||
name: AppLocalizations.of(context)!.date,
|
name: AppLocalizations.of(context)!.date,
|
||||||
),
|
),
|
||||||
@@ -357,7 +357,7 @@ class _ExcursionMainState extends State<ExcursionMain> {
|
|||||||
// Check for always permission before starting tracking
|
// Check for always permission before starting tracking
|
||||||
LocationPermission permission = await Geolocator.checkPermission();
|
LocationPermission permission = await Geolocator.checkPermission();
|
||||||
if (permission != LocationPermission.always) {
|
if (permission != LocationPermission.always) {
|
||||||
if (mounted) {
|
if (context.mounted) {
|
||||||
bool? shouldContinue = await showDialog<bool>(
|
bool? shouldContinue = await showDialog<bool>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => AlertDialog(
|
builder: (context) => AlertDialog(
|
||||||
@@ -371,7 +371,7 @@ class _ExcursionMainState extends State<ExcursionMain> {
|
|||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
await Geolocator.openAppSettings();
|
await Geolocator.openAppSettings();
|
||||||
Navigator.of(context).pop(true);
|
if (context.mounted) Navigator.of(context).pop(true);
|
||||||
},
|
},
|
||||||
child: Text(AppLocalizations.of(context)!.openSettings),
|
child: Text(AppLocalizations.of(context)!.openSettings),
|
||||||
),
|
),
|
||||||
@@ -387,7 +387,7 @@ class _ExcursionMainState extends State<ExcursionMain> {
|
|||||||
// Try checking the permission multiple times
|
// Try checking the permission multiple times
|
||||||
for (int i = 0; i < 5; i++) {
|
for (int i = 0; i < 5; i++) {
|
||||||
await Future.delayed(const Duration(seconds: 1));
|
await Future.delayed(const Duration(seconds: 1));
|
||||||
if (!mounted) return;
|
if (!context.mounted) return;
|
||||||
|
|
||||||
permission = await Geolocator.checkPermission();
|
permission = await Geolocator.checkPermission();
|
||||||
if (permission == LocationPermission.always) {
|
if (permission == LocationPermission.always) {
|
||||||
@@ -396,7 +396,7 @@ class _ExcursionMainState extends State<ExcursionMain> {
|
|||||||
|
|
||||||
// If this is the last attempt and we still don't have permission
|
// If this is the last attempt and we still don't have permission
|
||||||
if (i == 4 && permission != LocationPermission.always) {
|
if (i == 4 && permission != LocationPermission.always) {
|
||||||
if (mounted) {
|
if (context.mounted) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(
|
SnackBar(
|
||||||
content: Text(AppLocalizations.of(context)!.permissionNotGranted),
|
content: Text(AppLocalizations.of(context)!.permissionNotGranted),
|
||||||
@@ -410,6 +410,7 @@ class _ExcursionMainState extends State<ExcursionMain> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (context.mounted) {
|
||||||
await Navigator.push(context, MaterialPageRoute(
|
await Navigator.push(context, MaterialPageRoute(
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
return Tracking(
|
return Tracking(
|
||||||
@@ -418,6 +419,7 @@ class _ExcursionMainState extends State<ExcursionMain> {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
|
}
|
||||||
setState(() {});
|
setState(() {});
|
||||||
},
|
},
|
||||||
child: Text(AppLocalizations.of(context)!.trackingAnAusschalten),
|
child: Text(AppLocalizations.of(context)!.trackingAnAusschalten),
|
||||||
|
|||||||
@@ -26,15 +26,15 @@ class _HinweiseState extends State<Hinweise> {
|
|||||||
void initState() {
|
void initState() {
|
||||||
sonstigesController.addListener(updateController);
|
sonstigesController.addListener(updateController);
|
||||||
|
|
||||||
liegestelleChecked = widget.hinweise.text.contains("liegestelle") ? true : false;
|
liegestelleChecked = widget.hinweise.text.contains("Liegestelle") ? true : false;
|
||||||
kadaverChecked = widget.hinweise.text.contains("kadaver") ? true : false;
|
kadaverChecked = widget.hinweise.text.contains("Wildtierkadaver") ? true : false;
|
||||||
sichtungChecked = widget.hinweise.text.contains("sichtung") ? true : false;
|
sichtungChecked = widget.hinweise.text.contains("Sichtung") ? true : false;
|
||||||
heulenChecked = widget.hinweise.text.contains("heulen") ? true : false;
|
heulenChecked = widget.hinweise.text.contains("Heulen") ? true : false;
|
||||||
|
|
||||||
bool firstRun = true;
|
bool firstRun = true;
|
||||||
|
|
||||||
for (String val in widget.hinweise.text.split(",")) {
|
for (String val in widget.hinweise.text.split(",")) {
|
||||||
if (val != "liegestelle" && val != "kadaver" && val != "sichtung" && val != "heulen" && val != "") {
|
if (val != "Liegestelle" && val != "Wildtierkadaver" && val != "Sichtung" && val != "Heulen" && val != "") {
|
||||||
sonstigesChecked = true;
|
sonstigesChecked = true;
|
||||||
if (!firstRun) sonstigesController.text += ",";
|
if (!firstRun) sonstigesController.text += ",";
|
||||||
sonstigesController.text += val;
|
sonstigesController.text += val;
|
||||||
@@ -53,10 +53,10 @@ class _HinweiseState extends State<Hinweise> {
|
|||||||
|
|
||||||
void updateController() {
|
void updateController() {
|
||||||
Map<String, bool> props = {
|
Map<String, bool> props = {
|
||||||
"liegestelle": liegestelleChecked,
|
"Liegestelle": liegestelleChecked,
|
||||||
"kadaver": kadaverChecked,
|
"Wildtierkadaver": kadaverChecked,
|
||||||
"sichtung": sichtungChecked,
|
"Sichtung": sichtungChecked,
|
||||||
"heulen": heulenChecked,
|
"Heulen": heulenChecked,
|
||||||
"sonstiges": sonstigesChecked
|
"sonstiges": sonstigesChecked
|
||||||
};
|
};
|
||||||
bool firstRun = true;
|
bool firstRun = true;
|
||||||
|
|||||||
@@ -215,7 +215,7 @@ class _TrackingState extends State<Tracking> {
|
|||||||
currentPosition!.longitude,
|
currentPosition!.longitude,
|
||||||
),
|
),
|
||||||
radius: currentPosition!.accuracy,
|
radius: currentPosition!.accuracy,
|
||||||
color: Colors.blue.withOpacity(0.2),
|
color: Colors.blue.withAlpha(2),
|
||||||
borderColor: Colors.blue,
|
borderColor: Colors.blue,
|
||||||
borderStrokeWidth: 2,
|
borderStrokeWidth: 2,
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -72,12 +72,12 @@ class AddEntriesDialogHelper {
|
|||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
setState(() => isLoading = true);
|
setState(() => isLoading = true);
|
||||||
int errorCode = await HttpRequest.httpRequest(
|
int errorCode = await HttpRequestService.httpRequest(
|
||||||
saveDataMap: saveData,
|
saveDataMap: saveData,
|
||||||
);
|
);
|
||||||
setState(() => isLoading = false);
|
setState(() => isLoading = false);
|
||||||
|
|
||||||
if (errorCode == 201 && context.mounted) {
|
if (errorCode == 200 && context.mounted) {
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
// saveData(true);
|
// saveData(true);
|
||||||
SaveMainEntryMethod.saveEntry(
|
SaveMainEntryMethod.saveEntry(
|
||||||
@@ -160,12 +160,12 @@ class AddEntriesDialogHelper {
|
|||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
setState(() => isLoading = true);
|
setState(() => isLoading = true);
|
||||||
int errorCode = await HttpRequest.httpRequest(
|
int errorCode = await HttpRequestService.httpRequest(
|
||||||
saveDataMap: saveData,
|
saveDataMap: saveData,
|
||||||
);
|
);
|
||||||
setState(() => isLoading = false);
|
setState(() => isLoading = false);
|
||||||
|
|
||||||
if (errorCode != 201 || !context.mounted) {
|
if (errorCode != 200 || !context.mounted) {
|
||||||
SaveMainEntryMethod.saveEntry(
|
SaveMainEntryMethod.saveEntry(
|
||||||
entryData: saveData,
|
entryData: saveData,
|
||||||
isTemplate: isTemplate,
|
isTemplate: isTemplate,
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ class _IntroScreenState extends State<IntroScreen> {
|
|||||||
TextEditingController ffApiAddress = TextEditingController();
|
TextEditingController ffApiAddress = TextEditingController();
|
||||||
TextEditingController exApiAddress = TextEditingController();
|
TextEditingController exApiAddress = TextEditingController();
|
||||||
|
|
||||||
String selectedFFApiAddress = "Test";
|
String selectedFFApiAddress = "https://data.dbb-wolf.de/app24.php";
|
||||||
String selectedEXApiAddress = "Test";
|
String selectedEXApiAddress = "https://data.dbb-wolf.de/api_exkursion.php";
|
||||||
String? selectedBLand = "Sachsen";
|
String? selectedBLand = "Sachsen";
|
||||||
|
|
||||||
Future<void> _saveData() async {
|
Future<void> _saveData() async {
|
||||||
@@ -38,8 +38,8 @@ class _IntroScreenState extends State<IntroScreen> {
|
|||||||
Future.delayed(Duration.zero, () async {
|
Future.delayed(Duration.zero, () async {
|
||||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
setState(() {
|
setState(() {
|
||||||
ffApiAddress.text = prefs.getString('fotofallenApiAddress') ?? "";
|
ffApiAddress.text = prefs.getString('fotofallenApiAddress') ?? "https://data.dbb-wolf.de/app24.php";
|
||||||
exApiAddress.text = prefs.getString('exkursionenApiAddress') ?? "";
|
exApiAddress.text = prefs.getString('exkursionenApiAddress') ?? "https://data.dbb-wolf.de/api_exkursion.php";
|
||||||
addresse1C.text = prefs.getString('addresse1') ?? "";
|
addresse1C.text = prefs.getString('addresse1') ?? "";
|
||||||
bLandC.text = prefs.getString('bLand') ?? "Sachsen";
|
bLandC.text = prefs.getString('bLand') ?? "Sachsen";
|
||||||
});
|
});
|
||||||
@@ -161,86 +161,97 @@ class _IntroScreenState extends State<IntroScreen> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
height: 25,
|
height: 35,
|
||||||
),
|
),
|
||||||
Align(
|
Align(
|
||||||
alignment: Alignment.bottomLeft,
|
alignment: Alignment.bottomLeft,
|
||||||
child: Text(AppLocalizations.of(context)!.ffApiAddress)),
|
child: Text(AppLocalizations.of(context)!.ffApiAddress)),
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
// Expanded(
|
||||||
flex: 4,
|
// flex: 4,
|
||||||
child: TextField(
|
// child: TextField(
|
||||||
decoration: InputDecoration(
|
// decoration: InputDecoration(
|
||||||
hintText:
|
// hintText:
|
||||||
AppLocalizations.of(context)!.ffApiAddress),
|
// AppLocalizations.of(context)!.ffApiAddress),
|
||||||
controller: ffApiAddress,
|
// controller: ffApiAddress,
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
Expanded(
|
Expanded(
|
||||||
flex: 1,
|
flex: 1,
|
||||||
child: PopupMenuButton(
|
child: TextField(
|
||||||
icon: const Icon(Icons.arrow_drop_down),
|
controller: ffApiAddress,
|
||||||
initialValue: selectedFFApiAddress,
|
),
|
||||||
onSelected: (value) {
|
// child: PopupMenuButton(
|
||||||
setState(() {
|
// icon: const Icon(Icons.arrow_drop_down),
|
||||||
selectedFFApiAddress = value;
|
// initialValue: selectedFFApiAddress,
|
||||||
ffApiAddress.text = value;
|
// onSelected: (value) {
|
||||||
});
|
// setState(() {
|
||||||
},
|
// selectedFFApiAddress = value;
|
||||||
itemBuilder: (context) => <PopupMenuEntry>[
|
// ffApiAddress.text = value;
|
||||||
PopupMenuItem(
|
// });
|
||||||
value:
|
// },
|
||||||
"http://192.168.1.106/www.dbb-wolf.de/data/app24.php",
|
// itemBuilder: (context) => <PopupMenuEntry>[
|
||||||
child:
|
// // PopupMenuItem(
|
||||||
Text(AppLocalizations.of(context)!.test)),
|
// // value:
|
||||||
PopupMenuItem(
|
// // "http://192.168.1.106/www.dbb-wolf.de/data/app24.php",
|
||||||
value: "...",
|
// // child:
|
||||||
child: Text(
|
// // Text(AppLocalizations.of(context)!.test)),
|
||||||
AppLocalizations.of(context)!.notest))
|
// PopupMenuItem(
|
||||||
],
|
// value: "https://data.dbb-wolf.de/app24.php",
|
||||||
))
|
// child: Text(
|
||||||
|
// AppLocalizations.of(context)!.notest))
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
//)
|
||||||
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 10,),
|
const SizedBox(
|
||||||
|
height: 10,
|
||||||
|
),
|
||||||
Align(
|
Align(
|
||||||
alignment: Alignment.bottomLeft,
|
alignment: Alignment.bottomLeft,
|
||||||
child: Text(AppLocalizations.of(context)!.exApiAddress)),
|
child: Text(AppLocalizations.of(context)!.exApiAddress)),
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
// Expanded(
|
||||||
flex: 4,
|
// flex: 4,
|
||||||
child: TextField(
|
// child: TextField(
|
||||||
decoration: InputDecoration(
|
// decoration: InputDecoration(
|
||||||
hintText:
|
// hintText:
|
||||||
AppLocalizations.of(context)!.exApiAddress),
|
// AppLocalizations.of(context)!.exApiAddress),
|
||||||
controller: exApiAddress,
|
// controller: exApiAddress,
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
Expanded(
|
Expanded(
|
||||||
flex: 1,
|
flex: 1,
|
||||||
child: PopupMenuButton(
|
child: TextField(
|
||||||
icon: const Icon(Icons.arrow_drop_down),
|
controller: exApiAddress,
|
||||||
initialValue: selectedEXApiAddress,
|
),
|
||||||
onSelected: (value) {
|
// child: PopupMenuButton(
|
||||||
setState(() {
|
// icon: const Icon(Icons.arrow_drop_down),
|
||||||
selectedEXApiAddress = value;
|
// initialValue: selectedEXApiAddress,
|
||||||
exApiAddress.text = value;
|
// onSelected: (value) {
|
||||||
});
|
// setState(() {
|
||||||
},
|
// selectedEXApiAddress = value;
|
||||||
itemBuilder: (context) => <PopupMenuEntry>[
|
// exApiAddress.text = value;
|
||||||
PopupMenuItem(
|
// });
|
||||||
value:
|
// },
|
||||||
"http://192.168.1.106/www.dbb-wolf.de/data/app24.php",
|
// itemBuilder: (context) => <PopupMenuEntry>[
|
||||||
child:
|
// // PopupMenuItem(
|
||||||
Text(AppLocalizations.of(context)!.test)),
|
// // value:
|
||||||
PopupMenuItem(
|
// // "http://192.168.1.106/www.dbb-wolf.de/data/app24.php",
|
||||||
value: "...",
|
// // child:
|
||||||
child: Text(
|
// // Text(AppLocalizations.of(context)!.test)),
|
||||||
AppLocalizations.of(context)!.notest))
|
// PopupMenuItem(
|
||||||
],
|
// value:
|
||||||
))
|
// "https://data.dbb-wolf.de/api_exkursion.php",
|
||||||
|
// child: Text(
|
||||||
|
// AppLocalizations.of(context)!.notest))
|
||||||
|
// ],
|
||||||
|
// )
|
||||||
|
)
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import 'package:dio/dio.dart';
|
|||||||
|
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
class HttpRequest {
|
class HttpRequestService {
|
||||||
static Future<int> httpRequest({Map<String, String>? saveDataMap, String? saveDataString}) async {
|
static Future<int> httpRequest({Map<String, String>? saveDataMap, String? saveDataString}) async {
|
||||||
// print(jsonEncode(place));
|
// print(jsonEncode(place));
|
||||||
|
|
||||||
@@ -25,7 +25,6 @@ class HttpRequest {
|
|||||||
response = await dio.post(prefs.getString('exkursionenApiAddress') ?? "",
|
response = await dio.post(prefs.getString('exkursionenApiAddress') ?? "",
|
||||||
data: saveDataMap == null ? saveDataString : jsonEncode(saveDataMap));
|
data: saveDataMap == null ? saveDataString : jsonEncode(saveDataMap));
|
||||||
}
|
}
|
||||||
|
|
||||||
return response.statusCode!;
|
return response.statusCode!;
|
||||||
} on DioException {
|
} on DioException {
|
||||||
return response.statusCode ?? 400;
|
return response.statusCode ?? 400;
|
||||||
|
|||||||
@@ -1,69 +1,80 @@
|
|||||||
import 'dart:convert';
|
|
||||||
|
|
||||||
import 'package:dio/dio.dart';
|
import 'package:fforte/screens/sharedMethods/http_request.dart';
|
||||||
import 'package:fforte/l10n/app_localizations.dart';
|
import 'package:file_picker/file_picker.dart';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
|
||||||
|
|
||||||
class SendFile extends StatefulWidget {
|
class SendFile {
|
||||||
const SendFile({super.key});
|
static Future<void> sendFile() async {
|
||||||
|
|
||||||
@override
|
|
||||||
State<SendFile> createState() => _SendFileState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _SendFileState extends State<SendFile> {
|
|
||||||
File? pickedFile;
|
File? pickedFile;
|
||||||
|
|
||||||
@override
|
FilePickerResult? result = await FilePicker.platform.pickFiles();
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Scaffold(
|
if (result != null) {
|
||||||
appBar: AppBar(),
|
pickedFile = File(result.files.single.path!);
|
||||||
body: Column(
|
String fileContent = await pickedFile.readAsString();
|
||||||
children: [
|
await HttpRequestService.httpRequest(saveDataString: fileContent);
|
||||||
ElevatedButton(
|
}
|
||||||
onPressed: () async {
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// class SendFile extends StatefulWidget {
|
||||||
|
// const SendFile({super.key});
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// State<SendFile> createState() => _SendFileState();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// class _SendFileState extends State<SendFile> {
|
||||||
|
// File? pickedFile;
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// Widget build(BuildContext context) {
|
||||||
|
// return Scaffold(
|
||||||
|
// appBar: AppBar(),
|
||||||
|
// body: Column(
|
||||||
|
// children: [
|
||||||
|
// ElevatedButton(
|
||||||
|
// onPressed: () async {
|
||||||
// FilePickerResult? result =
|
// FilePickerResult? result =
|
||||||
// await FilePicker.platform.pickFiles();
|
// await FilePicker.platform.pickFiles();
|
||||||
|
//
|
||||||
// if (result != null) {
|
// if (result != null) {
|
||||||
// pickedFile = File(result.files.single.path!);
|
// pickedFile = File(result.files.single.path!);
|
||||||
// } else {
|
// } else {
|
||||||
// pickedFile = File("");
|
// pickedFile = File("");
|
||||||
// }
|
// }
|
||||||
},
|
// },
|
||||||
child: Text(AppLocalizations.of(context)!.pickfile)),
|
// child: Text(AppLocalizations.of(context)!.pickfile)),
|
||||||
Text(pickedFile.toString()),
|
// Text(pickedFile.toString()),
|
||||||
ElevatedButton(
|
// ElevatedButton(
|
||||||
onPressed: () async {
|
// onPressed: () async {
|
||||||
final dio = Dio();
|
// final dio = Dio();
|
||||||
final SharedPreferences prefs = await SharedPreferences.getInstance();
|
// final SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
String? fileContent = await pickedFile?.readAsString();
|
// String? fileContent = await pickedFile?.readAsString();
|
||||||
|
//
|
||||||
dio.options.responseType = ResponseType.plain;
|
// dio.options.responseType = ResponseType.plain;
|
||||||
Response response = Response(
|
// Response response = Response(
|
||||||
requestOptions: RequestOptions(path: ''), statusCode: 400);
|
// requestOptions: RequestOptions(path: ''), statusCode: 400);
|
||||||
|
//
|
||||||
try {
|
// try {
|
||||||
response = await dio.post(prefs.getString('apiAddress') ?? "",
|
// response = await dio.post(prefs.getString('apiAddress') ?? "",
|
||||||
data: jsonEncode(fileContent));
|
// data: jsonEncode(fileContent));
|
||||||
} on DioException catch (e) {
|
// } on DioException catch (e) {
|
||||||
if (e.response?.statusCode == 500) {
|
// if (e.response?.statusCode == 500) {
|
||||||
/* print('-------------------------');
|
// /* print('-------------------------');
|
||||||
print('code 500'); */
|
// print('code 500'); */
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
if (response.statusCode == 201) {
|
// if (response.statusCode == 201) {
|
||||||
// print(response.statusCode);
|
// // print(response.statusCode);
|
||||||
} else {
|
// } else {
|
||||||
//print(response.statusCode);
|
// //print(response.statusCode);
|
||||||
}
|
// }
|
||||||
},
|
// },
|
||||||
child: Text(AppLocalizations.of(context)!.sendtoserver))
|
// child: Text(AppLocalizations.of(context)!.sendtoserver))
|
||||||
],
|
// ],
|
||||||
),
|
// ),
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|||||||
@@ -185,7 +185,7 @@ class _ViewEntriesState extends State<ViewEntries> {
|
|||||||
mainEntries[index]["Datum"])),
|
mainEntries[index]["Datum"])),
|
||||||
),
|
),
|
||||||
trailing: Checkbox(
|
trailing: Checkbox(
|
||||||
value: mainEntries[index]['Sent'] == 0
|
value: mainEntries[index]['Sent'] == "0" || mainEntries[index]["Sent"] == ""
|
||||||
? false
|
? false
|
||||||
: true,
|
: true,
|
||||||
onChanged: null,
|
onChanged: null,
|
||||||
|
|||||||
@@ -8,7 +8,13 @@ import 'package:geolocator/geolocator.dart';
|
|||||||
import 'package:latlong2/latlong.dart';
|
import 'package:latlong2/latlong.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
|
/// Service, with the Singleton design pattern, that runs the geolocator service that tracks the position of the device.
|
||||||
|
/// This is needed for excursions
|
||||||
|
///
|
||||||
|
/// Start the tracking service via [startTracking]
|
||||||
|
/// Manage the position stream via [pauseTracking], [stopTracking] and [resumeTracking]
|
||||||
class TrackingService {
|
class TrackingService {
|
||||||
|
// Singleton stuff
|
||||||
static TrackingService? _instance;
|
static TrackingService? _instance;
|
||||||
|
|
||||||
factory TrackingService() {
|
factory TrackingService() {
|
||||||
@@ -18,6 +24,7 @@ class TrackingService {
|
|||||||
|
|
||||||
TrackingService._internal();
|
TrackingService._internal();
|
||||||
|
|
||||||
|
/// Resets all values, making it possible to start tracking again.
|
||||||
static void resetInstance() {
|
static void resetInstance() {
|
||||||
if (_instance != null) {
|
if (_instance != null) {
|
||||||
_instance!.dispose();
|
_instance!.dispose();
|
||||||
@@ -25,41 +32,48 @@ class TrackingService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Variables
|
||||||
|
// - Stores the tracked coordinates
|
||||||
List<LatLng> pathList = [];
|
List<LatLng> pathList = [];
|
||||||
|
// - Stores all gotten accuracies
|
||||||
List<double> accuracyList = [];
|
List<double> accuracyList = [];
|
||||||
|
// - Stores timer so that is responsible vor the periodically tracking
|
||||||
Timer? _positionTimer;
|
Timer? _positionTimer;
|
||||||
bool isTracking = false;
|
bool isTracking = false;
|
||||||
|
// - Some more Singleton stuff (i guess. Vibecoded it because of lack of time)
|
||||||
BuildContext? _lastContext;
|
BuildContext? _lastContext;
|
||||||
final _positionController = StreamController<Position>.broadcast();
|
final _positionController = StreamController<Position>.broadcast();
|
||||||
final _statsController = StreamController<TrackingStats>.broadcast();
|
final _statsController = StreamController<TrackingStats>.broadcast();
|
||||||
|
|
||||||
|
// - Getter
|
||||||
Stream<Position> get positionStream$ => _positionController.stream;
|
Stream<Position> get positionStream$ => _positionController.stream;
|
||||||
Stream<TrackingStats> get statsStream$ => _statsController.stream;
|
Stream<TrackingStats> get statsStream$ => _statsController.stream;
|
||||||
|
|
||||||
double? currentAccuracy;
|
// - Stores the last measured accuracy so that it can be displayed in the excursions view double? currentAccuracy;
|
||||||
|
|
||||||
|
// Name says it all
|
||||||
double _calculateMedianAccuracy(List<double> accuracies) {
|
double _calculateMedianAccuracy(List<double> accuracies) {
|
||||||
|
// if one or less values for accuracy are available return that accuracy or 0
|
||||||
if (accuracies.isEmpty) return 0;
|
if (accuracies.isEmpty) return 0;
|
||||||
if (accuracies.length == 1) return accuracies.first;
|
if (accuracies.length == 1) return accuracies.first;
|
||||||
|
|
||||||
// Kopiere die Liste, um die Originaldaten nicht zu verändern
|
// Copy the list so that the original data doesnt get modified
|
||||||
var sorted = List<double>.from(accuracies)..sort();
|
var sorted = List<double>.from(accuracies)..sort();
|
||||||
|
|
||||||
|
// Calculates median (not arithmetic mean!!). That is because often the firsed tracked accuracy is about 9000m
|
||||||
if (sorted.length % 2 == 0) {
|
if (sorted.length % 2 == 0) {
|
||||||
// Bei gerader Anzahl: Durchschnitt der beiden mittleren Werte
|
|
||||||
int midIndex = sorted.length ~/ 2;
|
int midIndex = sorted.length ~/ 2;
|
||||||
return (sorted[midIndex - 1] + sorted[midIndex]) / 2;
|
return (sorted[midIndex - 1] + sorted[midIndex]) / 2;
|
||||||
} else {
|
} else {
|
||||||
// Bei ungerader Anzahl: Der mittlere Wert
|
|
||||||
return sorted[sorted.length ~/ 2];
|
return sorted[sorted.length ~/ 2];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Starts tracking
|
||||||
Future<void> startTracking(BuildContext context) async {
|
Future<void> startTracking(BuildContext context) async {
|
||||||
if (isTracking) return;
|
if (isTracking) return;
|
||||||
final LocationSettings locationSettings = LocationSettings(
|
final LocationSettings locationSettings =
|
||||||
accuracy: LocationAccuracy.high
|
LocationSettings(accuracy: LocationAccuracy.high);
|
||||||
);
|
|
||||||
|
|
||||||
_lastContext = context;
|
_lastContext = context;
|
||||||
await NotificationService().initNotification();
|
await NotificationService().initNotification();
|
||||||
@@ -74,12 +88,11 @@ class TrackingService {
|
|||||||
final intervalSeconds = prefs.getInt('trackingInterval') ?? 60;
|
final intervalSeconds = prefs.getInt('trackingInterval') ?? 60;
|
||||||
|
|
||||||
// Create a timer that triggers position updates
|
// Create a timer that triggers position updates
|
||||||
_positionTimer = Timer.periodic(Duration(seconds: intervalSeconds), (_) async {
|
_positionTimer =
|
||||||
|
Timer.periodic(Duration(seconds: intervalSeconds), (_) async {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
final Position position = await Geolocator.getCurrentPosition(
|
final Position position = await Geolocator.getCurrentPosition(
|
||||||
locationSettings: locationSettings
|
locationSettings: locationSettings);
|
||||||
);
|
|
||||||
|
|
||||||
pathList.add(LatLng(position.latitude, position.longitude));
|
pathList.add(LatLng(position.latitude, position.longitude));
|
||||||
accuracyList.add(position.accuracy);
|
accuracyList.add(position.accuracy);
|
||||||
@@ -95,8 +108,7 @@ class TrackingService {
|
|||||||
// Get initial position immediately
|
// Get initial position immediately
|
||||||
try {
|
try {
|
||||||
final Position position = await Geolocator.getCurrentPosition(
|
final Position position = await Geolocator.getCurrentPosition(
|
||||||
locationSettings: locationSettings
|
locationSettings: locationSettings);
|
||||||
);
|
|
||||||
|
|
||||||
pathList.add(LatLng(position.latitude, position.longitude));
|
pathList.add(LatLng(position.latitude, position.longitude));
|
||||||
accuracyList.add(position.accuracy);
|
accuracyList.add(position.accuracy);
|
||||||
@@ -119,8 +131,7 @@ class TrackingService {
|
|||||||
_lastStats = TrackingStats(
|
_lastStats = TrackingStats(
|
||||||
currentAccuracy: currentAccuracy ?? 0,
|
currentAccuracy: currentAccuracy ?? 0,
|
||||||
averageAccuracy: 0,
|
averageAccuracy: 0,
|
||||||
totalDistanceMeters: 0
|
totalDistanceMeters: 0);
|
||||||
);
|
|
||||||
_statsController.add(_lastStats!);
|
_statsController.add(_lastStats!);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -131,8 +142,7 @@ class TrackingService {
|
|||||||
pathList[i - 1].latitude,
|
pathList[i - 1].latitude,
|
||||||
pathList[i - 1].longitude,
|
pathList[i - 1].longitude,
|
||||||
pathList[i].latitude,
|
pathList[i].latitude,
|
||||||
pathList[i].longitude
|
pathList[i].longitude);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
double medianAccuracy = _calculateMedianAccuracy(accuracyList);
|
double medianAccuracy = _calculateMedianAccuracy(accuracyList);
|
||||||
@@ -140,8 +150,7 @@ class TrackingService {
|
|||||||
_lastStats = TrackingStats(
|
_lastStats = TrackingStats(
|
||||||
currentAccuracy: currentAccuracy ?? 0,
|
currentAccuracy: currentAccuracy ?? 0,
|
||||||
averageAccuracy: medianAccuracy,
|
averageAccuracy: medianAccuracy,
|
||||||
totalDistanceMeters: totalDistance
|
totalDistanceMeters: totalDistance);
|
||||||
);
|
|
||||||
_statsController.add(_lastStats!);
|
_statsController.add(_lastStats!);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,7 +158,8 @@ class TrackingService {
|
|||||||
_updateStats();
|
_updateStats();
|
||||||
}
|
}
|
||||||
|
|
||||||
double _calculateDistance(double lat1, double lon1, double lat2, double lon2) {
|
double _calculateDistance(
|
||||||
|
double lat1, double lon1, double lat2, double lon2) {
|
||||||
const double earthRadius = 6371000; // Erdradius in Metern
|
const double earthRadius = 6371000; // Erdradius in Metern
|
||||||
|
|
||||||
double lat1Rad = lat1 * math.pi / 180;
|
double lat1Rad = lat1 * math.pi / 180;
|
||||||
@@ -158,8 +168,10 @@ class TrackingService {
|
|||||||
double deltaLon = (lon2 - lon1) * math.pi / 180;
|
double deltaLon = (lon2 - lon1) * math.pi / 180;
|
||||||
|
|
||||||
double a = math.sin(deltaLat / 2) * math.sin(deltaLat / 2) +
|
double a = math.sin(deltaLat / 2) * math.sin(deltaLat / 2) +
|
||||||
math.cos(lat1Rad) * math.cos(lat2Rad) *
|
math.cos(lat1Rad) *
|
||||||
math.sin(deltaLon/2) * math.sin(deltaLon/2);
|
math.cos(lat2Rad) *
|
||||||
|
math.sin(deltaLon / 2) *
|
||||||
|
math.sin(deltaLon / 2);
|
||||||
|
|
||||||
double c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a));
|
double c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a));
|
||||||
return earthRadius * c;
|
return earthRadius * c;
|
||||||
|
|||||||
Reference in New Issue
Block a user