Update: 2026-06-30 23:08:15
This commit is contained in:
@@ -4,6 +4,9 @@
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.READ_CONTACTS" />
|
||||
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
|
||||
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
|
||||
|
||||
@@ -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,
|
||||
|
||||
98
siro_rider/lib/services/geofencing_service.dart
Normal file
98
siro_rider/lib/services/geofencing_service.dart
Normal file
@@ -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<void> 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<void> initAndStart() async {
|
||||
try {
|
||||
await NativeGeofenceManager.instance.initialize();
|
||||
} catch (e) {
|
||||
debugPrint('Error initializing NativeGeofenceManager: $e');
|
||||
}
|
||||
}
|
||||
|
||||
static Future<void> 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<void> _updateLocalGeofences(List<dynamic> 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');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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 --")
|
||||
@@ -0,0 +1,5 @@
|
||||
#
|
||||
# Generated file, do not edit.
|
||||
#
|
||||
|
||||
command script import --relative-to-command-file flutter_lldb_helper.py
|
||||
@@ -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"
|
||||
@@ -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
|
||||
@@ -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 --")
|
||||
@@ -0,0 +1,5 @@
|
||||
#
|
||||
# Generated file, do not edit.
|
||||
#
|
||||
|
||||
command script import --relative-to-command-file flutter_lldb_helper.py
|
||||
@@ -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"
|
||||
@@ -0,0 +1 @@
|
||||
/Users/hamzaaleghwairyeen/.pub-cache/hosted/pub.dev/jni-1.0.0/
|
||||
@@ -0,0 +1 @@
|
||||
/Users/hamzaaleghwairyeen/.pub-cache/hosted/pub.dev/path_provider_linux-2.2.1/
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user