Copilot edit
This commit is contained in:
parent
60c91e8fbb
commit
b2c471c26e
|
|
@ -1,6 +1,5 @@
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'package:firebase_core/firebase_core.dart';
|
import 'package:firebase_core/firebase_core.dart';
|
||||||
import 'package:firebase_messaging/firebase_messaging.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_animate/flutter_animate.dart';
|
import 'package:flutter_animate/flutter_animate.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
|
@ -13,23 +12,15 @@ import 'package:proxibuy/presentation/comment/bloc/comment_bloc.dart'; // این
|
||||||
import 'package:proxibuy/presentation/notification_preferences/bloc/notification_preferences_bloc.dart';
|
import 'package:proxibuy/presentation/notification_preferences/bloc/notification_preferences_bloc.dart';
|
||||||
import 'package:proxibuy/presentation/offer/bloc/offer_bloc.dart';
|
import 'package:proxibuy/presentation/offer/bloc/offer_bloc.dart';
|
||||||
import 'package:proxibuy/presentation/reservation/cubit/reservation_cubit.dart';
|
import 'package:proxibuy/presentation/reservation/cubit/reservation_cubit.dart';
|
||||||
import 'package:proxibuy/services/background_service.dart';
|
|
||||||
import 'package:proxibuy/services/mqtt_service.dart';
|
import 'package:proxibuy/services/mqtt_service.dart';
|
||||||
import 'core/config/app_colors.dart';
|
import 'core/config/app_colors.dart';
|
||||||
import 'package:proxibuy/presentation/pages/splash_screen.dart';
|
import 'package:proxibuy/presentation/pages/splash_screen.dart';
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
|
|
||||||
Future<String?> getFcmToken() async {
|
|
||||||
FirebaseMessaging messaging = FirebaseMessaging.instance;
|
|
||||||
String? token = await messaging.getToken();
|
|
||||||
print("🔥 Firebase Messaging Token: $token");
|
|
||||||
return token;
|
|
||||||
}
|
|
||||||
|
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
await initializeService();
|
// Background service را بعداً initialize خواهیم کرد
|
||||||
|
// await initializeService();
|
||||||
|
|
||||||
HttpOverrides.global = MyHttpOverrides();
|
HttpOverrides.global = MyHttpOverrides();
|
||||||
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
|
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,8 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:flutter_background_service/flutter_background_service.dart';
|
import 'package:flutter_background_service/flutter_background_service.dart';
|
||||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
import 'package:geolocator/geolocator.dart';
|
import 'package:geolocator/geolocator.dart' as geo;
|
||||||
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
import 'package:proxibuy/core/config/api_config.dart';
|
import 'package:proxibuy/core/config/api_config.dart';
|
||||||
import 'package:proxibuy/core/config/app_colors.dart';
|
import 'package:proxibuy/core/config/app_colors.dart';
|
||||||
import 'package:proxibuy/core/gen/assets.gen.dart';
|
import 'package:proxibuy/core/gen/assets.gen.dart';
|
||||||
|
|
@ -40,7 +41,9 @@ class _OffersPageState extends State<OffersPage> {
|
||||||
List<String> _selectedCategories = [];
|
List<String> _selectedCategories = [];
|
||||||
StreamSubscription? _locationServiceSubscription;
|
StreamSubscription? _locationServiceSubscription;
|
||||||
StreamSubscription? _connectivitySubscription;
|
StreamSubscription? _connectivitySubscription;
|
||||||
|
Timer? _permissionCheckTimer;
|
||||||
bool _isGpsEnabled = false;
|
bool _isGpsEnabled = false;
|
||||||
|
bool _isNotificationEnabled = false;
|
||||||
bool _isConnectedToInternet = true;
|
bool _isConnectedToInternet = true;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -50,12 +53,14 @@ class _OffersPageState extends State<OffersPage> {
|
||||||
_initializePage();
|
_initializePage();
|
||||||
_initConnectivityListener();
|
_initConnectivityListener();
|
||||||
_fetchInitialReservations();
|
_fetchInitialReservations();
|
||||||
|
_startPermissionMonitoring();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_locationServiceSubscription?.cancel();
|
_locationServiceSubscription?.cancel();
|
||||||
_connectivitySubscription?.cancel();
|
_connectivitySubscription?.cancel();
|
||||||
|
_permissionCheckTimer?.cancel();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -170,25 +175,63 @@ class _OffersPageState extends State<OffersPage> {
|
||||||
void _initLocationListener() {
|
void _initLocationListener() {
|
||||||
_checkInitialGpsStatus();
|
_checkInitialGpsStatus();
|
||||||
_locationServiceSubscription =
|
_locationServiceSubscription =
|
||||||
Geolocator.getServiceStatusStream().listen((status) {
|
geo.Geolocator.getServiceStatusStream().listen((status) async {
|
||||||
final isEnabled = status == ServiceStatus.enabled;
|
final isServiceEnabled = status == geo.ServiceStatus.enabled;
|
||||||
if (mounted && _isGpsEnabled != isEnabled) {
|
|
||||||
|
// Also check permission when service status changes
|
||||||
|
bool hasPermission = false;
|
||||||
|
if (isServiceEnabled) {
|
||||||
|
try {
|
||||||
|
geo.LocationPermission permission = await geo.Geolocator.checkPermission();
|
||||||
|
hasPermission = permission == geo.LocationPermission.whileInUse ||
|
||||||
|
permission == geo.LocationPermission.always;
|
||||||
|
} catch (e) {
|
||||||
|
debugPrint("Error checking permission in listener: $e");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final isGpsEnabledNew = isServiceEnabled && hasPermission;
|
||||||
|
|
||||||
|
if (mounted && _isGpsEnabled != isGpsEnabledNew) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_isGpsEnabled = isEnabled;
|
_isGpsEnabled = isGpsEnabledNew;
|
||||||
});
|
});
|
||||||
if (!isEnabled) {
|
if (!isGpsEnabledNew) {
|
||||||
context.read<OffersBloc>().add(ClearOffers());
|
context.read<OffersBloc>().add(ClearOffers());
|
||||||
|
|
||||||
|
// Show GPS dialog if GPS becomes disabled
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
if (mounted) {
|
||||||
|
showGPSDialog(context);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _checkInitialGpsStatus() async {
|
Future<void> _checkInitialGpsStatus() async {
|
||||||
final status = await Geolocator.isLocationServiceEnabled();
|
try {
|
||||||
if (mounted) {
|
// Check if location service is enabled
|
||||||
setState(() {
|
final serviceEnabled = await geo.Geolocator.isLocationServiceEnabled();
|
||||||
_isGpsEnabled = status;
|
|
||||||
});
|
// Check location permission
|
||||||
|
geo.LocationPermission permission = await geo.Geolocator.checkPermission();
|
||||||
|
bool hasPermission = permission == geo.LocationPermission.whileInUse ||
|
||||||
|
permission == geo.LocationPermission.always;
|
||||||
|
|
||||||
|
if (mounted) {
|
||||||
|
setState(() {
|
||||||
|
_isGpsEnabled = serviceEnabled && hasPermission;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
debugPrint("Error checking GPS status: $e");
|
||||||
|
if (mounted) {
|
||||||
|
setState(() {
|
||||||
|
_isGpsEnabled = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -204,6 +247,55 @@ class _OffersPageState extends State<OffersPage> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _startPermissionMonitoring() {
|
||||||
|
// Initial check
|
||||||
|
_checkAllPermissions();
|
||||||
|
|
||||||
|
// Periodic check every 5 seconds
|
||||||
|
_permissionCheckTimer = Timer.periodic(const Duration(seconds: 5), (timer) {
|
||||||
|
_checkAllPermissions();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _checkAllPermissions() async {
|
||||||
|
if (!mounted) return;
|
||||||
|
|
||||||
|
// Check GPS permission and service
|
||||||
|
await _checkInitialGpsStatus();
|
||||||
|
|
||||||
|
// Check notification permission
|
||||||
|
await _checkInitialNotificationStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _checkInitialNotificationStatus() async {
|
||||||
|
try {
|
||||||
|
final status = await Permission.notification.status;
|
||||||
|
final isEnabled = status.isGranted;
|
||||||
|
|
||||||
|
if (mounted && _isNotificationEnabled != isEnabled) {
|
||||||
|
setState(() {
|
||||||
|
_isNotificationEnabled = isEnabled;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Show notification dialog if permission is revoked
|
||||||
|
if (!isEnabled) {
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
if (mounted) {
|
||||||
|
showNotificationPermissionDialog(context);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
debugPrint("Error checking notification status: $e");
|
||||||
|
if (mounted) {
|
||||||
|
setState(() {
|
||||||
|
_isNotificationEnabled = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> _handleRefresh() {
|
Future<void> _handleRefresh() {
|
||||||
final completer = Completer<void>();
|
final completer = Completer<void>();
|
||||||
final service = FlutterBackgroundService();
|
final service = FlutterBackgroundService();
|
||||||
|
|
@ -530,7 +622,7 @@ class OffersView extends StatelessWidget {
|
||||||
const SizedBox(height: 60),
|
const SizedBox(height: 60),
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
await Geolocator.openLocationSettings();
|
await geo.Geolocator.openLocationSettings();
|
||||||
},
|
},
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
backgroundColor: AppColors.confirm,
|
backgroundColor: AppColors.confirm,
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import 'package:connectivity_plus/connectivity_plus.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||||
|
import 'package:geolocator/geolocator.dart';
|
||||||
import 'package:permission_handler/permission_handler.dart';
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
import 'package:proxibuy/core/config/app_colors.dart';
|
import 'package:proxibuy/core/config/app_colors.dart';
|
||||||
import 'package:proxibuy/presentation/auth/bloc/auth_bloc.dart';
|
import 'package:proxibuy/presentation/auth/bloc/auth_bloc.dart';
|
||||||
|
|
@ -10,6 +11,7 @@ import 'package:proxibuy/presentation/pages/onboarding_page.dart';
|
||||||
import 'package:proxibuy/presentation/pages/offers_page.dart';
|
import 'package:proxibuy/presentation/pages/offers_page.dart';
|
||||||
import 'package:proxibuy/core/gen/assets.gen.dart';
|
import 'package:proxibuy/core/gen/assets.gen.dart';
|
||||||
import 'package:proxibuy/services/mqtt_service.dart';
|
import 'package:proxibuy/services/mqtt_service.dart';
|
||||||
|
import 'package:proxibuy/services/background_service.dart';
|
||||||
import 'package:firebase_messaging/firebase_messaging.dart';
|
import 'package:firebase_messaging/firebase_messaging.dart';
|
||||||
|
|
||||||
class SplashScreen extends StatefulWidget {
|
class SplashScreen extends StatefulWidget {
|
||||||
|
|
@ -212,11 +214,35 @@ class _SplashScreenState extends State<SplashScreen> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _requestPermissions() async {
|
Future<void> _requestPermissions() async {
|
||||||
await Permission.notification.request();
|
try {
|
||||||
|
// Request notification permission
|
||||||
|
await Permission.notification.request();
|
||||||
|
|
||||||
var status = await Permission.location.request();
|
// Check and request location permission
|
||||||
if (status.isGranted) {
|
LocationPermission permission = await Geolocator.checkPermission();
|
||||||
await Permission.locationAlways.request();
|
|
||||||
|
if (permission == LocationPermission.denied) {
|
||||||
|
permission = await Geolocator.requestPermission();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only request "always" permission if basic location is granted
|
||||||
|
if (permission == LocationPermission.whileInUse ||
|
||||||
|
permission == LocationPermission.always) {
|
||||||
|
// Request background location permission using permission_handler
|
||||||
|
await Permission.locationAlways.request();
|
||||||
|
}
|
||||||
|
|
||||||
|
debugPrint("Location permission status: $permission");
|
||||||
|
|
||||||
|
// حالا که permissions گرفته شد، background service را راهاندازی کنیم
|
||||||
|
try {
|
||||||
|
await initializeService();
|
||||||
|
debugPrint("Background Service initialized successfully");
|
||||||
|
} catch (e) {
|
||||||
|
debugPrint("Error initializing Background Service: $e");
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
debugPrint("Error requesting permissions: $e");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -5,110 +5,124 @@ import 'package:proxibuy/core/config/app_colors.dart';
|
||||||
import 'package:proxibuy/core/gen/assets.gen.dart';
|
import 'package:proxibuy/core/gen/assets.gen.dart';
|
||||||
|
|
||||||
Future<void> showGPSDialog(BuildContext context) async {
|
Future<void> showGPSDialog(BuildContext context) async {
|
||||||
bool isLocationEnabled = await Geolocator.isLocationServiceEnabled();
|
try {
|
||||||
if (!isLocationEnabled) {
|
bool isLocationEnabled = await Geolocator.isLocationServiceEnabled();
|
||||||
await showDialog(
|
LocationPermission permission = await Geolocator.checkPermission();
|
||||||
// ignore: use_build_context_synchronously
|
bool hasPermission = permission == LocationPermission.whileInUse ||
|
||||||
context: context,
|
permission == LocationPermission.always;
|
||||||
barrierDismissible: false,
|
|
||||||
builder: (BuildContext context) {
|
if (!isLocationEnabled || !hasPermission) {
|
||||||
return Dialog(
|
await showDialog(
|
||||||
shape:
|
// ignore: use_build_context_synchronously
|
||||||
RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)),
|
context: context,
|
||||||
elevation: 10,
|
barrierDismissible: false,
|
||||||
backgroundColor: Colors.white,
|
builder: (BuildContext context) {
|
||||||
child: Stack(
|
return Dialog(
|
||||||
clipBehavior: Clip.none,
|
shape:
|
||||||
alignment: Alignment.topCenter,
|
RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)),
|
||||||
children: [
|
elevation: 10,
|
||||||
Padding(
|
backgroundColor: Colors.white,
|
||||||
padding: const EdgeInsets.only(
|
child: Stack(
|
||||||
top: 40, left: 20, right: 20, bottom: 20),
|
clipBehavior: Clip.none,
|
||||||
child: Column(
|
alignment: Alignment.topCenter,
|
||||||
mainAxisSize: MainAxisSize.min,
|
children: [
|
||||||
children: [
|
Padding(
|
||||||
const SizedBox(height: 10),
|
padding: const EdgeInsets.only(
|
||||||
const Padding(
|
top: 40, left: 20, right: 20, bottom: 20),
|
||||||
padding: EdgeInsets.all(15.0),
|
child: Column(
|
||||||
child: Text(
|
mainAxisSize: MainAxisSize.min,
|
||||||
"فعالسازی موقعیت مکانی (GPS)",
|
children: [
|
||||||
style: TextStyle(
|
const SizedBox(height: 10),
|
||||||
fontSize: 16,
|
const Padding(
|
||||||
fontWeight: FontWeight.bold,
|
padding: EdgeInsets.all(15.0),
|
||||||
),
|
child: Text(
|
||||||
),
|
"فعالسازی موقعیت مکانی (GPS)",
|
||||||
),
|
style: TextStyle(
|
||||||
const SizedBox(height: 5),
|
fontSize: 16,
|
||||||
const Text(
|
fontWeight: FontWeight.bold,
|
||||||
"برای اینکه بتونیم تخفیفهای اطرافت رو سریع بهت اطلاع بدیم، اجازه بده به موقعیت مکانیت دسترسی داشته باشیم.",
|
|
||||||
style: TextStyle(
|
|
||||||
color: AppColors.hint,
|
|
||||||
fontSize: 16,
|
|
||||||
),
|
|
||||||
textAlign: TextAlign.start,
|
|
||||||
),
|
|
||||||
const SizedBox(height: 20),
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
|
||||||
children: [
|
|
||||||
GestureDetector(
|
|
||||||
onTap: () => Navigator.of(context).pop(),
|
|
||||||
child: Text("الان نه",style: TextStyle(color: AppColors.primary,fontWeight: FontWeight.bold),),
|
|
||||||
),
|
|
||||||
ElevatedButton(
|
|
||||||
style: ElevatedButton.styleFrom(
|
|
||||||
backgroundColor: AppColors.primary,
|
|
||||||
foregroundColor: Colors.white,
|
|
||||||
shape: RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
side: const BorderSide(color: AppColors.border),
|
|
||||||
),
|
|
||||||
padding: const EdgeInsets.symmetric(
|
|
||||||
horizontal: 45, vertical: 7),
|
|
||||||
),
|
|
||||||
onPressed: () async {
|
|
||||||
await Geolocator.openLocationSettings();
|
|
||||||
// ignore: use_build_context_synchronously
|
|
||||||
Navigator.of(context).pop();
|
|
||||||
},
|
|
||||||
child: const Text(
|
|
||||||
"فعالسازی",
|
|
||||||
style: TextStyle(color: Colors.white),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
],
|
const SizedBox(height: 5),
|
||||||
),
|
Text(
|
||||||
),
|
!isLocationEnabled
|
||||||
Positioned(
|
? "برای اینکه بتونیم تخفیفهای اطرافت رو سریع بهت اطلاع بدیم، لطفاً GPS رو فعال کن."
|
||||||
top: -40,
|
: "برای اینکه بتونیم تخفیفهای اطرافت رو سریع بهت اطلاع بدیم، اجازه بده به موقعیت مکانیت دسترسی داشته باشیم.",
|
||||||
child: Container(
|
style: const TextStyle(
|
||||||
decoration: BoxDecoration(
|
color: AppColors.hint,
|
||||||
shape: BoxShape.circle,
|
fontSize: 16,
|
||||||
boxShadow: [
|
),
|
||||||
BoxShadow(
|
textAlign: TextAlign.start,
|
||||||
// ignore: deprecated_member_use
|
),
|
||||||
color: Colors.black.withOpacity(0.3),
|
const SizedBox(height: 20),
|
||||||
blurRadius: 8,
|
Row(
|
||||||
offset: const Offset(0, 4),
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
|
children: [
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () => Navigator.of(context).pop(),
|
||||||
|
child: Text("الان نه",style: TextStyle(color: AppColors.primary,fontWeight: FontWeight.bold),),
|
||||||
|
),
|
||||||
|
ElevatedButton(
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: AppColors.primary,
|
||||||
|
foregroundColor: Colors.white,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
side: const BorderSide(color: AppColors.border),
|
||||||
|
),
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 45, vertical: 7),
|
||||||
|
),
|
||||||
|
onPressed: () async {
|
||||||
|
if (!isLocationEnabled) {
|
||||||
|
await Geolocator.openLocationSettings();
|
||||||
|
} else if (!hasPermission) {
|
||||||
|
await Geolocator.requestPermission();
|
||||||
|
}
|
||||||
|
// ignore: use_build_context_synchronously
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
child: Text(
|
||||||
|
!isLocationEnabled ? "فعالسازی GPS" : "اجازه دسترسی",
|
||||||
|
style: const TextStyle(color: Colors.white),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
child: CircleAvatar(
|
),
|
||||||
backgroundColor: Colors.white,
|
Positioned(
|
||||||
radius: 40,
|
top: -40,
|
||||||
child: Padding(
|
child: Container(
|
||||||
padding: const EdgeInsets.all(12.0),
|
decoration: BoxDecoration(
|
||||||
child: SvgPicture.asset(Assets.icons.globalSearch.path),
|
shape: BoxShape.circle,
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
// ignore: deprecated_member_use
|
||||||
|
color: Colors.black.withOpacity(0.3),
|
||||||
|
blurRadius: 8,
|
||||||
|
offset: const Offset(0, 4),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: CircleAvatar(
|
||||||
|
backgroundColor: Colors.white,
|
||||||
|
radius: 40,
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(12.0),
|
||||||
|
child: SvgPicture.asset(Assets.icons.globalSearch.path),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
);
|
||||||
);
|
},
|
||||||
},
|
);
|
||||||
);
|
}
|
||||||
|
} catch (e) {
|
||||||
|
debugPrint("Error showing GPS dialog: $e");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2,11 +2,9 @@ import 'dart:async';
|
||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_background_service/flutter_background_service.dart';
|
import 'package:flutter_background_service/flutter_background_service.dart';
|
||||||
import 'package:flutter_background_service_android/flutter_background_service_android.dart';
|
|
||||||
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||||
import 'package:geolocator/geolocator.dart';
|
import 'package:geolocator/geolocator.dart';
|
||||||
import 'package:permission_handler/permission_handler.dart';
|
|
||||||
import 'package:proxibuy/services/mqtt_service.dart';
|
import 'package:proxibuy/services/mqtt_service.dart';
|
||||||
|
|
||||||
const notificationChannelId = 'proxibuy_foreground_service';
|
const notificationChannelId = 'proxibuy_foreground_service';
|
||||||
|
|
@ -31,15 +29,30 @@ void onStart(ServiceInstance service) async {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> sendGpsData() async {
|
Future<void> sendGpsData() async {
|
||||||
var locationStatus = await Permission.location.status;
|
|
||||||
if (!locationStatus.isGranted) {
|
|
||||||
debugPrint("Background Service: Location permission not granted.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// Check location service status
|
||||||
|
bool serviceEnabled = await Geolocator.isLocationServiceEnabled();
|
||||||
|
if (!serviceEnabled) {
|
||||||
|
debugPrint("Background Service: Location service is disabled.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check location permission
|
||||||
|
LocationPermission permission = await Geolocator.checkPermission();
|
||||||
|
if (permission == LocationPermission.denied) {
|
||||||
|
debugPrint("Background Service: Location permission denied.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (permission == LocationPermission.deniedForever) {
|
||||||
|
debugPrint("Background Service: Location permission denied forever.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
final position = await Geolocator.getCurrentPosition(
|
final position = await Geolocator.getCurrentPosition(
|
||||||
desiredAccuracy: LocationAccuracy.high);
|
locationSettings: const LocationSettings(
|
||||||
|
accuracy: LocationAccuracy.high,
|
||||||
|
));
|
||||||
final token = await storage.read(key: 'accessToken');
|
final token = await storage.read(key: 'accessToken');
|
||||||
final userID = await storage.read(key: 'userID');
|
final userID = await storage.read(key: 'userID');
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,9 @@ import 'dart:async';
|
||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_background_service/flutter_background_service.dart';
|
import 'package:flutter_background_service/flutter_background_service.dart';
|
||||||
import 'package:flutter_background_service_android/flutter_background_service_android.dart';
|
|
||||||
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||||
import 'package:geolocator/geolocator.dart';
|
import 'package:geolocator/geolocator.dart';
|
||||||
import 'package:permission_handler/permission_handler.dart';
|
|
||||||
import 'package:proxibuy/services/mqtt_service.dart';
|
import 'package:proxibuy/services/mqtt_service.dart';
|
||||||
|
|
||||||
const notificationChannelId = 'proxibuy_foreground_service';
|
const notificationChannelId = 'proxibuy_foreground_service';
|
||||||
|
|
@ -41,27 +39,42 @@ void onStart(ServiceInstance service) async {
|
||||||
Timer.periodic(const Duration(seconds: 30), (timer) async {
|
Timer.periodic(const Duration(seconds: 30), (timer) async {
|
||||||
debugPrint("✅ Background Service is running and sending location...");
|
debugPrint("✅ Background Service is running and sending location...");
|
||||||
|
|
||||||
var locationStatus = await Permission.location.status;
|
try {
|
||||||
var locationAlwaysStatus = await Permission.locationAlways.status;
|
// Check location service status
|
||||||
if (!locationStatus.isGranted || !locationAlwaysStatus.isGranted) {
|
bool serviceEnabled = await Geolocator.isLocationServiceEnabled();
|
||||||
debugPrint("Background Service: Permissions not granted. Task skipped.");
|
if (!serviceEnabled) {
|
||||||
return;
|
debugPrint("Background Service: Location service is disabled.");
|
||||||
}
|
return;
|
||||||
|
|
||||||
final position = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
|
|
||||||
final token = await storage.read(key: 'accessToken');
|
|
||||||
final userID = await storage.read(key: 'userID');
|
|
||||||
|
|
||||||
if (token != null && token.isNotEmpty && userID != null) {
|
|
||||||
if (!mqttService.isConnected) {
|
|
||||||
await mqttService.connect(token);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mqttService.isConnected) {
|
// Check location permission using Geolocator
|
||||||
final payload = {"userID": userID, "lat": position.latitude, "lng": position.longitude};
|
LocationPermission permission = await Geolocator.checkPermission();
|
||||||
mqttService.publish("proxybuy/sendGps", payload);
|
if (permission == LocationPermission.denied ||
|
||||||
debugPrint("Background Service: GPS sent successfully.");
|
permission == LocationPermission.deniedForever) {
|
||||||
|
debugPrint("Background Service: Location permission not granted. Status: $permission");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final position = await Geolocator.getCurrentPosition(
|
||||||
|
locationSettings: const LocationSettings(
|
||||||
|
accuracy: LocationAccuracy.high,
|
||||||
|
));
|
||||||
|
final token = await storage.read(key: 'accessToken');
|
||||||
|
final userID = await storage.read(key: 'userID');
|
||||||
|
|
||||||
|
if (token != null && token.isNotEmpty && userID != null) {
|
||||||
|
if (!mqttService.isConnected) {
|
||||||
|
await mqttService.connect(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mqttService.isConnected) {
|
||||||
|
final payload = {"userID": userID, "lat": position.latitude, "lng": position.longitude};
|
||||||
|
mqttService.publish("proxybuy/sendGps", payload);
|
||||||
|
debugPrint("Background Service: GPS sent successfully.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
debugPrint("❌ Background Service Error: $e");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue