diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist
index 23eda06..eac98b6 100644
--- a/ios/Runner/Info.plist
+++ b/ios/Runner/Info.plist
@@ -102,6 +102,7 @@
UIBackgroundModes
location
+ bluetooth-central
bluetooth-peripheral
UILaunchStoryboardName
diff --git a/lib/services/background_location_service.dart b/lib/services/background_location_service.dart
index c93dcd5..04ced60 100644
--- a/lib/services/background_location_service.dart
+++ b/lib/services/background_location_service.dart
@@ -1,4 +1,5 @@
import 'dart:async';
+import 'dart:io';
import 'package:flutter/widgets.dart';
import 'package:geolocator/geolocator.dart';
import 'package:shared_preferences/shared_preferences.dart';
@@ -58,6 +59,16 @@ class BackgroundLocationService {
return false;
}
+ if (Platform.isIOS && permission != LocationPermission.always) {
+ permission = await Geolocator.requestPermission();
+ if (permission != LocationPermission.always) {
+ debugPrint(
+ '⚠️ [BackgroundLocation] iOS background tracking requires Always permission',
+ );
+ return false;
+ }
+ }
+
// Save settings
final prefs = await SharedPreferences.getInstance();
await prefs.setBool(_prefKeyEnabled, true);
@@ -68,8 +79,7 @@ class BackgroundLocationService {
try {
_positionSubscription =
Geolocator.getPositionStream(
- locationSettings: LocationSettings(
- accuracy: LocationAccuracy.best,
+ locationSettings: _buildLocationSettings(
distanceFilter: distanceThreshold.toInt(),
),
).listen((Position position) async {
@@ -171,4 +181,22 @@ class BackgroundLocationService {
await startTracking(distanceThreshold: distance);
}
}
+
+ LocationSettings _buildLocationSettings({int distanceFilter = 10}) {
+ if (Platform.isIOS) {
+ return AppleSettings(
+ accuracy: LocationAccuracy.best,
+ activityType: ActivityType.fitness,
+ allowBackgroundLocationUpdates: true,
+ distanceFilter: distanceFilter,
+ pauseLocationUpdatesAutomatically: false,
+ showBackgroundLocationIndicator: true,
+ );
+ }
+
+ return LocationSettings(
+ accuracy: LocationAccuracy.best,
+ distanceFilter: distanceFilter,
+ );
+ }
}
diff --git a/lib/services/location_tracking_service.dart b/lib/services/location_tracking_service.dart
index c70c339..1b4a940 100644
--- a/lib/services/location_tracking_service.dart
+++ b/lib/services/location_tracking_service.dart
@@ -1,4 +1,5 @@
import 'dart:async';
+import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:geolocator/geolocator.dart';
import 'package:shared_preferences/shared_preferences.dart';
@@ -148,6 +149,10 @@ class LocationTrackingService {
/// Check if location permissions are granted
Future checkPermissions() async {
final permission = await Geolocator.checkPermission();
+ if (Platform.isIOS) {
+ return permission == LocationPermission.always;
+ }
+
return permission == LocationPermission.always ||
permission == LocationPermission.whileInUse;
}
@@ -181,6 +186,16 @@ class LocationTrackingService {
return false;
}
+ if (Platform.isIOS && permission != LocationPermission.always) {
+ permission = await Geolocator.requestPermission();
+ if (permission != LocationPermission.always) {
+ onError?.call(
+ 'Background tracking on iOS requires "Always" location access. Enable it in Settings.',
+ );
+ return false;
+ }
+ }
+
debugPrint('✅ [LocationTracking] Location permissions granted');
return true;
}
@@ -209,9 +224,9 @@ class LocationTrackingService {
}
final position = await Geolocator.getCurrentPosition(
- locationSettings: LocationSettings(
- accuracy: LocationAccuracy.best,
+ locationSettings: _buildLocationSettings(
timeLimit: timeLimit,
+ distanceFilter: 0,
),
);
@@ -255,13 +270,35 @@ class LocationTrackingService {
/// [distanceFilter] - Minimum distance in meters between position updates
Stream getPositionStream({double distanceFilter = 10.0}) {
return Geolocator.getPositionStream(
- locationSettings: LocationSettings(
- accuracy: LocationAccuracy.best,
+ locationSettings: _buildLocationSettings(
distanceFilter: distanceFilter.toInt(),
),
);
}
+ LocationSettings _buildLocationSettings({
+ int distanceFilter = 10,
+ Duration? timeLimit,
+ }) {
+ if (Platform.isIOS) {
+ return AppleSettings(
+ accuracy: LocationAccuracy.best,
+ activityType: ActivityType.fitness,
+ allowBackgroundLocationUpdates: true,
+ distanceFilter: distanceFilter,
+ pauseLocationUpdatesAutomatically: false,
+ showBackgroundLocationIndicator: true,
+ timeLimit: timeLimit,
+ );
+ }
+
+ return LocationSettings(
+ accuracy: LocationAccuracy.best,
+ distanceFilter: distanceFilter,
+ timeLimit: timeLimit,
+ );
+ }
+
// ============================================================================
// Tracking Control
// ============================================================================