Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] Throw LocationSignalLostException when GPS signal is lost #1617

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions geolocator/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 13.1.0

* Position update stream may now throw `LocationSignalLostException` when GPS signal is lost. This new exception is safe to catch & ignore.

## 13.0.2

- Updates dependency on geolocator_apple to version 2.3.8.
Expand Down
3 changes: 3 additions & 0 deletions geolocator/lib/geolocator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,9 @@ class Geolocator {
/// supplied [timeLimit] duration.
/// Throws a [LocationServiceDisabledException] when the user allowed access,
/// but the location services of the device are disabled.
/// Throws a [LocationSignalLostException] when the location/GPS signal is
/// lost. The caller should catch this exception and is free to ignore it. The
/// stream will continue to emit location updates when the signal is restored.
static Stream<Position> getPositionStream({
LocationSettings? locationSettings,
}) =>
Expand Down
8 changes: 4 additions & 4 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: 13.0.2
version: 13.1.0

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

geolocator_platform_interface: ^4.2.3
geolocator_android: ^4.6.0
geolocator_apple: ^2.3.8
geolocator_platform_interface: ^4.3.0
geolocator_android: ^4.7.0
geolocator_apple: ^2.4.0
geolocator_web: ^4.1.1
geolocator_windows: ^0.2.3

Expand Down
4 changes: 4 additions & 0 deletions geolocator_android/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 4.7.0

* Posiiton stream now throws `LocationSignalLostException` when GPS signal is lost. This new exception is safe to ignore.

## 4.6.1

* Fixes a bug where the plugin throws an exception while requesting locations updates with coarse location permission only.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ public enum ErrorCodes {
activityMissing,
errorWhileAcquiringPosition,
locationServicesDisabled,
locationSignalLost,
permissionDefinitionsNotFound,
permissionDenied,
permissionRequestInProgress;
Expand All @@ -16,6 +17,8 @@ public String toString() {
return "ERROR_WHILE_ACQUIRING_POSITION";
case locationServicesDisabled:
return "LOCATION_SERVICES_DISABLED";
case locationSignalLost:
return "LOCATION_SIGNAL_LOST";
case permissionDefinitionsNotFound:
return "PERMISSION_DEFINITIONS_NOT_FOUND";
case permissionDenied:
Expand All @@ -35,6 +38,8 @@ public String toDescription() {
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.";
case locationSignalLost:
return "Location signal has been lost. Further location updates are unlikely until something changes with the device's settings or environment.";
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:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,9 @@ public synchronized void onLocationResult(@NonNull LocationResult locationResult
@Override
public synchronized void onLocationAvailability(
@NonNull LocationAvailability locationAvailability) {
if (!locationAvailability.isLocationAvailable() && !checkLocationService(context)) {
if (!locationAvailability.isLocationAvailable()) {
if (errorCallback != null) {
errorCallback.onError(ErrorCodes.locationServicesDisabled);
errorCallback.onError(checkLocationService(context) ? ErrorCodes.locationSignalLost : ErrorCodes.locationServicesDisabled);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#Wed Aug 12 09:15:23 CEST 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-all.zip
2 changes: 2 additions & 0 deletions geolocator_android/lib/src/geolocator_android.dart
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,8 @@ class GeolocatorAndroid extends GeolocatorPlatform {
return ActivityMissingException(exception.message);
case 'LOCATION_SERVICES_DISABLED':
return const LocationServiceDisabledException();
case 'LOCATION_SIGNAL_LOST':
return const LocationSignalLostException();
case 'LOCATION_SUBSCRIPTION_ACTIVE':
return const AlreadySubscribedException();
case 'PERMISSION_DEFINITIONS_NOT_FOUND':
Expand Down
4 changes: 2 additions & 2 deletions geolocator_android/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: geolocator_android
description: Geolocation plugin for Flutter. This plugin provides the Android implementation for the geolocator.
repository: https://github.com/baseflow/flutter-geolocator/tree/main/geolocator_android
issue_tracker: https://github.com/baseflow/flutter-geolocator/issues?q=is%3Aissue+is%3Aopen
version: 4.6.1
version: 4.7.0

environment:
sdk: ">=2.15.0 <4.0.0"
Expand All @@ -20,7 +20,7 @@ flutter:
dependencies:
flutter:
sdk: flutter
geolocator_platform_interface: ^4.1.0
geolocator_platform_interface: ^4.3.0
meta: ^1.10.0
uuid: ">=4.0.0 <6.0.0"

Expand Down
35 changes: 35 additions & 0 deletions geolocator_android/test/geolocator_android_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:geolocator_android/geolocator_android.dart';
import 'package:geolocator_platform_interface/geolocator_platform_interface.dart';

import 'event_channel_mock.dart';
import 'method_channel_mock.dart';
Expand Down Expand Up @@ -1071,6 +1072,40 @@ void main() {
streamController.close();
});

test(
// ignore: lines_longer_than_80_chars
'Should receive a location signal lost exception if location signal is lost',
() async {
// Arrange
final streamController =
StreamController<PlatformException>.broadcast();
EventChannelMock(
channelName: 'flutter.baseflow.com/geolocator_updates_android',
stream: streamController.stream,
);

// Act
final positionStream = GeolocatorAndroid().getPositionStream();
final streamQueue = StreamQueue(positionStream);

// Emit test error
streamController.addError(PlatformException(
code: 'LOCATION_SIGNAL_LOST',
message: 'Location signal lost',
details: null));

// Assert
expect(
streamQueue.next,
throwsA(
isA<LocationSignalLostException>(),
));

// Clean up
streamQueue.cancel();
streamController.close();
});

test(
// ignore: lines_longer_than_80_chars
'Should receive a already subscribed exception', () async {
Expand Down
4 changes: 4 additions & 0 deletions geolocator_apple/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 2.4.0

* Posiiton stream now throws `LocationSignalLostException` when GPS signal is lost. This new exception is safe to ignore.

## 2.3.8+1

* HOT FIX: Adds back implementation of the `stopListening` method in the `GeolocationHandler.m` file.
Expand Down
1 change: 1 addition & 0 deletions geolocator_apple/ios/Classes/Constants/ErrorCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
FOUNDATION_EXPORT NSString * const GeolocatorErrorLocationUpdateFailure;
FOUNDATION_EXPORT NSString * const GeolocatorErrorLocationServicesDisabled;
FOUNDATION_EXPORT NSString * const GeolocatorErrorLocationSubscriptionActive;
FOUNDATION_EXPORT NSString * const GeolocatorErrorLocationSignalLost;
FOUNDATION_EXPORT NSString * const GeolocatorErrorPermissionDefinitionsNotFound;
FOUNDATION_EXPORT NSString * const GeolocatorErrorPermissionDenied;
FOUNDATION_EXPORT NSString * const GeolocatorErrorPermissionRequestInProgress;
1 change: 1 addition & 0 deletions geolocator_apple/ios/Classes/Constants/ErrorCodes.m
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
NSString * const GeolocatorErrorLocationUpdateFailure = @"LOCATION_UPDATE_FAILURE";
NSString * const GeolocatorErrorLocationServicesDisabled = @"LOCATION_SERVICES_DISABLED";
NSString * const GeolocatorErrorLocationSubscriptionActive = @"LOCATION_SUBSCRIPTION_ACTIVE";
NSString * const GeolocatorErrorLocationSignalLost = @"LOCATION_SIGNAL_LOST";
NSString * const GeolocatorErrorPermissionDefinitionsNotFound = @"PERMISSION_DEFINITIONS_NOT_FOUND";
NSString * const GeolocatorErrorPermissionDenied = @"PERMISSION_DENIED";
NSString * const GeolocatorErrorPermissionRequestInProgress = @"PERMISSION_REQUEST_IN_PROGRESS";
3 changes: 3 additions & 0 deletions geolocator_apple/ios/Classes/Handlers/GeolocationHandler.m
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,9 @@ - (void)locationManager:(CLLocationManager *)manager
"Error description: %@", error.localizedFailureReason, error.localizedDescription);

if([error.domain isEqualToString:kCLErrorDomain] && error.code == kCLErrorLocationUnknown) {
if (self.errorHandler) {
self.errorHandler(GeolocatorErrorLocationSignalLost, error.localizedDescription);
}
return;
}

Expand Down
2 changes: 2 additions & 0 deletions geolocator_apple/lib/src/geolocator_apple.dart
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,8 @@ class GeolocatorApple extends GeolocatorPlatform {
return const LocationServiceDisabledException();
case 'LOCATION_SUBSCRIPTION_ACTIVE':
return const AlreadySubscribedException();
case 'LOCATION_SIGNAL_LOST':
return const LocationSignalLostException();
case 'PERMISSION_DEFINITIONS_NOT_FOUND':
return PermissionDefinitionsNotFoundException(exception.message);
case 'PERMISSION_DENIED':
Expand Down
4 changes: 2 additions & 2 deletions geolocator_apple/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: geolocator_apple
description: Geolocation Apple plugin for Flutter. This plugin provides the Apple implementation for the geolocator.
repository: https://github.com/baseflow/flutter-geolocator/tree/main/geolocator_apple
issue_tracker: https://github.com/baseflow/flutter-geolocator/issues?q=is%3Aissue+is%3Aopen
version: 2.3.8+1
version: 2.4.0

environment:
sdk: ">=2.15.0 <4.0.0"
Expand All @@ -22,7 +22,7 @@ flutter:
dependencies:
flutter:
sdk: flutter
geolocator_platform_interface: ^4.1.0
geolocator_platform_interface: ^4.3.0

dev_dependencies:
async: ^2.8.2
Expand Down
35 changes: 35 additions & 0 deletions geolocator_apple/test/geolocator_apple_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'package:async/async.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:geolocator_apple/geolocator_apple.dart';
import 'package:geolocator_platform_interface/geolocator_platform_interface.dart';

import 'event_channel_mock.dart';
import 'method_channel_mock.dart';
Expand Down Expand Up @@ -897,6 +898,40 @@ void main() {
streamController.close();
});

test(
// ignore: lines_longer_than_80_chars
'Should receive a location signal lost exception if location signal is lost',
() async {
// Arrange
final streamController =
StreamController<PlatformException>.broadcast();
EventChannelMock(
channelName: 'flutter.baseflow.com/geolocator_updates_apple',
stream: streamController.stream,
);

// Act
final positionStream = GeolocatorApple().getPositionStream();
final streamQueue = StreamQueue(positionStream);

// Emit test error
streamController.addError(PlatformException(
code: 'LOCATION_SIGNAL_LOST',
message: 'Location signal lost',
details: null));

// Assert
expect(
streamQueue.next,
throwsA(
isA<LocationSignalLostException>(),
));

// Clean up
streamQueue.cancel();
streamController.close();
});

test(
// ignore: lines_longer_than_80_chars
'Should receive a already subscribed exception', () async {
Expand Down
4 changes: 4 additions & 0 deletions geolocator_platform_interface/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 4.3.0

* Adds `LocationSignalLostException` which can be thrown when GPS signal is lost.

## 4.2.4

- Correctly handle integer-like numbers when decoding `Position` from JSON.
Expand Down
1 change: 1 addition & 0 deletions geolocator_platform_interface/lib/src/errors/errors.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export 'activity_missing_exception.dart';
export 'already_subscribed_exception.dart';
export 'invalid_permission_exception.dart';
export 'location_service_disabled_exception.dart';
export 'location_signal_lost_exception.dart';
export 'permission_definitions_not_found_exception.dart';
export 'permission_denied_exception.dart';
export 'permission_request_in_progress_exception.dart';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/// An exception thrown when the GPS signal is lost.
class LocationSignalLostException implements Exception {
/// Constructs the [LocationSignalLostException]
const LocationSignalLostException();

@override
String toString() => 'The location service on the device is unable to '
'retrieve a location. Possibly because the GPS signal is lost.';
}
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,9 @@ abstract class GeolocatorPlatform extends PlatformInterface {
/// location when the user denied access.
/// Throws a [LocationServiceDisabledException] when the user allowed access,
/// but the location services of the device are disabled.
/// Throws a [LocationSignalLostException] when the location/GPS signal is
/// lost. The caller should catch this exception and is free to ignore it. The
/// stream will continue to emit location updates when the signal is restored.
Stream<Position> getPositionStream({
LocationSettings? locationSettings,
}) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,8 @@ class MethodChannelGeolocator extends GeolocatorPlatform {
return ActivityMissingException(exception.message);
case 'LOCATION_SERVICES_DISABLED':
return const LocationServiceDisabledException();
case 'LOCATION_SIGNAL_LOST':
return const LocationSignalLostException();
case 'LOCATION_SUBSCRIPTION_ACTIVE':
return const AlreadySubscribedException();
case 'PERMISSION_DEFINITIONS_NOT_FOUND':
Expand Down
2 changes: 1 addition & 1 deletion geolocator_platform_interface/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ description: A common platform interface for the geolocator plugin.
repository: https://github.com/baseflow/flutter-geolocator/tree/main/geolocator_platform_interface
# NOTE: We strongly prefer non-breaking changes, even at the expense of a
# less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes
version: 4.2.4
version: 4.3.0

dependencies:
flutter:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -891,6 +891,39 @@ void main() {
streamController.close();
});

test(
'Should receive a location signal lost exception when location signal is lost',
() async {
// Arrange
final streamController =
StreamController<PlatformException>.broadcast();
EventChannelMock(
channelName: 'flutter.baseflow.com/geolocator_updates',
stream: streamController.stream,
);

// Act
final positionStream = MethodChannelGeolocator().getPositionStream();
final streamQueue = StreamQueue(positionStream);

// Emit test error
streamController.addError(PlatformException(
code: 'LOCATION_SIGNAL_LOST',
message: 'Location signal lost',
details: null));

// Assert
expect(
streamQueue.next,
throwsA(
isA<LocationSignalLostException>(),
));

// Clean up
streamQueue.cancel();
streamController.close();
});

test('Should receive a permission request in progress exception',
() async {
// Arrange
Expand Down
Loading