From 7d33f0efef0d551caa2e67a95957e697b046403a Mon Sep 17 00:00:00 2001 From: Johannes Bolz Date: Wed, 27 Nov 2024 20:18:04 +0100 Subject: [PATCH 1/5] [geolocator_android] Add option to force a specific Android location provider --- .../geolocator/errors/ErrorCodes.java | 2 +- .../location/LocationManagerClient.java | 12 +++++++--- .../geolocator/location/LocationOptions.java | 23 ++++++++++++++----- .../lib/src/types/android_settings.dart | 19 +++++++++++++++ 4 files changed, 46 insertions(+), 10 deletions(-) diff --git a/geolocator_android/android/src/main/java/com/baseflow/geolocator/errors/ErrorCodes.java b/geolocator_android/android/src/main/java/com/baseflow/geolocator/errors/ErrorCodes.java index cea4141e1..38ef1f046 100644 --- a/geolocator_android/android/src/main/java/com/baseflow/geolocator/errors/ErrorCodes.java +++ b/geolocator_android/android/src/main/java/com/baseflow/geolocator/errors/ErrorCodes.java @@ -34,7 +34,7 @@ public String toDescription() { case errorWhileAcquiringPosition: return "An unexpected error occurred while trying to acquire the device's position."; case locationServicesDisabled: - return "Location services are disabled. To receive location updates the location services should be enabled."; + return "Location services are disabled or requested location provider is unavailable. To receive location updates the location services must be enabled. When forcing a specific provider, it must be available on the device."; case permissionDefinitionsNotFound: return "No location permissions are defined in the manifest. Make sure at least ACCESS_FINE_LOCATION or ACCESS_COARSE_LOCATION are defined in the manifest."; case permissionDenied: diff --git a/geolocator_android/android/src/main/java/com/baseflow/geolocator/location/LocationManagerClient.java b/geolocator_android/android/src/main/java/com/baseflow/geolocator/location/LocationManagerClient.java index c8b3e59a0..e2b9fa31c 100644 --- a/geolocator_android/android/src/main/java/com/baseflow/geolocator/location/LocationManagerClient.java +++ b/geolocator_android/android/src/main/java/com/baseflow/geolocator/location/LocationManagerClient.java @@ -77,11 +77,14 @@ static boolean isBetterLocation(Location location, Location bestLocation) { private static @Nullable String determineProvider( @NonNull LocationManager locationManager, - @NonNull LocationAccuracy accuracy) { + @NonNull LocationAccuracy accuracy, + @Nullable String forceProvider) { final List enabledProviders = locationManager.getProviders(true); - if (accuracy == LocationAccuracy.lowest) { + if (forceProvider != null) { + return enabledProviders.contains(forceProvider) ? forceProvider : null; + } else if (accuracy == LocationAccuracy.lowest) { return LocationManager.PASSIVE_PROVIDER; } else if (enabledProviders.contains(LocationManager.FUSED_PROVIDER) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { return LocationManager.FUSED_PROVIDER; @@ -172,7 +175,10 @@ public void startPositionUpdates( quality = accuracyToQuality(accuracy); } - this.currentLocationProvider = determineProvider(this.locationManager, accuracy); + this.currentLocationProvider = determineProvider( + this.locationManager, + accuracy, + locationOptions != null ? locationOptions.getForceProvider() : null); if (this.currentLocationProvider == null) { errorCallback.onError(ErrorCodes.locationServicesDisabled); diff --git a/geolocator_android/android/src/main/java/com/baseflow/geolocator/location/LocationOptions.java b/geolocator_android/android/src/main/java/com/baseflow/geolocator/location/LocationOptions.java index 9087c8270..ee2764f4e 100644 --- a/geolocator_android/android/src/main/java/com/baseflow/geolocator/location/LocationOptions.java +++ b/geolocator_android/android/src/main/java/com/baseflow/geolocator/location/LocationOptions.java @@ -1,5 +1,7 @@ package com.baseflow.geolocator.location; +import androidx.annotation.Nullable; + import java.util.Map; public class LocationOptions { @@ -9,24 +11,27 @@ public class LocationOptions { private final long distanceFilter; private final long timeInterval; private final boolean useMSLAltitude; + private final String forceProvider; private LocationOptions( - LocationAccuracy accuracy, long distanceFilter, long timeInterval, boolean useMSLAltitude) { + LocationAccuracy accuracy, long distanceFilter, long timeInterval, boolean useMSLAltitude, String provider) { this.accuracy = accuracy; this.distanceFilter = distanceFilter; this.timeInterval = timeInterval; this.useMSLAltitude = useMSLAltitude; + this.forceProvider = provider; } public static LocationOptions parseArguments(Map arguments) { if (arguments == null) { - return new LocationOptions(LocationAccuracy.best, 0, 5000, false); + return new LocationOptions(LocationAccuracy.best, 0, 5000, false, null); } final Integer accuracy = (Integer) arguments.get("accuracy"); final Integer distanceFilter = (Integer) arguments.get("distanceFilter"); final Integer timeInterval = (Integer) arguments.get("timeInterval"); final Boolean useMSLAltitude = (Boolean) arguments.get("useMSLAltitude"); + final String provider = (String) arguments.get("forceProvider"); LocationAccuracy locationAccuracy = LocationAccuracy.best; @@ -54,10 +59,11 @@ public static LocationOptions parseArguments(Map arguments) { } return new LocationOptions( - locationAccuracy, - distanceFilter != null ? distanceFilter : 0, - timeInterval != null ? timeInterval : 5000, - useMSLAltitude != null && useMSLAltitude); + locationAccuracy, + distanceFilter != null ? distanceFilter : 0, + timeInterval != null ? timeInterval : 5000, + useMSLAltitude != null && useMSLAltitude, + provider); } public LocationAccuracy getAccuracy() { @@ -75,4 +81,9 @@ public long getTimeInterval() { public boolean isUseMSLAltitude() { return useMSLAltitude; } + + @Nullable + public String getForceProvider() { + return forceProvider; + } } diff --git a/geolocator_android/lib/src/types/android_settings.dart b/geolocator_android/lib/src/types/android_settings.dart index fea5dfb01..8cfa304e9 100644 --- a/geolocator_android/lib/src/types/android_settings.dart +++ b/geolocator_android/lib/src/types/android_settings.dart @@ -17,6 +17,7 @@ class AndroidSettings extends LocationSettings { Duration? timeLimit, this.foregroundNotificationConfig, this.useMSLAltitude = false, + this.forceLocationProvider, }) : super( accuracy: accuracy, distanceFilter: distanceFilter, @@ -74,6 +75,11 @@ class AndroidSettings extends LocationSettings { /// Defaults to false final bool useMSLAltitude; + /// Set this to use a specific [AndroidLocationProvider]. + /// Set this value only in conjunction with [forceLocationManager] set to true. Be sure the provider is available on your targeted devices. + /// Defaults to null. + final AndroidLocationProvider? forceLocationProvider; + @override Map toJson() { return super.toJson() @@ -82,6 +88,19 @@ class AndroidSettings extends LocationSettings { 'timeInterval': intervalDuration?.inMilliseconds, 'foregroundNotificationConfig': foregroundNotificationConfig?.toJson(), 'useMSLAltitude': useMSLAltitude, + 'forceLocationProvider': forceLocationProvider?.name, }); } } + +/// Represents the different [Android location providers](https://developer.android.com/reference/android/location/LocationManager#constants_1) +enum AndroidLocationProvider { + /// [GPS_PROVIDER](https://developer.android.com/reference/android/location/LocationManager#GPS_PROVIDER) + gps, + /// [FUSED_PROVIDER](https://developer.android.com/reference/android/location/LocationManager#FUSED_PROVIDER) + fused, + /// [NETWORK_PROVIDER](https://developer.android.com/reference/android/location/LocationManager#NETWORK_PROVIDER) + network, + /// [PASSIVE_PROVIDER](https://developer.android.com/reference/android/location/LocationManager#PASSIVE_PROVIDER) + passive, +} From eeb5e613915676f652173c8d30f9d34ae3265920 Mon Sep 17 00:00:00 2001 From: Johannes Bolz Date: Wed, 27 Nov 2024 21:16:22 +0100 Subject: [PATCH 2/5] [geolocator_android] export AndroidLocationProvider visibility --- geolocator_android/lib/geolocator_android.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/geolocator_android/lib/geolocator_android.dart b/geolocator_android/lib/geolocator_android.dart index c15a7c21f..b93faef36 100644 --- a/geolocator_android/lib/geolocator_android.dart +++ b/geolocator_android/lib/geolocator_android.dart @@ -16,7 +16,7 @@ export 'package:geolocator_platform_interface/geolocator_platform_interface.dart ServiceStatus; export 'src/geolocator_android.dart'; -export 'src/types/android_settings.dart' show AndroidSettings; +export 'src/types/android_settings.dart' show AndroidSettings, AndroidLocationProvider; export 'src/types/android_position.dart' show AndroidPosition; export 'src/types/foreground_settings.dart' show AndroidResource, ForegroundNotificationConfig; From e90bc4558aac4afa66be42b0dafce748c3f77268 Mon Sep 17 00:00:00 2001 From: Johannes Bolz Date: Wed, 27 Nov 2024 21:24:27 +0100 Subject: [PATCH 3/5] [geolocator_android] make AndroidLocationProvider visible --- geolocator/lib/geolocator.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/geolocator/lib/geolocator.dart b/geolocator/lib/geolocator.dart index 008796a3c..9662d7a84 100644 --- a/geolocator/lib/geolocator.dart +++ b/geolocator/lib/geolocator.dart @@ -8,6 +8,7 @@ import 'package:geolocator_platform_interface/geolocator_platform_interface.dart export 'package:geolocator_android/geolocator_android.dart' show AndroidSettings, + AndroidLocationProvider, ForegroundNotificationConfig, AndroidResource, AndroidPosition; From 0f6e8282d5bcbbf04671255a6a59b119b9bafc5d Mon Sep 17 00:00:00 2001 From: Johannes Bolz Date: Thu, 28 Nov 2024 16:43:12 +0100 Subject: [PATCH 4/5] [geolocator_android] corrected forceProvider field/key name --- geolocator_android/lib/src/types/android_settings.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/geolocator_android/lib/src/types/android_settings.dart b/geolocator_android/lib/src/types/android_settings.dart index 8cfa304e9..c89eee378 100644 --- a/geolocator_android/lib/src/types/android_settings.dart +++ b/geolocator_android/lib/src/types/android_settings.dart @@ -17,7 +17,7 @@ class AndroidSettings extends LocationSettings { Duration? timeLimit, this.foregroundNotificationConfig, this.useMSLAltitude = false, - this.forceLocationProvider, + this.forceProvider, }) : super( accuracy: accuracy, distanceFilter: distanceFilter, @@ -78,7 +78,7 @@ class AndroidSettings extends LocationSettings { /// Set this to use a specific [AndroidLocationProvider]. /// Set this value only in conjunction with [forceLocationManager] set to true. Be sure the provider is available on your targeted devices. /// Defaults to null. - final AndroidLocationProvider? forceLocationProvider; + final AndroidLocationProvider? forceProvider; @override Map toJson() { @@ -88,7 +88,7 @@ class AndroidSettings extends LocationSettings { 'timeInterval': intervalDuration?.inMilliseconds, 'foregroundNotificationConfig': foregroundNotificationConfig?.toJson(), 'useMSLAltitude': useMSLAltitude, - 'forceLocationProvider': forceLocationProvider?.name, + 'forceProvider': forceProvider?.name, }); } } From 5f5e9baa053951cbe86ceae591a9b532313f79c8 Mon Sep 17 00:00:00 2001 From: Johannes Bolz Date: Fri, 29 Nov 2024 11:42:49 +0100 Subject: [PATCH 5/5] [geolocator_android] fixed formatting --- geolocator_android/lib/geolocator_android.dart | 3 ++- geolocator_android/lib/src/types/android_settings.dart | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/geolocator_android/lib/geolocator_android.dart b/geolocator_android/lib/geolocator_android.dart index b93faef36..dabc9fd7a 100644 --- a/geolocator_android/lib/geolocator_android.dart +++ b/geolocator_android/lib/geolocator_android.dart @@ -16,7 +16,8 @@ export 'package:geolocator_platform_interface/geolocator_platform_interface.dart ServiceStatus; export 'src/geolocator_android.dart'; -export 'src/types/android_settings.dart' show AndroidSettings, AndroidLocationProvider; +export 'src/types/android_settings.dart' + show AndroidSettings, AndroidLocationProvider; export 'src/types/android_position.dart' show AndroidPosition; export 'src/types/foreground_settings.dart' show AndroidResource, ForegroundNotificationConfig; diff --git a/geolocator_android/lib/src/types/android_settings.dart b/geolocator_android/lib/src/types/android_settings.dart index c89eee378..ad674056d 100644 --- a/geolocator_android/lib/src/types/android_settings.dart +++ b/geolocator_android/lib/src/types/android_settings.dart @@ -97,10 +97,13 @@ class AndroidSettings extends LocationSettings { enum AndroidLocationProvider { /// [GPS_PROVIDER](https://developer.android.com/reference/android/location/LocationManager#GPS_PROVIDER) gps, + /// [FUSED_PROVIDER](https://developer.android.com/reference/android/location/LocationManager#FUSED_PROVIDER) fused, + /// [NETWORK_PROVIDER](https://developer.android.com/reference/android/location/LocationManager#NETWORK_PROVIDER) network, + /// [PASSIVE_PROVIDER](https://developer.android.com/reference/android/location/LocationManager#PASSIVE_PROVIDER) passive, }