Skip to content

Commit

Permalink
adds WebSettings to allow controlling maximumAge of location update (#…
Browse files Browse the repository at this point in the history
…1526)

* adds WebSettings to allow controlling maximumAge of location update

* Update CHANGELOG.md

* Update pubspec.yaml

* Update CHANGELOG.md

* Update pubspec.yaml

* Update CHANGELOG.md

* Update pubspec.yaml

---------

Co-authored-by: Maurits van Beusekom <[email protected]>
  • Loading branch information
josh-burton and mvanbeusekom authored Aug 5, 2024
1 parent b741647 commit 881786e
Show file tree
Hide file tree
Showing 14 changed files with 161 additions and 44 deletions.
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ We really appreciate contributions via GitHub pull requests. To contribute take
* `git checkout upstream/develop -b <name_of_your_branch>`
* Apply your changes
* Verify your changes and fix potential warnings/ errors:
* Check formatting: `flutter format .`
* Check formatting: `dart format .`
* Run static analyses: `flutter analyze`
* Run unit-tests: `flutter test`
* Commit your changes: `git commit -am "<your informative commit message>"`
Expand All @@ -46,4 +46,4 @@ Send us your pull request:

* Go to `https://github.com/BaseflowIT/flutter-geolocator` and click the "Compare & pull request" button.

Please make sure you solved all warnings and errors reported by the static code analyses and that you fill in the full pull request template. Failing to do so will result in us asking you to fix it.
Please make sure you solved all warnings and errors reported by the static code analyses and that you fill in the full pull request template. Failing to do so will result in us asking you to fix it.
10 changes: 10 additions & 0 deletions geolocator/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
## 13.0.0

- **BREAKING CHANGE:** Deprecates getCurrentPosition desiredAccuracy, forceAndroidLocationManager, and timeLimit parameters in favor of supplying a LocationSettings class.
- Exposes `WebSettings` from geolocator.
- Updates dependency on geolocator_web to version 4.1.0
- Updates dependency on geolocator_android to version 4.3.0
- Updates dependency on geolocator_apple to version 2.3.7
- Updates dependency on geolocator_windows to version 0.2.3
- Updates dependency on geolocator_platform_interface to version 4.2.3

## 12.0.0

- **BREAKING CHANGE:** Updates dependency on geolocator_web to version [4.0.0](https://pub.dev/packages/geolocator_web/changelog).
Expand Down
46 changes: 32 additions & 14 deletions geolocator/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,12 @@ To query the current location of the device simply make a call to the `getCurren
``` dart
import 'package:geolocator/geolocator.dart';
Position position = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
final LocationSettings locationSettings = LocationSettings(
accuracy: LocationAccuracy.high,
distanceFilter: 100,
);
Position position = await Geolocator.getCurrentPosition(locationSettings: locationSettings);
```

#### Last known location
Expand Down Expand Up @@ -267,29 +272,32 @@ StreamSubscription<Position> positionStream = Geolocator.getPositionStream(locat
});
```

In certain situation it is necessary to specify some platform specific settings. This can be accomplished using the platform specific `AndroidSettings` or `AppleSettings` classes. When using a platform specific class, the platform specific package must be imported as well. For example:
### Platform specific location settings

In certain situation it is necessary to specify some platform specific settings. This can be accomplished using the platform specific `AndroidSettings`, `AppleSettings` and `WebSettings` classes. When using a platform specific class, the platform specific package must be imported as well. For example:

```dart
import 'package:geolocator/geolocator.dart';
import 'package:geolocator_apple/geolocator_apple.dart';
import 'package:geolocator_android/geolocator_android.dart';
import 'package:geolocator_android/geolocator_web.dart';
import 'package:geolocator_apple/geolocator_apple.dart';
late LocationSettings locationSettings;
if (defaultTargetPlatform == TargetPlatform.android) {
locationSettings = AndroidSettings(
accuracy: LocationAccuracy.high,
distanceFilter: 100,
forceLocationManager: true,
intervalDuration: const Duration(seconds: 10),
//(Optional) Set foreground notification config to keep the app alive
//when going to the background
foregroundNotificationConfig: const ForegroundNotificationConfig(
accuracy: LocationAccuracy.high,
distanceFilter: 100,
forceLocationManager: true,
intervalDuration: const Duration(seconds: 10),
//(Optional) Set foreground notification config to keep the app alive
//when going to the background
foregroundNotificationConfig: const ForegroundNotificationConfig(
notificationText:
"Example app will continue to receive your location even when you aren't using it",
notificationTitle: "Running in Background",
enableWakeLock: true,
)
)
);
} else if (defaultTargetPlatform == TargetPlatform.iOS || defaultTargetPlatform == TargetPlatform.macOS) {
locationSettings = AppleSettings(
Expand All @@ -300,16 +308,26 @@ if (defaultTargetPlatform == TargetPlatform.android) {
// Only set to true if our app will be started up in the background.
showBackgroundLocationIndicator: false,
);
} else if (kIsWeb) {
locationSettings = WebSettings(
accuracy: LocationAccuracy.high,
distanceFilter: 100,
maximumAge: Duration(minutes: 5),
);
} else {
locationSettings = LocationSettings(
locationSettings = LocationSettings(
accuracy: LocationAccuracy.high,
distanceFilter: 100,
);
}
// supply location settings to getCurrentPosition
Position position = await Geolocator.getCurrentPosition(locationSettings: locationSettings);
// supply location settings to getPositionStream
StreamSubscription<Position> positionStream = Geolocator.getPositionStream(locationSettings: locationSettings).listen(
(Position? position) {
print(position == null ? 'Unknown' : '${position.latitude.toString()}, ${position.longitude.toString()}');
(Position? position) {
print(position == null ? 'Unknown' : '${position.latitude.toString()}, ${position.longitude.toString()}');
});
```

Expand Down
46 changes: 36 additions & 10 deletions geolocator/lib/geolocator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export 'package:geolocator_android/geolocator_android.dart'
AndroidPosition;
export 'package:geolocator_apple/geolocator_apple.dart'
show AppleSettings, ActivityType;
export 'package:geolocator_apple/geolocator_web.dart' show WebSettings;
export 'package:geolocator_platform_interface/geolocator_platform_interface.dart';

/// Wraps CLLocationManager (on iOS) and FusedLocationProviderClient or
Expand Down Expand Up @@ -60,6 +61,21 @@ class Geolocator {

/// Returns the current position.
///
/// You can control the behavior of the location update by specifying an instance of
/// the [LocationSettings] class for the [locationSettings] parameter.
/// Standard settings are:
/// * `LocationSettings.accuracy`: allows controlling the precision of the position updates by
/// supplying (defaults to "best");
/// * `LocationSettings.distanceFilter`: allows controlling the minimum
/// distance the device needs to move before the update is emitted (default
/// value is 0 which indicates no filter is used);
/// * `LocationSettings.timeLimit`: allows for setting a timeout interval. If
/// between fetching locations the timeout interval is exceeded a
/// [TimeoutException] will be thrown. By default no time limit is configured.
///
/// If you want to specify platform specific settings you can use the
/// [AndroidSettings], [AppleSettings] and [WebSettings] classes.
///
/// You can control the precision of the location updates by supplying the
/// [desiredAccuracy] parameter (defaults to "best").
/// On Android you can force the use of the Android LocationManager instead of
Expand Down Expand Up @@ -101,26 +117,36 @@ class Geolocator {
/// Requests a tradeoff that favors highly accurate locations at the possible
/// expense of additional power usage.
static Future<Position> getCurrentPosition({
LocationSettings? locationSettings,
@Deprecated(
"use settings parameter with AndroidSettings, AppleSettings, WebSettings, or LocationSettings")
LocationAccuracy desiredAccuracy = LocationAccuracy.best,
@Deprecated(
"use settings parameter with AndroidSettings, AppleSettings, WebSettings, or LocationSettings")
bool forceAndroidLocationManager = false,
@Deprecated(
"use settings parameter with AndroidSettings, AppleSettings, WebSettings, or LocationSettings")
Duration? timeLimit,
}) {
late LocationSettings locationSettings;
if (defaultTargetPlatform == TargetPlatform.android) {
locationSettings = AndroidSettings(
LocationSettings? settings;

if (locationSettings != null) {
settings = locationSettings;
} else if (defaultTargetPlatform == TargetPlatform.android) {
settings = AndroidSettings(
accuracy: desiredAccuracy,
forceLocationManager: forceAndroidLocationManager,
timeLimit: timeLimit,
);
} else {
locationSettings = LocationSettings(
accuracy: desiredAccuracy,
timeLimit: timeLimit,
);
}

settings ??= LocationSettings(
accuracy: desiredAccuracy,
timeLimit: timeLimit,
);

return GeolocatorPlatform.instance
.getCurrentPosition(locationSettings: locationSettings);
.getCurrentPosition(locationSettings: settings);
}

/// Fires whenever the location changes inside the bounds of the
Expand Down Expand Up @@ -153,7 +179,7 @@ class Geolocator {
/// [TimeoutException] will be thrown. By default no time limit is configured.
///
/// If you want to specify platform specific settings you can use the
/// [AndroidSettings] and [AppleSettings] classes.
/// [AndroidSettings], [AppleSettings] and [WebSettings] classes.
///
/// Throws a [TimeoutException] when no location is received within the
/// supplied [timeLimit] duration.
Expand Down
14 changes: 7 additions & 7 deletions geolocator/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: geolocator
description: Geolocation plugin for Flutter. This plugin provides a cross-platform (iOS, Android) API for generic location (GPS etc.) functions.
repository: https://github.com/baseflow/flutter-geolocator/tree/main/geolocator
issue_tracker: https://github.com/baseflow/flutter-geolocator/issues?q=is%3Aissue+is%3Aopen
version: 12.0.0
version: 13.0.0

environment:
sdk: ">=2.15.0 <4.0.0"
Expand All @@ -26,15 +26,15 @@ dependencies:
flutter:
sdk: flutter

geolocator_platform_interface: ^4.1.0
geolocator_android: ^4.3.0
geolocator_apple: ^2.3.0
geolocator_web: ^4.0.0
geolocator_windows: ^0.2.2
geolocator_platform_interface: ^4.2.3
geolocator_android: ^4.6.0
geolocator_apple: ^2.3.7
geolocator_web: ^4.1.0
geolocator_windows: ^0.2.3

dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ">=3.0.1 <5.0.0"
mockito: ^5.0.0-nullsafety.7
plugin_platform_interface: ^2.0.0
plugin_platform_interface: ^2.1.8
7 changes: 6 additions & 1 deletion geolocator_web/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
## 4.1.0

- Adds WebSettings class, allowing a location maximumAge to be specified.
- Supports maximumAge parameter in `getCurrentPosition` and `watchPosition` methods.

## 4.0.1

- Upgrades the package:web dependency to version 1.0.0.
- Upgrades Dart SDK from 3.3.0 to 3.4.0 for geolocator_web
- Upgrades Dart SDK from 3.3.0 to 3.4.0 for geolocator_web.

## 4.0.0

Expand Down
8 changes: 7 additions & 1 deletion geolocator_web/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ Please file any issues, bugs or feature requests as an issue on our [GitHub](htt

If you would like to contribute to the plugin (e.g. by improving the documentation, solving a bug or adding a cool new feature), please carefully review our [contribution guide](../CONTRIBUTING.md) and send us your [pull request](https://github.com/Baseflow/flutter-geolocator/pulls).

## Tests

Tests require being run on a browser due to the use of the `dart:js_interop` package:

`flutter test --platform chrome`

## Author

This Geolocator plugin for Flutter is developed by [Baseflow](https://baseflow.com).
This Geolocator plugin for Flutter is developed by [Baseflow](https://baseflow.com).
18 changes: 12 additions & 6 deletions geolocator_web/lib/geolocator_web.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ import 'src/geolocation_manager.dart';
import 'src/permissions_manager.dart';
import 'src/html_geolocation_manager.dart';
import 'src/html_permissions_manager.dart';
import 'src/types/web_settings.dart';

export 'package:geolocator_platform_interface/geolocator_platform_interface.dart';
export 'src/types/web_settings.dart' show WebSettings;

/// The web implementation of [GeolocatorPlatform].
///
Expand Down Expand Up @@ -73,9 +75,11 @@ class GeolocatorPlugin extends GeolocatorPlatform {
LocationSettings? locationSettings,
}) async {
final result = await _geolocation.getCurrentPosition(
enableHighAccuracy: _enableHighAccuracy(locationSettings?.accuracy),
timeout: locationSettings?.timeLimit,
);
enableHighAccuracy: _enableHighAccuracy(locationSettings?.accuracy),
timeout: locationSettings?.timeLimit,
maximumAge: locationSettings is WebSettings
? locationSettings.maximumAge
: null);

return result;
}
Expand All @@ -88,9 +92,11 @@ class GeolocatorPlugin extends GeolocatorPlatform {

return _geolocation
.watchPosition(
enableHighAccuracy: _enableHighAccuracy(locationSettings?.accuracy),
timeout: locationSettings?.timeLimit,
)
enableHighAccuracy: _enableHighAccuracy(locationSettings?.accuracy),
timeout: locationSettings?.timeLimit,
maximumAge: locationSettings is WebSettings
? locationSettings.maximumAge
: null)
.skipWhile((geoposition) {
if (locationSettings?.distanceFilter == 0 ||
locationSettings?.distanceFilter == null) {
Expand Down
8 changes: 8 additions & 0 deletions geolocator_web/lib/src/geolocation_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,15 @@ abstract class GeolocationManager {
/// possible position fix. This can result in slower response times and higher
/// battery consumption.
///
/// [maximumAge] indicates the maximum age of a possible cached position that is acceptable to return.
/// If set to 0, it means that the device cannot use a cached position and must attempt to retrieve the real current position.
///
/// Throws a [TimeoutException] when no position is received within the
/// supplied [timeout] duration.
Future<Position> getCurrentPosition({
bool? enableHighAccuracy,
Duration? timeout,
Duration? maximumAge,
});

/// Returns a position stream providing continuous position updates.
Expand All @@ -22,10 +26,14 @@ abstract class GeolocationManager {
/// possible location fix. This can result in slower response times and higher
/// battery consumption.
///
/// [maximumAge] indicates the maximum age of a possible cached position that is acceptable to return.
/// If set to 0, it means that the device cannot use a cached position and must attempt to retrieve the real current position.
///
/// Throws a [TimeoutException] when no location is received within the
/// supplied [timeout] duration.
Stream<Position> watchPosition({
bool? enableHighAccuracy,
Duration? timeout,
Duration? maximumAge,
});
}
4 changes: 4 additions & 0 deletions geolocator_web/lib/src/html_geolocation_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class HtmlGeolocationManager implements GeolocationManager {
Future<Position> getCurrentPosition({
bool? enableHighAccuracy,
Duration? timeout,
Duration? maximumAge,
}) async {
Completer<Position> completer = Completer();
try {
Expand All @@ -33,6 +34,7 @@ class HtmlGeolocationManager implements GeolocationManager {
enableHighAccuracy: enableHighAccuracy ?? false,
timeout:
timeout?.inMicroseconds ?? const Duration(days: 1).inMilliseconds,
maximumAge: maximumAge?.inMilliseconds ?? 0,
),
);
} catch (e) {
Expand All @@ -47,6 +49,7 @@ class HtmlGeolocationManager implements GeolocationManager {
Stream<Position> watchPosition({
bool? enableHighAccuracy,
Duration? timeout,
Duration? maximumAge,
}) {
int? watchId;
StreamController<Position> controller = StreamController<Position>(
Expand All @@ -69,6 +72,7 @@ class HtmlGeolocationManager implements GeolocationManager {
enableHighAccuracy: enableHighAccuracy ?? false,
timeout:
timeout?.inMicroseconds ?? const Duration(days: 1).inMilliseconds,
maximumAge: maximumAge?.inMilliseconds ?? 0,
),
);
};
Expand Down
26 changes: 26 additions & 0 deletions geolocator_web/lib/src/types/web_settings.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import 'package:geolocator_platform_interface/geolocator_platform_interface.dart';

/// Represents different Web specific settings with which you can set a value
/// other then the default value of the setting.
class WebSettings extends LocationSettings {
/// Initializes a new [WebSpecificSettings] instance with default values.
WebSettings({
super.accuracy,
super.distanceFilter,
this.maximumAge = Duration.zero,
super.timeLimit,
});

/// A value indicating the maximum age of a possible cached position that is acceptable to return.
/// If set to 0, it means that the device cannot use a cached position and must attempt to retrieve the real current position.
/// Default: 0
final Duration maximumAge;

@override
Map<String, dynamic> toJson() {
return super.toJson()
..addAll({
'maximumAge': maximumAge,
});
}
}
Loading

0 comments on commit 881786e

Please sign in to comment.