26-1-20/1
This commit is contained in:
138
lib/main.dart
138
lib/main.dart
@@ -16,17 +16,16 @@ import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||
import 'package:flutter_overlay_window/flutter_overlay_window.dart';
|
||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||
import 'package:flutter_stripe/flutter_stripe.dart';
|
||||
import 'package:permission_handler/permission_handler.dart'; // ✅ جديد
|
||||
import 'package:device_info_plus/device_info_plus.dart'; // ✅ جديد
|
||||
|
||||
import 'constant/api_key.dart';
|
||||
import 'constant/info.dart';
|
||||
import 'constant/notification.dart';
|
||||
import 'controller/firebase/firbase_messge.dart';
|
||||
import 'controller/firebase/local_notification.dart';
|
||||
import 'controller/functions/add_error.dart';
|
||||
import 'controller/functions/battery_status.dart';
|
||||
import 'controller/functions/background_service.dart';
|
||||
import 'controller/functions/crud.dart';
|
||||
import 'controller/functions/encrypt_decrypt.dart';
|
||||
import 'controller/functions/secure_storage.dart';
|
||||
import 'controller/local/local_controller.dart';
|
||||
import 'controller/local/translations.dart';
|
||||
import 'firebase_options.dart';
|
||||
@@ -41,7 +40,12 @@ final box = GetStorage();
|
||||
const storage = FlutterSecureStorage();
|
||||
DbSql sql = DbSql.instance;
|
||||
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
|
||||
const platform = MethodChannel('com.example.intaleq_driver/app_control');
|
||||
const platform = MethodChannel('com.intaleq_driver/app_control');
|
||||
|
||||
// ✅ قنوات الإشعارات المطلوبة
|
||||
const String backgroundServiceChannelId = 'driver_service_channel';
|
||||
const String locationServiceChannelId = 'location_service_channel';
|
||||
const String geolocatorChannelId = 'geolocator_channel';
|
||||
|
||||
/// تهيئة Firebase بوعي لمنع تهيئة مكرّرة على أندرويد (isolates متعددة)
|
||||
Future<void> initFirebaseIfNeeded() async {
|
||||
@@ -53,6 +57,103 @@ Future<void> initFirebaseIfNeeded() async {
|
||||
}
|
||||
}
|
||||
|
||||
/// ✅ طلب إذن الإشعارات على Android 13+
|
||||
Future<bool> requestNotificationPermission() async {
|
||||
if (Platform.isAndroid) {
|
||||
try {
|
||||
final androidInfo = await DeviceInfoPlugin().androidInfo;
|
||||
|
||||
if (androidInfo.version.sdkInt >= 33) {
|
||||
final status = await Permission.notification.request();
|
||||
|
||||
if (status.isGranted) {
|
||||
print('✅ Notification permission granted');
|
||||
return true;
|
||||
} else if (status.isDenied) {
|
||||
print('⚠️ Notification permission denied');
|
||||
return false;
|
||||
} else if (status.isPermanentlyDenied) {
|
||||
print('⚠️ Notification permission permanently denied');
|
||||
await openAppSettings();
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
print('✅ Android < 13, no runtime notification permission needed');
|
||||
return true;
|
||||
}
|
||||
} catch (e) {
|
||||
print('❌ Error requesting notification permission: $e');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true; // iOS
|
||||
}
|
||||
|
||||
/// ✅ إنشاء جميع قنوات الإشعارات المطلوبة
|
||||
Future<void> createAllNotificationChannels() async {
|
||||
if (!Platform.isAndroid) return;
|
||||
|
||||
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
|
||||
FlutterLocalNotificationsPlugin();
|
||||
|
||||
// قناة Background Service
|
||||
const AndroidNotificationChannel backgroundChannel =
|
||||
AndroidNotificationChannel(
|
||||
backgroundServiceChannelId,
|
||||
'خدمة السائق',
|
||||
description: 'استقبال الطلبات في الخلفية',
|
||||
importance: Importance.low,
|
||||
playSound: false,
|
||||
enableVibration: false,
|
||||
showBadge: false,
|
||||
);
|
||||
|
||||
// قناة Location Service
|
||||
const AndroidNotificationChannel locationChannel = AndroidNotificationChannel(
|
||||
locationServiceChannelId,
|
||||
'خدمة الموقع',
|
||||
description: 'تتبع موقع السائق',
|
||||
importance: Importance.low,
|
||||
playSound: false,
|
||||
enableVibration: false,
|
||||
showBadge: false,
|
||||
);
|
||||
|
||||
// قناة Geolocator
|
||||
const AndroidNotificationChannel geolocatorChannel =
|
||||
AndroidNotificationChannel(
|
||||
geolocatorChannelId,
|
||||
'تحديد الموقع',
|
||||
description: 'خدمة تحديد الموقع الجغرافي',
|
||||
importance: Importance.low,
|
||||
playSound: false,
|
||||
enableVibration: false,
|
||||
showBadge: false,
|
||||
);
|
||||
|
||||
try {
|
||||
// إنشاء جميع القنوات
|
||||
await flutterLocalNotificationsPlugin
|
||||
.resolvePlatformSpecificImplementation<
|
||||
AndroidFlutterLocalNotificationsPlugin>()
|
||||
?.createNotificationChannel(backgroundChannel);
|
||||
|
||||
await flutterLocalNotificationsPlugin
|
||||
.resolvePlatformSpecificImplementation<
|
||||
AndroidFlutterLocalNotificationsPlugin>()
|
||||
?.createNotificationChannel(locationChannel);
|
||||
|
||||
await flutterLocalNotificationsPlugin
|
||||
.resolvePlatformSpecificImplementation<
|
||||
AndroidFlutterLocalNotificationsPlugin>()
|
||||
?.createNotificationChannel(geolocatorChannel);
|
||||
|
||||
print('✅ All notification channels created successfully');
|
||||
} catch (e) {
|
||||
print('❌ Error creating notification channels: $e');
|
||||
}
|
||||
}
|
||||
|
||||
/// ============ Handlers: Background ============
|
||||
|
||||
@pragma('vm:entry-point')
|
||||
@@ -129,7 +230,6 @@ void notificationTapBackground(NotificationResponse notificationResponse) {
|
||||
void overlayMain() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
await GetStorage.init();
|
||||
// await initFirebaseIfNeeded();
|
||||
|
||||
if (!Get.isRegistered<NotificationController>()) {
|
||||
Get.put(NotificationController());
|
||||
@@ -167,31 +267,39 @@ void main() {
|
||||
DeviceOrientation.portraitDown,
|
||||
]);
|
||||
|
||||
// سجل الهاندلر تبع رسائل الخلفية (لازم يكون Top-Level ومع @pragma)
|
||||
// ✅ الترتيب الصحيح: الإذونات → القنوات → الخدمات
|
||||
|
||||
// 1. طلب إذن الإشعارات أولاً (Android 13+)
|
||||
bool notificationPermissionGranted = await requestNotificationPermission();
|
||||
if (!notificationPermissionGranted) {
|
||||
print('⚠️ تحذير: لم يتم منح إذن الإشعارات - قد لا تعمل بعض الميزات');
|
||||
}
|
||||
|
||||
// 2. إنشاء جميع قنوات الإشعارات
|
||||
await createAllNotificationChannels();
|
||||
|
||||
// 3. تهيئة الخدمة (بدون تشغيلها)
|
||||
await BackgroundServiceHelper.initialize();
|
||||
|
||||
// 4. سجل الهاندلر تبع رسائل الخلفية
|
||||
FirebaseMessaging.onBackgroundMessage(backgroundMessageHandler);
|
||||
|
||||
runApp(const MyApp());
|
||||
}, (error, stack) {
|
||||
// ==== START: ERROR FILTER ====
|
||||
final errorString = error.toString();
|
||||
|
||||
// اطبع كل شيء محلياً
|
||||
// (يمكنك استبدال print بـ Log.print إن رغبت)
|
||||
print("Caught Dart error: $error");
|
||||
print(stack);
|
||||
|
||||
// تجاهُل بعض الأخطاء المعروفة
|
||||
final isIgnoredError = errorString.contains('PERMISSION_DENIED') ||
|
||||
errorString.contains('FormatException') ||
|
||||
errorString.contains('Null check operator used on a null value');
|
||||
|
||||
if (!isIgnoredError) {
|
||||
// أرسل فقط ما ليس ضمن قائمة التجاهل
|
||||
CRUD.addError(error.toString(), stack.toString(), 'main');
|
||||
} else {
|
||||
print("Ignoring error and not sending to server: $errorString");
|
||||
}
|
||||
// ==== END: ERROR FILTER ====
|
||||
});
|
||||
}
|
||||
|
||||
@@ -228,8 +336,8 @@ class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
|
||||
|
||||
await FirebaseMessaging.instance.requestPermission();
|
||||
|
||||
// يمكن أيضاً تفعيل foreground presentation options هنا لو احتجت
|
||||
await NotificationController().initNotifications();
|
||||
|
||||
// Generate a random index to pick a message
|
||||
final random = Random();
|
||||
final randomMessage =
|
||||
@@ -259,7 +367,7 @@ class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
|
||||
initialRoute: '/',
|
||||
getPages: [
|
||||
GetPage(name: '/', page: () => SplashScreen()),
|
||||
GetPage(name: '/order-page', page: () => OrderRequestPage()),
|
||||
GetPage(name: '/OrderRequestPage', page: () => OrderRequestPage()),
|
||||
GetPage(
|
||||
name: '/passenger-location-map',
|
||||
page: () => PassengerLocationMapPage(),
|
||||
|
||||
Reference in New Issue
Block a user