diff --git a/siro_rider/android/app/src/main/AndroidManifest.xml b/siro_rider/android/app/src/main/AndroidManifest.xml index 0ddad7f1..2e56c4db 100644 --- a/siro_rider/android/app/src/main/AndroidManifest.xml +++ b/siro_rider/android/app/src/main/AndroidManifest.xml @@ -4,6 +4,9 @@ + + + diff --git a/siro_rider/lib/main.dart b/siro_rider/lib/main.dart index 6c00f5ef..da129cc0 100644 --- a/siro_rider/lib/main.dart +++ b/siro_rider/lib/main.dart @@ -24,6 +24,7 @@ import 'firebase_options.dart'; import 'models/db_sql.dart'; import 'print.dart'; import 'splash_screen_page.dart'; +import 'services/geofencing_service.dart'; // -- Global instances for easy access -- final box = GetStorage(); @@ -55,6 +56,11 @@ void main() { // ✅ التعديل هنا: تهيئة خدمة الـ Live Activity للآيفون IosLiveActivityService.init(); + // Initialize Geofencing Service + if (Platform.isAndroid || Platform.isIOS) { + await SiroGeofencingService.initAndStart(); + } + // Lock screen orientation. await SystemChrome.setPreferredOrientations([ DeviceOrientation.portraitUp, diff --git a/siro_rider/lib/services/geofencing_service.dart b/siro_rider/lib/services/geofencing_service.dart new file mode 100644 index 00000000..3cc35106 --- /dev/null +++ b/siro_rider/lib/services/geofencing_service.dart @@ -0,0 +1,98 @@ +import 'dart:convert'; +import 'package:flutter/foundation.dart'; +import 'package:native_geofence/native_geofence.dart'; +import 'package:http/http.dart' as http; +import 'package:get_storage/get_storage.dart'; +import 'package:siro_rider/constant/links.dart'; + +// Top-level function for background execution +@pragma('vm:entry-point') +Future geofenceBackgroundCallback(GeofenceCallbackParams params) async { + if (params.event == GeofenceEvent.enter) { + // Note: GetStorage might need to be initialized in the background isolate + await GetStorage.init(); + final storage = GetStorage(); + final passengerId = storage.read('passenger_id') ?? ''; + if (passengerId.toString().isEmpty) return; + + for (var geofence in params.geofences) { + debugPrint('Entered Geofence: ${geofence.id}'); + + try { + final url = Uri.parse('${AppLink.server}/api/location/sync_location.php'); + await http.post(url, body: { + 'passenger_id': passengerId.toString(), + 'lat': geofence.location.latitude.toString(), + 'lng': geofence.location.longitude.toString(), + 'source': 'geofence', + }); + } catch (e) { + debugPrint('Geofence API Error: $e'); + } + } + } +} + +class SiroGeofencingService { + static final _storage = GetStorage(); + + static Future initAndStart() async { + try { + await NativeGeofenceManager.instance.initialize(); + } catch (e) { + debugPrint('Error initializing NativeGeofenceManager: $e'); + } + } + + static Future syncZonesWithServer(double lat, double lng) async { + try { + final passengerId = _storage.read('passenger_id') ?? ''; + if (passengerId.toString().isEmpty) return; + + final url = Uri.parse('${AppLink.server}/api/location/sync_location.php'); + final response = await http.post(url, body: { + 'passenger_id': passengerId.toString(), + 'lat': lat.toString(), + 'lng': lng.toString(), + 'source': 'app_usage', + }); + + if (response.statusCode == 200) { + final data = json.decode(response.body); + if (data['status'] == 'success' && data['update_geofences'] != null) { + await _updateLocalGeofences(data['update_geofences']); + } + } + } catch (e) { + debugPrint('Error syncing geofence zones: $e'); + } + } + + static Future _updateLocalGeofences(List regions) async { + try { + for (var region in regions) { + final geofence = Geofence( + id: region['zone_name'], + location: Location( + latitude: double.parse(region['latitude'].toString()), + longitude: double.parse(region['longitude'].toString())), + radiusMeters: double.parse(region['radius_meters'].toString()), + triggers: {GeofenceEvent.enter}, + iosSettings: const IosGeofenceSettings( + initialTrigger: true, + ), + androidSettings: const AndroidGeofenceSettings( + initialTriggers: {GeofenceEvent.enter}, + ), + ); + + await NativeGeofenceManager.instance.createGeofence( + geofence, + geofenceBackgroundCallback, + ); + } + } catch (e) { + debugPrint('Error updating local geofences: $e'); + } + } +} diff --git a/siro_rider/packages/get/example_nav2/ios/Flutter/Generated.xcconfig b/siro_rider/packages/get/example_nav2/ios/Flutter/Generated.xcconfig new file mode 100644 index 00000000..3a84d07e --- /dev/null +++ b/siro_rider/packages/get/example_nav2/ios/Flutter/Generated.xcconfig @@ -0,0 +1,14 @@ +// This is a generated file; do not edit or check into version control. +FLUTTER_ROOT=/Users/hamzaaleghwairyeen/flutter +FLUTTER_APPLICATION_PATH=/Users/hamzaaleghwairyeen/development/App/Siro/siro_rider/packages/get/example_nav2 +COCOAPODS_PARALLEL_CODE_SIGN=true +FLUTTER_TARGET=lib/main.dart +FLUTTER_BUILD_DIR=build +FLUTTER_BUILD_NAME=1.0.0 +FLUTTER_BUILD_NUMBER=1 +EXCLUDED_ARCHS[sdk=iphonesimulator*]=i386 +EXCLUDED_ARCHS[sdk=iphoneos*]=armv7 +DART_OBFUSCATION=false +TRACK_WIDGET_CREATION=true +TREE_SHAKE_ICONS=false +PACKAGE_CONFIG=.dart_tool/package_config.json diff --git a/siro_rider/packages/get/example_nav2/ios/Flutter/ephemeral/flutter_lldb_helper.py b/siro_rider/packages/get/example_nav2/ios/Flutter/ephemeral/flutter_lldb_helper.py new file mode 100644 index 00000000..a88caf99 --- /dev/null +++ b/siro_rider/packages/get/example_nav2/ios/Flutter/ephemeral/flutter_lldb_helper.py @@ -0,0 +1,32 @@ +# +# Generated file, do not edit. +# + +import lldb + +def handle_new_rx_page(frame: lldb.SBFrame, bp_loc, extra_args, intern_dict): + """Intercept NOTIFY_DEBUGGER_ABOUT_RX_PAGES and touch the pages.""" + base = frame.register["x0"].GetValueAsAddress() + page_len = frame.register["x1"].GetValueAsUnsigned() + + # Note: NOTIFY_DEBUGGER_ABOUT_RX_PAGES will check contents of the + # first page to see if handled it correctly. This makes diagnosing + # misconfiguration (e.g. missing breakpoint) easier. + data = bytearray(page_len) + data[0:8] = b'IHELPED!' + + error = lldb.SBError() + frame.GetThread().GetProcess().WriteMemory(base, data, error) + if not error.Success(): + print(f'Failed to write into {base}[+{page_len}]', error) + return + +def __lldb_init_module(debugger: lldb.SBDebugger, _): + target = debugger.GetDummyTarget() + # Caveat: must use BreakpointCreateByRegEx here and not + # BreakpointCreateByName. For some reasons callback function does not + # get carried over from dummy target for the later. + bp = target.BreakpointCreateByRegex("^NOTIFY_DEBUGGER_ABOUT_RX_PAGES$") + bp.SetScriptCallbackFunction('{}.handle_new_rx_page'.format(__name__)) + bp.SetAutoContinue(True) + print("-- LLDB integration loaded --") diff --git a/siro_rider/packages/get/example_nav2/ios/Flutter/ephemeral/flutter_lldbinit b/siro_rider/packages/get/example_nav2/ios/Flutter/ephemeral/flutter_lldbinit new file mode 100644 index 00000000..e3ba6fbe --- /dev/null +++ b/siro_rider/packages/get/example_nav2/ios/Flutter/ephemeral/flutter_lldbinit @@ -0,0 +1,5 @@ +# +# Generated file, do not edit. +# + +command script import --relative-to-command-file flutter_lldb_helper.py diff --git a/siro_rider/packages/get/example_nav2/ios/Flutter/flutter_export_environment.sh b/siro_rider/packages/get/example_nav2/ios/Flutter/flutter_export_environment.sh new file mode 100755 index 00000000..bcb5621f --- /dev/null +++ b/siro_rider/packages/get/example_nav2/ios/Flutter/flutter_export_environment.sh @@ -0,0 +1,13 @@ +#!/bin/sh +# This is a generated file; do not edit or check into version control. +export "FLUTTER_ROOT=/Users/hamzaaleghwairyeen/flutter" +export "FLUTTER_APPLICATION_PATH=/Users/hamzaaleghwairyeen/development/App/Siro/siro_rider/packages/get/example_nav2" +export "COCOAPODS_PARALLEL_CODE_SIGN=true" +export "FLUTTER_TARGET=lib/main.dart" +export "FLUTTER_BUILD_DIR=build" +export "FLUTTER_BUILD_NAME=1.0.0" +export "FLUTTER_BUILD_NUMBER=1" +export "DART_OBFUSCATION=false" +export "TRACK_WIDGET_CREATION=true" +export "TREE_SHAKE_ICONS=false" +export "PACKAGE_CONFIG=.dart_tool/package_config.json" diff --git a/siro_rider/packages/get_storage/example/ios/Flutter/Generated.xcconfig b/siro_rider/packages/get_storage/example/ios/Flutter/Generated.xcconfig new file mode 100644 index 00000000..c6b99b19 --- /dev/null +++ b/siro_rider/packages/get_storage/example/ios/Flutter/Generated.xcconfig @@ -0,0 +1,14 @@ +// This is a generated file; do not edit or check into version control. +FLUTTER_ROOT=/Users/hamzaaleghwairyeen/flutter +FLUTTER_APPLICATION_PATH=/Users/hamzaaleghwairyeen/development/App/Siro/siro_rider/packages/get_storage/example +COCOAPODS_PARALLEL_CODE_SIGN=true +FLUTTER_TARGET=lib/main.dart +FLUTTER_BUILD_DIR=build +FLUTTER_BUILD_NAME=1.0.0 +FLUTTER_BUILD_NUMBER=1 +EXCLUDED_ARCHS[sdk=iphonesimulator*]=i386 +EXCLUDED_ARCHS[sdk=iphoneos*]=armv7 +DART_OBFUSCATION=false +TRACK_WIDGET_CREATION=true +TREE_SHAKE_ICONS=false +PACKAGE_CONFIG=.dart_tool/package_config.json diff --git a/siro_rider/packages/get_storage/example/ios/Flutter/ephemeral/flutter_lldb_helper.py b/siro_rider/packages/get_storage/example/ios/Flutter/ephemeral/flutter_lldb_helper.py new file mode 100644 index 00000000..a88caf99 --- /dev/null +++ b/siro_rider/packages/get_storage/example/ios/Flutter/ephemeral/flutter_lldb_helper.py @@ -0,0 +1,32 @@ +# +# Generated file, do not edit. +# + +import lldb + +def handle_new_rx_page(frame: lldb.SBFrame, bp_loc, extra_args, intern_dict): + """Intercept NOTIFY_DEBUGGER_ABOUT_RX_PAGES and touch the pages.""" + base = frame.register["x0"].GetValueAsAddress() + page_len = frame.register["x1"].GetValueAsUnsigned() + + # Note: NOTIFY_DEBUGGER_ABOUT_RX_PAGES will check contents of the + # first page to see if handled it correctly. This makes diagnosing + # misconfiguration (e.g. missing breakpoint) easier. + data = bytearray(page_len) + data[0:8] = b'IHELPED!' + + error = lldb.SBError() + frame.GetThread().GetProcess().WriteMemory(base, data, error) + if not error.Success(): + print(f'Failed to write into {base}[+{page_len}]', error) + return + +def __lldb_init_module(debugger: lldb.SBDebugger, _): + target = debugger.GetDummyTarget() + # Caveat: must use BreakpointCreateByRegEx here and not + # BreakpointCreateByName. For some reasons callback function does not + # get carried over from dummy target for the later. + bp = target.BreakpointCreateByRegex("^NOTIFY_DEBUGGER_ABOUT_RX_PAGES$") + bp.SetScriptCallbackFunction('{}.handle_new_rx_page'.format(__name__)) + bp.SetAutoContinue(True) + print("-- LLDB integration loaded --") diff --git a/siro_rider/packages/get_storage/example/ios/Flutter/ephemeral/flutter_lldbinit b/siro_rider/packages/get_storage/example/ios/Flutter/ephemeral/flutter_lldbinit new file mode 100644 index 00000000..e3ba6fbe --- /dev/null +++ b/siro_rider/packages/get_storage/example/ios/Flutter/ephemeral/flutter_lldbinit @@ -0,0 +1,5 @@ +# +# Generated file, do not edit. +# + +command script import --relative-to-command-file flutter_lldb_helper.py diff --git a/siro_rider/packages/get_storage/example/ios/Flutter/flutter_export_environment.sh b/siro_rider/packages/get_storage/example/ios/Flutter/flutter_export_environment.sh new file mode 100755 index 00000000..93e855f4 --- /dev/null +++ b/siro_rider/packages/get_storage/example/ios/Flutter/flutter_export_environment.sh @@ -0,0 +1,13 @@ +#!/bin/sh +# This is a generated file; do not edit or check into version control. +export "FLUTTER_ROOT=/Users/hamzaaleghwairyeen/flutter" +export "FLUTTER_APPLICATION_PATH=/Users/hamzaaleghwairyeen/development/App/Siro/siro_rider/packages/get_storage/example" +export "COCOAPODS_PARALLEL_CODE_SIGN=true" +export "FLUTTER_TARGET=lib/main.dart" +export "FLUTTER_BUILD_DIR=build" +export "FLUTTER_BUILD_NAME=1.0.0" +export "FLUTTER_BUILD_NUMBER=1" +export "DART_OBFUSCATION=false" +export "TRACK_WIDGET_CREATION=true" +export "TREE_SHAKE_ICONS=false" +export "PACKAGE_CONFIG=.dart_tool/package_config.json" diff --git a/siro_rider/packages/get_storage/example/linux/flutter/ephemeral/.plugin_symlinks/jni b/siro_rider/packages/get_storage/example/linux/flutter/ephemeral/.plugin_symlinks/jni new file mode 120000 index 00000000..9d997f0a --- /dev/null +++ b/siro_rider/packages/get_storage/example/linux/flutter/ephemeral/.plugin_symlinks/jni @@ -0,0 +1 @@ +/Users/hamzaaleghwairyeen/.pub-cache/hosted/pub.dev/jni-1.0.0/ \ No newline at end of file diff --git a/siro_rider/packages/get_storage/example/linux/flutter/ephemeral/.plugin_symlinks/path_provider_linux b/siro_rider/packages/get_storage/example/linux/flutter/ephemeral/.plugin_symlinks/path_provider_linux new file mode 120000 index 00000000..189b3e6b --- /dev/null +++ b/siro_rider/packages/get_storage/example/linux/flutter/ephemeral/.plugin_symlinks/path_provider_linux @@ -0,0 +1 @@ +/Users/hamzaaleghwairyeen/.pub-cache/hosted/pub.dev/path_provider_linux-2.2.1/ \ No newline at end of file diff --git a/siro_rider/pubspec.lock b/siro_rider/pubspec.lock index 7922cd32..2f1e1ab2 100644 --- a/siro_rider/pubspec.lock +++ b/siro_rider/pubspec.lock @@ -1325,6 +1325,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.0" + native_geofence: + dependency: "direct main" + description: + name: native_geofence + sha256: "472c33abe8dc2eb9e2021e1db7964952a1781582ad2e716182edfbbdff346597" + url: "https://pub.dev" + source: hosted + version: "1.3.1" nested: dependency: transitive description: diff --git a/siro_rider/pubspec.yaml b/siro_rider/pubspec.yaml index 13e24add..1a400a2c 100644 --- a/siro_rider/pubspec.yaml +++ b/siro_rider/pubspec.yaml @@ -10,6 +10,7 @@ environment: dependencies: flutter: sdk: flutter + native_geofence: ^1.1.0 cupertino_icons: ^1.0.8 flutter_webrtc: ^1.4.1 secure_string_operations: