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

Solves crashes related to no location permission given #1586

Closed
wants to merge 1 commit into from
Closed
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
116 changes: 55 additions & 61 deletions geolocator_android/lib/src/geolocator_android.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'dart:async';

import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:geolocator_android/geolocator_android.dart';
import 'package:geolocator_platform_interface/geolocator_platform_interface.dart';
Expand All @@ -8,18 +9,15 @@ import 'package:uuid/uuid.dart';
/// An implementation of [GeolocatorPlatform] that uses method channels.
class GeolocatorAndroid extends GeolocatorPlatform {
/// The method channel used to interact with the native platform.
static const _methodChannel =
MethodChannel('flutter.baseflow.com/geolocator_android');
static const _methodChannel = MethodChannel('flutter.baseflow.com/geolocator_android');

/// The event channel used to receive [Position] updates from the native
/// platform.
static const _eventChannel =
EventChannel('flutter.baseflow.com/geolocator_updates_android');
static const _eventChannel = EventChannel('flutter.baseflow.com/geolocator_updates_android');

/// The event channel used to receive [LocationServiceStatus] updates from the
/// native platform.
static const _serviceStatusEventChannel =
EventChannel('flutter.baseflow.com/geolocator_service_updates_android');
static const _serviceStatusEventChannel = EventChannel('flutter.baseflow.com/geolocator_service_updates_android');

/// Registers this class as the default instance of [GeolocatorPlatform].
static void registerWith() {
Expand All @@ -41,8 +39,7 @@ class GeolocatorAndroid extends GeolocatorPlatform {
Future<LocationPermission> checkPermission() async {
try {
// ignore: omit_local_variable_types
final int permission =
await _methodChannel.invokeMethod('checkPermission');
final int permission = await _methodChannel.invokeMethod('checkPermission');

return permission.toLocationPermission();
} on PlatformException catch (e) {
Expand All @@ -56,8 +53,7 @@ class GeolocatorAndroid extends GeolocatorPlatform {
Future<LocationPermission> requestPermission() async {
try {
// ignore: omit_local_variable_types
final int permission =
await _methodChannel.invokeMethod('requestPermission');
final int permission = await _methodChannel.invokeMethod('requestPermission');

return permission.toLocationPermission();
} on PlatformException catch (e) {
Expand All @@ -68,9 +64,8 @@ class GeolocatorAndroid extends GeolocatorPlatform {
}

@override
Future<bool> isLocationServiceEnabled() async => _methodChannel
.invokeMethod<bool>('isLocationServiceEnabled')
.then((value) => value ?? false);
Future<bool> isLocationServiceEnabled() async =>
_methodChannel.invokeMethod<bool>('isLocationServiceEnabled').then((value) => value ?? false);

@override
Future<Position?> getLastKnownPosition({
Expand All @@ -81,8 +76,7 @@ class GeolocatorAndroid extends GeolocatorPlatform {
'forceLocationManager': forceLocationManager,
};

final positionMap =
await _methodChannel.invokeMethod('getLastKnownPosition', parameters);
final positionMap = await _methodChannel.invokeMethod('getLastKnownPosition', parameters);

return positionMap != null ? AndroidPosition.fromMap(positionMap) : null;
} on PlatformException catch (e) {
Expand All @@ -94,8 +88,7 @@ class GeolocatorAndroid extends GeolocatorPlatform {

@override
Future<LocationAccuracyStatus> getLocationAccuracy() async {
final int accuracy =
await _methodChannel.invokeMethod('getLocationAccuracy');
final int accuracy = await _methodChannel.invokeMethod('getLocationAccuracy');
return LocationAccuracyStatus.values[accuracy];
}

Expand Down Expand Up @@ -146,12 +139,10 @@ class GeolocatorAndroid extends GeolocatorPlatform {
if (_serviceStatusStream != null) {
return _serviceStatusStream!;
}
var serviceStatusStream =
_serviceStatusEventChannel.receiveBroadcastStream();
var serviceStatusStream = _serviceStatusEventChannel.receiveBroadcastStream();

_serviceStatusStream = serviceStatusStream
.map((dynamic element) => ServiceStatus.values[element as int])
.handleError((error) {
_serviceStatusStream =
serviceStatusStream.map((dynamic element) => ServiceStatus.values[element as int]).handleError((error) {
_serviceStatusStream = null;
if (error is PlatformException) {
error = _handlePlatformException(error);
Expand All @@ -162,46 +153,51 @@ class GeolocatorAndroid extends GeolocatorPlatform {
return _serviceStatusStream!;
}

// Ryde Modification: Added try catch logic
@override
Stream<Position> getPositionStream({
LocationSettings? locationSettings,
}) {
if (_positionStream != null) {
return _positionStream!;
}
var originalStream = _eventChannel.receiveBroadcastStream(
locationSettings?.toJson(),
);
var positionStream = _wrapStream(originalStream);

var timeLimit = locationSettings?.timeLimit;

if (timeLimit != null) {
positionStream = positionStream.timeout(
timeLimit,
onTimeout: (s) {
_positionStream = null;
s.addError(TimeoutException(
'Time limit reached while waiting for position update.',
timeLimit,
));
s.close();
try {
if (_positionStream != null) {
return _positionStream!;
}
var originalStream = _eventChannel.receiveBroadcastStream(
locationSettings?.toJson(),
);
var positionStream = _wrapStream(originalStream);

var timeLimit = locationSettings?.timeLimit;

if (timeLimit != null) {
positionStream = positionStream.timeout(
timeLimit,
onTimeout: (s) {
_positionStream = null;
s.addError(TimeoutException(
'Time limit reached while waiting for position update.',
timeLimit,
));
s.close();
},
);
}

_positionStream = positionStream
.map<Position>((dynamic element) => AndroidPosition.fromMap(element.cast<String, dynamic>()))
.handleError(
(error) {
if (error is PlatformException) {
error = _handlePlatformException(error);
}
throw error;
},
);
return _positionStream!;
} catch (e) {
if (kDebugMode) print(e);
return const Stream.empty();
}

_positionStream = positionStream
.map<Position>((dynamic element) =>
AndroidPosition.fromMap(element.cast<String, dynamic>()))
.handleError(
(error) {
if (error is PlatformException) {
error = _handlePlatformException(error);
}
throw error;
},
);
return _positionStream!;
}

Stream<dynamic> _wrapStream(Stream<dynamic> incoming) {
Expand Down Expand Up @@ -230,14 +226,12 @@ class GeolocatorAndroid extends GeolocatorPlatform {
}

@override
Future<bool> openAppSettings() async => _methodChannel
.invokeMethod<bool>('openAppSettings')
.then((value) => value ?? false);
Future<bool> openAppSettings() async =>
_methodChannel.invokeMethod<bool>('openAppSettings').then((value) => value ?? false);

@override
Future<bool> openLocationSettings() async => _methodChannel
.invokeMethod<bool>('openLocationSettings')
.then((value) => value ?? false);
Future<bool> openLocationSettings() async =>
_methodChannel.invokeMethod<bool>('openLocationSettings').then((value) => value ?? false);

Exception _handlePlatformException(PlatformException exception) {
switch (exception.code) {
Expand Down
114 changes: 53 additions & 61 deletions geolocator_apple/lib/src/geolocator_apple.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,15 @@ import 'package:geolocator_platform_interface/geolocator_platform_interface.dart
/// An implementation of [GeolocatorPlatform] that uses method channels.
class GeolocatorApple extends GeolocatorPlatform {
/// The method channel used to interact with the native platform.
static const _methodChannel =
MethodChannel('flutter.baseflow.com/geolocator_apple');
static const _methodChannel = MethodChannel('flutter.baseflow.com/geolocator_apple');

/// The event channel used to receive [Position] updates from the native
/// platform.
static const _eventChannel =
EventChannel('flutter.baseflow.com/geolocator_updates_apple');
static const _eventChannel = EventChannel('flutter.baseflow.com/geolocator_updates_apple');

/// The event channel used to receive [LocationServiceStatus] updates from the
/// native platform.
static const _serviceStatusEventChannel =
EventChannel('flutter.baseflow.com/geolocator_service_updates_apple');
static const _serviceStatusEventChannel = EventChannel('flutter.baseflow.com/geolocator_service_updates_apple');

/// Registers this class as the default instance of [GeolocatorPlatform].
static void registerWith() {
Expand All @@ -38,8 +35,7 @@ class GeolocatorApple extends GeolocatorPlatform {
Future<LocationPermission> checkPermission() async {
try {
// ignore: omit_local_variable_types
final int permission =
await _methodChannel.invokeMethod('checkPermission');
final int permission = await _methodChannel.invokeMethod('checkPermission');

return permission.toLocationPermission();
} on PlatformException catch (e) {
Expand All @@ -53,8 +49,7 @@ class GeolocatorApple extends GeolocatorPlatform {
Future<LocationPermission> requestPermission() async {
try {
// ignore: omit_local_variable_types
final int permission =
await _methodChannel.invokeMethod('requestPermission');
final int permission = await _methodChannel.invokeMethod('requestPermission');

return permission.toLocationPermission();
} on PlatformException catch (e) {
Expand All @@ -65,9 +60,8 @@ class GeolocatorApple extends GeolocatorPlatform {
}

@override
Future<bool> isLocationServiceEnabled() async => _methodChannel
.invokeMethod<bool>('isLocationServiceEnabled')
.then((value) => value ?? false);
Future<bool> isLocationServiceEnabled() async =>
_methodChannel.invokeMethod<bool>('isLocationServiceEnabled').then((value) => value ?? false);

@override
Future<Position?> getLastKnownPosition({
Expand All @@ -78,8 +72,7 @@ class GeolocatorApple extends GeolocatorPlatform {
'forceLocationManager': forceLocationManager,
};

final positionMap =
await _methodChannel.invokeMethod('getLastKnownPosition', parameters);
final positionMap = await _methodChannel.invokeMethod('getLastKnownPosition', parameters);

return positionMap != null ? Position.fromMap(positionMap) : null;
} on PlatformException catch (e) {
Expand All @@ -91,8 +84,7 @@ class GeolocatorApple extends GeolocatorPlatform {

@override
Future<LocationAccuracyStatus> getLocationAccuracy() async {
final int accuracy =
await _methodChannel.invokeMethod('getLocationAccuracy');
final int accuracy = await _methodChannel.invokeMethod('getLocationAccuracy');
return LocationAccuracyStatus.values[accuracy];
}

Expand Down Expand Up @@ -133,12 +125,10 @@ class GeolocatorApple extends GeolocatorPlatform {
if (_serviceStatusStream != null) {
return _serviceStatusStream!;
}
var serviceStatusStream =
_serviceStatusEventChannel.receiveBroadcastStream();
var serviceStatusStream = _serviceStatusEventChannel.receiveBroadcastStream();

_serviceStatusStream = serviceStatusStream
.map((dynamic element) => ServiceStatus.values[element as int])
.handleError((error) {
_serviceStatusStream =
serviceStatusStream.map((dynamic element) => ServiceStatus.values[element as int]).handleError((error) {
_serviceStatusStream = null;
if (error is PlatformException) {
error = _handlePlatformException(error);
Expand All @@ -149,46 +139,50 @@ class GeolocatorApple extends GeolocatorPlatform {
return _serviceStatusStream!;
}

// Ryde Modification: added try catch
@override
Stream<Position> getPositionStream({
LocationSettings? locationSettings,
}) {
if (_positionStream != null) {
return _positionStream!;
}
var originalStream = _eventChannel.receiveBroadcastStream(
locationSettings?.toJson(),
);
var positionStream = _wrapStream(originalStream);

var timeLimit = locationSettings?.timeLimit;

if (timeLimit != null) {
positionStream = positionStream.timeout(
timeLimit,
onTimeout: (s) {
_positionStream = null;
s.addError(TimeoutException(
'Time limit reached while waiting for position update.',
timeLimit,
));
s.close();
try {
if (_positionStream != null) {
return _positionStream!;
}
var originalStream = _eventChannel.receiveBroadcastStream(
locationSettings?.toJson(),
);
var positionStream = _wrapStream(originalStream);

var timeLimit = locationSettings?.timeLimit;

if (timeLimit != null) {
positionStream = positionStream.timeout(
timeLimit,
onTimeout: (s) {
_positionStream = null;
s.addError(TimeoutException(
'Time limit reached while waiting for position update.',
timeLimit,
));
s.close();
},
);
}

_positionStream = positionStream
.map<Position>((dynamic element) => Position.fromMap(element.cast<String, dynamic>()))
.handleError(
(error) {
if (error is PlatformException) {
error = _handlePlatformException(error);
}
throw error;
},
);
return _positionStream!;
} catch (e) {
return const Stream.empty();
}

_positionStream = positionStream
.map<Position>((dynamic element) =>
Position.fromMap(element.cast<String, dynamic>()))
.handleError(
(error) {
if (error is PlatformException) {
error = _handlePlatformException(error);
}
throw error;
},
);
return _positionStream!;
}

Stream<dynamic> _wrapStream(Stream<dynamic> incoming) {
Expand Down Expand Up @@ -217,14 +211,12 @@ class GeolocatorApple extends GeolocatorPlatform {
}

@override
Future<bool> openAppSettings() async => _methodChannel
.invokeMethod<bool>('openAppSettings')
.then((value) => value ?? false);
Future<bool> openAppSettings() async =>
_methodChannel.invokeMethod<bool>('openAppSettings').then((value) => value ?? false);

@override
Future<bool> openLocationSettings() async => _methodChannel
.invokeMethod<bool>('openLocationSettings')
.then((value) => value ?? false);
Future<bool> openLocationSettings() async =>
_methodChannel.invokeMethod<bool>('openLocationSettings').then((value) => value ?? false);

Exception _handlePlatformException(PlatformException exception) {
switch (exception.code) {
Expand Down
Loading