Better error handling

This commit is contained in:
Anton Tananaev 2025-06-30 23:00:08 -07:00
parent 8ba5641591
commit 36c618170e
4 changed files with 25 additions and 11 deletions

View file

@ -1,3 +1,5 @@
import 'dart:developer' as developer;
import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_crashlytics/firebase_crashlytics.dart'; import 'package:firebase_crashlytics/firebase_crashlytics.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -10,6 +12,8 @@ import 'l10n/app_localizations.dart';
import 'main_screen.dart'; import 'main_screen.dart';
import 'preferences.dart'; import 'preferences.dart';
final messengerKey = GlobalKey<ScaffoldMessengerState>();
void main() async { void main() async {
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(); await Firebase.initializeApp();
@ -37,7 +41,11 @@ class _MainAppState extends State<MainApp> {
WidgetsBinding.instance.addPostFrameCallback((_) async { WidgetsBinding.instance.addPostFrameCallback((_) async {
await rateMyApp.init(); await rateMyApp.init();
if (mounted && rateMyApp.shouldOpenDialog) { if (mounted && rateMyApp.shouldOpenDialog) {
rateMyApp.showRateDialog(context); try {
await rateMyApp.showRateDialog(context);
} catch (error) {
developer.log('Failed to show rate dialog', error: error);
}
} }
}); });
} }
@ -45,6 +53,7 @@ class _MainAppState extends State<MainApp> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MaterialApp( return MaterialApp(
scaffoldMessengerKey: messengerKey,
localizationsDelegates: AppLocalizations.localizationsDelegates, localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales, supportedLocales: AppLocalizations.supportedLocales,
theme: ThemeData( theme: ThemeData(

View file

@ -1,6 +1,6 @@
import 'dart:developer' as developer;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:traccar_client/main.dart';
import 'package:traccar_client/password_service.dart'; import 'package:traccar_client/password_service.dart';
import 'package:traccar_client/preferences.dart'; import 'package:traccar_client/preferences.dart';
import 'package:flutter_background_geolocation/flutter_background_geolocation.dart' as bg; import 'package:flutter_background_geolocation/flutter_background_geolocation.dart' as bg;
@ -97,8 +97,14 @@ class _MainScreenState extends State<MainScreen> {
onChanged: (bool value) async { onChanged: (bool value) async {
if (await PasswordService.authenticate(context) && mounted) { if (await PasswordService.authenticate(context) && mounted) {
if (value) { if (value) {
bg.BackgroundGeolocation.start(); try {
await bg.BackgroundGeolocation.start();
if (mounted) {
_checkBatteryOptimizations(context); _checkBatteryOptimizations(context);
}
} on PlatformException catch (error) {
messengerKey.currentState?.showSnackBar(SnackBar(content: Text(error.message ?? error.code)));
}
} else { } else {
bg.BackgroundGeolocation.stop(); bg.BackgroundGeolocation.stop();
} }
@ -126,8 +132,8 @@ class _MainScreenState extends State<MainScreen> {
onPressed: () async { onPressed: () async {
try { try {
await bg.BackgroundGeolocation.getCurrentPosition(samples: 1, persist: true, extras: {'manual': true}); await bg.BackgroundGeolocation.getCurrentPosition(samples: 1, persist: true, extras: {'manual': true});
} catch (error) { } on PlatformException catch (error) {
developer.log('Failed to fetch location', error: error); messengerKey.currentState?.showSnackBar(SnackBar(content: Text(error.message ?? error.code)));
} }
}, },
child: Text(AppLocalizations.of(context)!.locationButton), child: Text(AppLocalizations.of(context)!.locationButton),

View file

@ -21,7 +21,6 @@ class _QuickActionsInitializerState extends State<QuickActionsInitializer> {
void initState() { void initState() {
super.initState(); super.initState();
quickActions.initialize((shortcutType) async { quickActions.initialize((shortcutType) async {
developer.log('action $shortcutType');
switch (shortcutType) { switch (shortcutType) {
case 'start': case 'start':
bg.BackgroundGeolocation.start(); bg.BackgroundGeolocation.start();

View file

@ -3,6 +3,7 @@ import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_background_geolocation/flutter_background_geolocation.dart' as bg; import 'package:flutter_background_geolocation/flutter_background_geolocation.dart' as bg;
import 'package:traccar_client/main.dart';
import 'package:traccar_client/password_service.dart'; import 'package:traccar_client/password_service.dart';
import 'package:traccar_client/qr_code_screen.dart'; import 'package:traccar_client/qr_code_screen.dart';
import 'package:wakelock_partial_android/wakelock_partial_android.dart'; import 'package:wakelock_partial_android/wakelock_partial_android.dart';
@ -35,7 +36,6 @@ class _SettingsScreenState extends State<SettingsScreen> {
: Preferences.instance.getString(key) ?? ''; : Preferences.instance.getString(key) ?? '';
final controller = TextEditingController(text: initialValue); final controller = TextEditingController(text: initialValue);
final scaffoldManager = ScaffoldMessenger.of(context);
final errorMessage = AppLocalizations.of(context)!.invalidValue; final errorMessage = AppLocalizations.of(context)!.invalidValue;
final result = await showDialog<String>( final result = await showDialog<String>(
@ -64,7 +64,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
if (key == Preferences.url) { if (key == Preferences.url) {
final uri = Uri.tryParse(result); final uri = Uri.tryParse(result);
if (uri == null || uri.host.isEmpty || !(uri.scheme == 'http' || uri.scheme == 'https')) { if (uri == null || uri.host.isEmpty || !(uri.scheme == 'http' || uri.scheme == 'https')) {
scaffoldManager.showSnackBar(SnackBar(content: Text(errorMessage))); messengerKey.currentState?.showSnackBar(SnackBar(content: Text(errorMessage)));
return; return;
} }
} }