From b723003d7cbfd3fb17f6446a1591ea6f02416b56 Mon Sep 17 00:00:00 2001 From: Yarden Date: Sun, 6 Oct 2024 21:53:30 +0300 Subject: [PATCH 1/2] init --- .../lib/src/geolocator_android.dart | 116 +++++++++--------- .../lib/src/geolocator_apple.dart | 114 ++++++++--------- 2 files changed, 108 insertions(+), 122 deletions(-) diff --git a/geolocator_android/lib/src/geolocator_android.dart b/geolocator_android/lib/src/geolocator_android.dart index 04c1ced86..ec94d0731 100644 --- a/geolocator_android/lib/src/geolocator_android.dart +++ b/geolocator_android/lib/src/geolocator_android.dart @@ -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'; @@ -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() { @@ -41,8 +39,7 @@ class GeolocatorAndroid extends GeolocatorPlatform { Future 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) { @@ -56,8 +53,7 @@ class GeolocatorAndroid extends GeolocatorPlatform { Future 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) { @@ -68,9 +64,8 @@ class GeolocatorAndroid extends GeolocatorPlatform { } @override - Future isLocationServiceEnabled() async => _methodChannel - .invokeMethod('isLocationServiceEnabled') - .then((value) => value ?? false); + Future isLocationServiceEnabled() async => + _methodChannel.invokeMethod('isLocationServiceEnabled').then((value) => value ?? false); @override Future getLastKnownPosition({ @@ -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) { @@ -94,8 +88,7 @@ class GeolocatorAndroid extends GeolocatorPlatform { @override Future getLocationAccuracy() async { - final int accuracy = - await _methodChannel.invokeMethod('getLocationAccuracy'); + final int accuracy = await _methodChannel.invokeMethod('getLocationAccuracy'); return LocationAccuracyStatus.values[accuracy]; } @@ -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); @@ -162,46 +153,51 @@ class GeolocatorAndroid extends GeolocatorPlatform { return _serviceStatusStream!; } + // Ryde Modification: Added try catch logic @override Stream 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((dynamic element) => AndroidPosition.fromMap(element.cast())) + .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((dynamic element) => - AndroidPosition.fromMap(element.cast())) - .handleError( - (error) { - if (error is PlatformException) { - error = _handlePlatformException(error); - } - throw error; - }, - ); - return _positionStream!; } Stream _wrapStream(Stream incoming) { @@ -230,14 +226,12 @@ class GeolocatorAndroid extends GeolocatorPlatform { } @override - Future openAppSettings() async => _methodChannel - .invokeMethod('openAppSettings') - .then((value) => value ?? false); + Future openAppSettings() async => + _methodChannel.invokeMethod('openAppSettings').then((value) => value ?? false); @override - Future openLocationSettings() async => _methodChannel - .invokeMethod('openLocationSettings') - .then((value) => value ?? false); + Future openLocationSettings() async => + _methodChannel.invokeMethod('openLocationSettings').then((value) => value ?? false); Exception _handlePlatformException(PlatformException exception) { switch (exception.code) { diff --git a/geolocator_apple/lib/src/geolocator_apple.dart b/geolocator_apple/lib/src/geolocator_apple.dart index 8475bdd2d..07c395db7 100644 --- a/geolocator_apple/lib/src/geolocator_apple.dart +++ b/geolocator_apple/lib/src/geolocator_apple.dart @@ -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() { @@ -38,8 +35,7 @@ class GeolocatorApple extends GeolocatorPlatform { Future 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) { @@ -53,8 +49,7 @@ class GeolocatorApple extends GeolocatorPlatform { Future 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) { @@ -65,9 +60,8 @@ class GeolocatorApple extends GeolocatorPlatform { } @override - Future isLocationServiceEnabled() async => _methodChannel - .invokeMethod('isLocationServiceEnabled') - .then((value) => value ?? false); + Future isLocationServiceEnabled() async => + _methodChannel.invokeMethod('isLocationServiceEnabled').then((value) => value ?? false); @override Future getLastKnownPosition({ @@ -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) { @@ -91,8 +84,7 @@ class GeolocatorApple extends GeolocatorPlatform { @override Future getLocationAccuracy() async { - final int accuracy = - await _methodChannel.invokeMethod('getLocationAccuracy'); + final int accuracy = await _methodChannel.invokeMethod('getLocationAccuracy'); return LocationAccuracyStatus.values[accuracy]; } @@ -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); @@ -149,46 +139,50 @@ class GeolocatorApple extends GeolocatorPlatform { return _serviceStatusStream!; } + // Ryde Modification: added try catch @override Stream 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((dynamic element) => Position.fromMap(element.cast())) + .handleError( + (error) { + if (error is PlatformException) { + error = _handlePlatformException(error); + } + throw error; }, ); + return _positionStream!; + } catch (e) { + return const Stream.empty(); } - - _positionStream = positionStream - .map((dynamic element) => - Position.fromMap(element.cast())) - .handleError( - (error) { - if (error is PlatformException) { - error = _handlePlatformException(error); - } - throw error; - }, - ); - return _positionStream!; } Stream _wrapStream(Stream incoming) { @@ -217,14 +211,12 @@ class GeolocatorApple extends GeolocatorPlatform { } @override - Future openAppSettings() async => _methodChannel - .invokeMethod('openAppSettings') - .then((value) => value ?? false); + Future openAppSettings() async => + _methodChannel.invokeMethod('openAppSettings').then((value) => value ?? false); @override - Future openLocationSettings() async => _methodChannel - .invokeMethod('openLocationSettings') - .then((value) => value ?? false); + Future openLocationSettings() async => + _methodChannel.invokeMethod('openLocationSettings').then((value) => value ?? false); Exception _handlePlatformException(PlatformException exception) { switch (exception.code) { From 6cb7b884665601e4e2cf7f0705876e020355d127 Mon Sep 17 00:00:00 2001 From: Yarden Date: Sun, 2 Feb 2025 15:41:16 +0200 Subject: [PATCH 2/2] init --- geolocator_apple/example/lib/main.dart | 130 +++++++++--------- .../lib/src/geolocator_apple.dart | 4 +- 2 files changed, 66 insertions(+), 68 deletions(-) diff --git a/geolocator_apple/example/lib/main.dart b/geolocator_apple/example/lib/main.dart index 442e0b2c5..fc04e9d2a 100644 --- a/geolocator_apple/example/lib/main.dart +++ b/geolocator_apple/example/lib/main.dart @@ -2,14 +2,13 @@ import 'dart:async'; import 'dart:io' show Platform; import 'package:baseflow_plugin_template/baseflow_plugin_template.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:geolocator_apple/geolocator_apple.dart'; import 'package:geolocator_platform_interface/geolocator_platform_interface.dart'; /// Defines the main theme color. -final MaterialColor themeMaterialColor = - BaseflowPluginExample.createMaterialColor( - const Color.fromRGBO(48, 49, 60, 1)); +final MaterialColor themeMaterialColor = BaseflowPluginExample.createMaterialColor(const Color.fromRGBO(48, 49, 60, 1)); void main() { runApp(const GeolocatorWidget()); @@ -22,8 +21,7 @@ class GeolocatorWidget extends StatefulWidget { /// Utility method to create a page with the Baseflow templating. static ExamplePage createPage() { - return ExamplePage( - Icons.location_on, (context) => const GeolocatorWidget()); + return ExamplePage(Icons.location_on, (context) => const GeolocatorWidget()); } @override @@ -31,11 +29,9 @@ class GeolocatorWidget extends StatefulWidget { } class _GeolocatorWidgetState extends State { - static const String _kLocationServicesDisabledMessage = - 'Location services are disabled.'; + static const String _kLocationServicesDisabledMessage = 'Location services are disabled.'; static const String _kPermissionDeniedMessage = 'Permission denied.'; - static const String _kPermissionDeniedForeverMessage = - 'Permission denied forever.'; + static const String _kPermissionDeniedForeverMessage = 'Permission denied forever.'; static const String _kPermissionGrantedMessage = 'Permission granted.'; final GeolocatorPlatform geolocatorApple = GeolocatorPlatform.instance; @@ -158,8 +154,7 @@ class _GeolocatorWidgetState extends State { ? 'Resume' : 'Pause', backgroundColor: _determineButtonColor(), - child: (_positionStreamSubscription == null || - _positionStreamSubscription!.isPaused) + child: (_positionStreamSubscription == null || _positionStreamSubscription!.isPaused) ? const Icon(Icons.play_arrow) : const Icon(Icons.pause), ), @@ -259,8 +254,7 @@ class _GeolocatorWidgetState extends State { setState(() {}); } - bool _isListening() => !(_positionStreamSubscription == null || - _positionStreamSubscription!.isPaused); + bool _isListening() => !(_positionStreamSubscription == null || _positionStreamSubscription!.isPaused); Color _determineButtonColor() { return _isListening() ? Colors.green : Colors.red; @@ -269,8 +263,7 @@ class _GeolocatorWidgetState extends State { void _toggleServiceStatusStream() { if (_serviceStatusStreamSubscription == null) { final serviceStatusStream = geolocatorApple.getServiceStatusStream(); - _serviceStatusStreamSubscription = - serviceStatusStream.handleError((error) { + _serviceStatusStreamSubscription = serviceStatusStream.handleError((error) { _serviceStatusStreamSubscription?.cancel(); _serviceStatusStreamSubscription = null; }).listen((serviceStatus) { @@ -289,61 +282,66 @@ class _GeolocatorWidgetState extends State { } Future _toggleListening() async { - final hasPermission = await _handlePermission(); + try { + final hasPermission = await _handlePermission(); - if (!hasPermission) { - return; - } + if (!hasPermission) { + return; + } - Exception? error; - - if (_positionStreamSubscription == null) { - final Stream positionStream = geolocatorApple.getPositionStream( - locationSettings: AppleSettings( - accuracy: LocationAccuracy.best, - distanceFilter: 10, - activityType: ActivityType.other, - // Only set showBackgroundLocationIndicator and - // allowBackgroundLocationUpdates to true if our app will be started up - // in the background. - showBackgroundLocationIndicator: false, - allowBackgroundLocationUpdates: false, - )); - _positionStreamSubscription = positionStream.handleError((e) { - _positionStreamSubscription?.cancel(); - _positionStreamSubscription = null; - error = e; - }).listen((position) => _updatePositionList( - _PositionItemType.position, - position.toString(), - )); - _positionStreamSubscription?.pause(); - } + Exception? error; - setState(() { if (_positionStreamSubscription == null) { - return; + final positionStream = geolocatorApple.getPositionStream( + locationSettings: AppleSettings( + accuracy: LocationAccuracy.best, + distanceFilter: 10, + activityType: ActivityType.other, + // Only set showBackgroundLocationIndicator and + // allowBackgroundLocationUpdates to true if our app will be started up + // in the background. + showBackgroundLocationIndicator: false, + allowBackgroundLocationUpdates: false, + )); + if (await positionStream.isEmpty) return; + _positionStreamSubscription = positionStream.handleError((e) { + _positionStreamSubscription?.cancel(); + _positionStreamSubscription = null; + error = e; + }).listen((position) => _updatePositionList( + _PositionItemType.position, + position.toString(), + )); + _positionStreamSubscription?.pause(); } - if (error != null) { - _updatePositionList(_PositionItemType.log, error.toString()); - return; - } + setState(() { + if (_positionStreamSubscription == null) { + return; + } - String statusDisplayValue; - if (_positionStreamSubscription!.isPaused) { - _positionStreamSubscription!.resume(); - statusDisplayValue = 'resumed'; - } else { - _positionStreamSubscription!.pause(); - statusDisplayValue = 'paused'; - } + if (error != null) { + _updatePositionList(_PositionItemType.log, error.toString()); + return; + } - _updatePositionList( - _PositionItemType.log, - 'Listening for position updates $statusDisplayValue', - ); - }); + String statusDisplayValue; + if (_positionStreamSubscription!.isPaused) { + _positionStreamSubscription!.resume(); + statusDisplayValue = 'resumed'; + } else { + _positionStreamSubscription!.pause(); + statusDisplayValue = 'paused'; + } + + _updatePositionList( + _PositionItemType.log, + 'Listening for position updates $statusDisplayValue', + ); + }); + } catch (e) { + if (kDebugMode) print(e); + } } @override @@ -372,11 +370,9 @@ class _GeolocatorWidgetState extends State { } Future _isLocationServiceEnabled() async { - final bool isLocationServiceEnabled = - await geolocatorApple.isLocationServiceEnabled(); - final String displayValue = isLocationServiceEnabled - ? 'Location services are enabled.' - : 'Location services are disabled.'; + final bool isLocationServiceEnabled = await geolocatorApple.isLocationServiceEnabled(); + final String displayValue = + isLocationServiceEnabled ? 'Location services are enabled.' : 'Location services are disabled.'; _updatePositionList(_PositionItemType.log, displayValue); } diff --git a/geolocator_apple/lib/src/geolocator_apple.dart b/geolocator_apple/lib/src/geolocator_apple.dart index 07c395db7..2fd853d93 100644 --- a/geolocator_apple/lib/src/geolocator_apple.dart +++ b/geolocator_apple/lib/src/geolocator_apple.dart @@ -187,7 +187,9 @@ class GeolocatorApple extends GeolocatorPlatform { Stream _wrapStream(Stream incoming) { return incoming.asBroadcastStream(onCancel: (subscription) { - subscription.cancel(); + if (!subscription.isPaused) { + subscription.cancel(); + } _positionStream = null; }); }