import 'package:wanisdriver/config/AppSnackbar.dart'; import 'package:flutter/material.dart'; import 'package:geolocator/geolocator.dart'; import 'package:get/get.dart'; import 'package:permission_handler/permission_handler.dart'; import '../Provider/utils_singleton.dart'; import '../config/custom_loader.dart'; import '../routes/app_routes.dart'; import '../services/AppBackgroundServices.dart'; import '../services/DriverServices.dart'; import '../utils/colors.dart'; import '../widgets/custom_button.dart'; import '../widgets/custom_text.dart'; class AllowLocationScreen extends StatefulWidget { const AllowLocationScreen({super.key}); @override _AllowLocationScreenState createState() => _AllowLocationScreenState(); } class _AllowLocationScreenState extends State { final driverservice driverservices = driverservice(); bool _permissionsRequested = false; @override void initState() { super.initState(); _checkAllPermissions(); // Your logic is respected } //-- FIX: Modified this method to check for locationAlways -- Future _checkAllPermissions() async { bool locationAlwaysGranted = await Permission.locationAlways.isGranted; bool storageGranted = await Permission.storage.isGranted; bool overlayGranted = await Permission.systemAlertWindow.isGranted; bool cameraGranted = await Permission.camera.isGranted; final batteryStatus = await Permission.ignoreBatteryOptimizations.status; if (locationAlwaysGranted && storageGranted && overlayGranted && cameraGranted && batteryStatus.isGranted) { debugPrint("All permissions seem to be granted already. Starting services."); String token = await driverservices.getToken(); await AppBackgroundServices.startAllServices( user: utils.user!, authToken: token, ); Get.offAllNamed(AppRoutes.main); } } // Your existing helper methods are respected void showLoadingDialog(String message) { Get.dialog( const Center(child: CustomLoader(logoSize: 60.0, dotSize: 10.0)), barrierDismissible: false, ); } Future requestPermission(Permission permission, String permissionName) async { final status = await permission.request(); if (status.isGranted) { return true; } else { AppSnackbar.showInfo('Permission Denied', '$permissionName permission is required. Please enable it in settings.'); return false; } } //-- FIX: This entire method is updated to handle the two-step background location flow -- Future handlePermissions(BuildContext context) async { if (_permissionsRequested) { AppSnackbar.showError('Already Requested', 'Permissions have already been requested. Please enable them in settings if needed.'); return; } _permissionsRequested = true; // MARK AS REQUESTED showLoadingDialog('Requesting Permissions...'); // --- STEP 1: Request Foregound Location --- PermissionStatus locationStatus = await Permission.location.request(); if (!locationStatus.isGranted) { if (Get.isDialogOpen ?? false) Get.back(); Get.snackbar('Permission Required', 'Location "while using the app" is mandatory to proceed.'); if (locationStatus.isPermanentlyDenied) openAppSettings(); return; } // --- STEP 2: Request Background Location --- await Get.dialog( AlertDialog( title: const Text('Background Location Needed'), content: const Text('To get ride offers while the app is in the background, please select "Allow all the time" on the next screen.'), actions: [ TextButton(onPressed: () => Get.back(), child: const Text('OK')), ], ), ); // This will open the settings page for the user await Permission.locationAlways.request(); // --- Request Other Permissions (respecting your original logic) --- bool storageGranted = await requestPermission(Permission.storage, 'Storage'); bool overlayGranted = await requestPermission(Permission.systemAlertWindow, 'System Alert Window'); bool cameraGranted = await requestPermission(Permission.camera, 'Camera'); bool batteryGranted = await requestPermission(Permission.ignoreBatteryOptimizations, 'Battery Optimization'); if (Get.isDialogOpen ?? false) Get.back(); // --- Final Check --- bool locationAlwaysGranted = await Permission.locationAlways.isGranted; if (locationAlwaysGranted && storageGranted && overlayGranted && cameraGranted && batteryGranted) { debugPrint("✅ All permissions granted! Starting services."); String token = await driverservices.getToken(); await AppBackgroundServices.startAllServices( user: utils.user!, authToken: token, ); Get.offAllNamed(AppRoutes.main); } else { // -- FIX: This block now correctly shows an error instead of navigating -- debugPrint("❌ Not all permissions were granted. Staying on this screen."); // AppSnackbar.showError('Permissions Incomplete', 'Some permissions were not granted. Please try again or enable them in settings to continue.'); String token = await driverservices.getToken(); await AppBackgroundServices.startAllServices( user: utils.user!, authToken: token, ); Get.toNamed(AppRoutes.main); } } @override Widget build(BuildContext context) { return Scaffold( backgroundColor:Theme.of(context).brightness == Brightness.dark?AppColors.blackBackgroundColor:AppColors.whiteBackgroundColor, body: Stack( children: [ Padding( padding: const EdgeInsets.symmetric(horizontal: 20), child: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, // Vertically centers the content within the column crossAxisAlignment: CrossAxisAlignment.center, // Horizontally centers the content children: [ Txt( text: 'Allow Permissions', style: TextStyle( fontSize: 25, fontWeight: FontWeight.bold, fontFamily: 'Poppins', color: Theme.of(context).brightness == Brightness.dark?AppColors.white: AppColors.black, ), ), const SizedBox(height: 10), // Added some spacing between title and description Txt( text: 'Choose your location', maxLines: 2, overflow: TextOverflow.ellipsis, textAlign: TextAlign.center, style: TextStyle( fontSize: 15, fontWeight: FontWeight.normal, fontFamily: 'Poppins', color: Theme.of(context).brightness == Brightness.dark?AppColors.white: AppColors.black, ), ), const SizedBox(height: 40), // Space before the button CustomButton( borderRadius: 25, height: 55, onClick: () async { await handlePermissions(context); }, title: 'Allow Permissions', width: MediaQuery.of(context).size.width * 0.75, //backgroundColor: Theme.of(context).brightness == Brightness.dark ? AppColors.darkPrimaryColor : AppColors.primaryColor, ), const SizedBox(height: 15), // Space before the "Skip" text GestureDetector( onTap: () async { showLoadingDialog('Redirecting to Home...'); await Future.delayed(const Duration(seconds: 1)); // Simulate delay if (Get.isDialogOpen ?? false) { Navigator.of(context).pop(); // Close the loading dialog if it's open } Get.toNamed(AppRoutes.main); }, child: const Txt( text: 'Skip', style: TextStyle( fontSize: 19, fontWeight: FontWeight.normal, fontFamily: 'Poppins', color: Color(0xFF757575), ), ), ), ], ), ), ), Positioned( top: 0, left: 0, right: 0, child: Image.asset( 'assets/images/toplocationscreen.png', height: MediaQuery.of(context).size.height * 0.25, width: MediaQuery.of(context).size.width, fit: BoxFit.cover, ), ), ], ), ); } }