diff --git a/src/Essentials/samples/Samples/View/GeolocationPage.xaml b/src/Essentials/samples/Samples/View/GeolocationPage.xaml
index c10eeb38c638..67475e119435 100644
--- a/src/Essentials/samples/Samples/View/GeolocationPage.xaml
+++ b/src/Essentials/samples/Samples/View/GeolocationPage.xaml
@@ -27,6 +27,16 @@
IsEnabled="{Binding IsNotBusy}"
HorizontalOptions="FillAndExpand" />
+
+
+
+
+
+
+
+
diff --git a/src/Essentials/samples/Samples/ViewModel/GeolocationViewModel.cs b/src/Essentials/samples/Samples/ViewModel/GeolocationViewModel.cs
index 9a937ee239c6..ed9d3c0275f4 100644
--- a/src/Essentials/samples/Samples/ViewModel/GeolocationViewModel.cs
+++ b/src/Essentials/samples/Samples/ViewModel/GeolocationViewModel.cs
@@ -13,17 +13,25 @@ public class GeolocationViewModel : BaseViewModel
string currentLocation;
int accuracy = (int)GeolocationAccuracy.Default;
CancellationTokenSource cts;
+ string listeningLocation;
+ string listeningLocationStatus;
public GeolocationViewModel()
{
GetLastLocationCommand = new Command(OnGetLastLocation);
GetCurrentLocationCommand = new Command(OnGetCurrentLocation);
+ StartListeningCommand = new Command(OnStartListening);
+ StopListeningCommand = new Command(OnStopListening);
}
public ICommand GetLastLocationCommand { get; }
public ICommand GetCurrentLocationCommand { get; }
+ public ICommand StartListeningCommand { get; }
+
+ public ICommand StopListeningCommand { get; }
+
public string LastLocation
{
get => lastLocation;
@@ -45,6 +53,22 @@ public int Accuracy
set => SetProperty(ref accuracy, value);
}
+ public bool IsListening => Geolocation.IsListeningForeground;
+
+ public bool IsNotListening => !IsListening;
+
+ public string ListeningLocation
+ {
+ get => listeningLocation;
+ set => SetProperty(ref listeningLocation, value);
+ }
+
+ public string ListeningLocationStatus
+ {
+ get => listeningLocationStatus;
+ set => SetProperty(ref listeningLocationStatus, value);
+ }
+
async void OnGetLastLocation()
{
if (IsBusy)
@@ -88,6 +112,53 @@ async void OnGetCurrentLocation()
IsBusy = false;
}
+ async void OnStartListening()
+ {
+ try
+ {
+ Geolocation.LocationChanged += Geolocation_LocationChanged;
+
+ var request = new GeolocationListeningRequest((GeolocationAccuracy)Accuracy);
+
+ var success = await Geolocation.StartListeningForegroundAsync(request);
+
+ ListeningLocationStatus = success
+ ? "Started listening for foreground location updates"
+ : "Couldn't start listening";
+ }
+ catch (Exception ex)
+ {
+ ListeningLocationStatus = FormatLocation(null, ex);
+ }
+
+ OnPropertyChanged(nameof(IsListening));
+ OnPropertyChanged(nameof(IsNotListening));
+ }
+
+ void Geolocation_LocationChanged(object sender, GeolocationLocationChangedEventArgs e)
+ {
+ ListeningLocation = FormatLocation(e.Location);
+ }
+
+ void OnStopListening()
+ {
+ try
+ {
+ Geolocation.LocationChanged -= Geolocation_LocationChanged;
+
+ Geolocation.StopListeningForeground();
+
+ ListeningLocationStatus = "Stopped listening for foreground location updates";
+ }
+ catch (Exception ex)
+ {
+ ListeningLocationStatus = FormatLocation(null, ex);
+ }
+
+ OnPropertyChanged(nameof(IsListening));
+ OnPropertyChanged(nameof(IsNotListening));
+ }
+
string FormatLocation(Location location, Exception ex = null)
{
if (location == null)
@@ -116,6 +187,9 @@ public override void OnDisappearing()
if (cts != null && !cts.IsCancellationRequested)
cts.Cancel();
}
+
+ OnStopListening();
+
base.OnDisappearing();
}
}
diff --git a/src/Essentials/src/Geolocation/Geolocation.android.cs b/src/Essentials/src/Geolocation/Geolocation.android.cs
index f2f8454efd21..b7035227b163 100644
--- a/src/Essentials/src/Geolocation/Geolocation.android.cs
+++ b/src/Essentials/src/Geolocation/Geolocation.android.cs
@@ -18,11 +18,19 @@ partial class GeolocationImplementation : IGeolocation
const long twoMinutes = 120000;
static readonly string[] ignoredProviders = new string[] { LocationManager.PassiveProvider, "local_database" };
+ static ContinuousLocationListener continuousListener;
+ static List listeningProviders;
+
static LocationManager locationManager;
static LocationManager LocationManager =>
locationManager ??= Application.Context.GetSystemService(Context.LocationService) as LocationManager;
+ ///
+ /// Indicates if currently listening to location updates while the app is in foreground.
+ ///
+ public bool IsListeningForeground { get => continuousListener != null; }
+
public async Task GetLastKnownLocationAsync()
{
await Permissions.EnsureGrantedOrRestrictedAsync();
@@ -42,7 +50,7 @@ public async Task GetLastKnownLocationAsync()
public async Task GetLocationAsync(GeolocationRequest request, CancellationToken cancellationToken)
{
- _ = request ?? throw new ArgumentNullException(nameof(request));
+ ArgumentNullException.ThrowIfNull(request);
await Permissions.EnsureGrantedOrRestrictedAsync();
@@ -112,6 +120,101 @@ void RemoveUpdates()
}
}
+ ///
+ /// Starts listening to location updates using the
+ /// event or the event. Events may only sent when
+ /// the app is in the foreground. Requests
+ /// from the user.
+ ///
+ /// Thrown when is .
+ /// Thrown if listening is not supported on this platform.
+ /// Thrown if already listening and returns .
+ /// The listening request parameters to use.
+ /// when listening was started, or when listening couldn't be started.
+ public async Task StartListeningForegroundAsync(GeolocationListeningRequest request)
+ {
+ ArgumentNullException.ThrowIfNull(request);
+
+ if (IsListeningForeground)
+ throw new InvalidOperationException("Already listening to location changes.");
+
+ await Permissions.EnsureGrantedOrRestrictedAsync();
+
+ var enabledProviders = LocationManager.GetProviders(true);
+ var hasProviders = enabledProviders.Any(p => !ignoredProviders.Contains(p));
+
+ if (!hasProviders)
+ throw new FeatureNotEnabledException("Location services are not enabled on device.");
+
+ // get the best possible provider for the requested accuracy
+ var providerInfo = GetBestProvider(LocationManager, request.DesiredAccuracy);
+
+ // if no providers exist, we can't listen for locations
+ if (string.IsNullOrEmpty(providerInfo.Provider))
+ return false;
+
+ var allProviders = LocationManager.GetProviders(false);
+
+ listeningProviders = new List();
+ if (allProviders.Contains(Android.Locations.LocationManager.GpsProvider))
+ listeningProviders.Add(Android.Locations.LocationManager.GpsProvider);
+ if (allProviders.Contains(Android.Locations.LocationManager.NetworkProvider))
+ listeningProviders.Add(Android.Locations.LocationManager.NetworkProvider);
+
+ if (listeningProviders.Count == 0)
+ listeningProviders.Add(providerInfo.Provider);
+
+ var continuousListener = new ContinuousLocationListener(LocationManager, providerInfo.Accuracy, listeningProviders);
+ continuousListener.LocationHandler = HandleLocation;
+ continuousListener.ErrorHandler = HandleError;
+
+ // start getting location updates
+ // make sure to use a thread with a looper
+ var looper = Looper.MyLooper() ?? Looper.MainLooper;
+
+ var minTimeMilliseconds = (long)request.MinimumTime.TotalMilliseconds;
+
+ foreach (var provider in listeningProviders)
+ LocationManager.RequestLocationUpdates(provider, minTimeMilliseconds, providerInfo.Accuracy, continuousListener, looper);
+
+ return true;
+
+ void HandleLocation(AndroidLocation location)
+ {
+ OnLocationChanged(location.ToLocation());
+ }
+
+ void HandleError(GeolocationError geolocationError)
+ {
+ StopListeningForeground();
+ OnLocationError(geolocationError);
+ }
+ }
+
+ ///
+ /// Stop listening for location updates when the app is in the foreground.
+ /// Has no effect when not listening and
+ /// is currently .
+ ///
+ public void StopListeningForeground()
+ {
+ if (continuousListener == null)
+ return;
+
+ continuousListener.LocationHandler = null;
+ continuousListener.ErrorHandler = null;
+
+ if (listeningProviders == null)
+ return;
+
+ for (var i = 0; i < listeningProviders.Count; i++)
+ {
+ LocationManager.RemoveUpdates(continuousListener);
+ }
+
+ continuousListener = null;
+ }
+
static (string Provider, float Accuracy) GetBestProvider(LocationManager locationManager, GeolocationAccuracy accuracy)
{
// Criteria: https://developer.android.com/reference/android/location/Criteria
@@ -276,4 +379,68 @@ void ILocationListener.OnStatusChanged(string provider, Availability status, Bun
}
}
}
+
+ class ContinuousLocationListener : Java.Lang.Object, ILocationListener
+ {
+ readonly LocationManager manager;
+
+ float desiredAccuracy;
+
+ HashSet activeProviders = new HashSet();
+
+ internal Action LocationHandler { get; set; }
+
+ internal Action ErrorHandler { get; set; }
+
+ internal ContinuousLocationListener(LocationManager manager, float desiredAccuracy, IEnumerable providers)
+ {
+ this.manager = manager;
+ this.desiredAccuracy = desiredAccuracy;
+
+ foreach (var provider in providers)
+ {
+ if (manager.IsProviderEnabled(provider))
+ activeProviders.Add(provider);
+ }
+ }
+
+ void ILocationListener.OnLocationChanged(AndroidLocation location)
+ {
+ if (location.Accuracy <= desiredAccuracy)
+ {
+ LocationHandler?.Invoke(location);
+ return;
+ }
+ }
+
+ void ILocationListener.OnProviderDisabled(string provider)
+ {
+ lock (activeProviders)
+ {
+ if (activeProviders.Remove(provider) &&
+ activeProviders.Count == 0)
+ ErrorHandler?.Invoke(GeolocationError.PositionUnavailable);
+ }
+ }
+
+ void ILocationListener.OnProviderEnabled(string provider)
+ {
+ lock (activeProviders)
+ activeProviders.Add(provider);
+ }
+
+ void ILocationListener.OnStatusChanged(string provider, Availability status, Bundle extras)
+ {
+ switch (status)
+ {
+ case Availability.Available:
+ ((ILocationListener)this).OnProviderEnabled(provider);
+ break;
+
+ case Availability.OutOfService:
+ ((ILocationListener)this).OnProviderDisabled(provider);
+ break;
+ }
+ }
+ }
}
diff --git a/src/Essentials/src/Geolocation/Geolocation.ios.macos.cs b/src/Essentials/src/Geolocation/Geolocation.ios.macos.cs
index 3a7ea40794bd..e2c93bace244 100644
--- a/src/Essentials/src/Geolocation/Geolocation.ios.macos.cs
+++ b/src/Essentials/src/Geolocation/Geolocation.ios.macos.cs
@@ -3,12 +3,20 @@
using System.Threading;
using System.Threading.Tasks;
using CoreLocation;
+using Foundation;
using Microsoft.Maui.ApplicationModel;
namespace Microsoft.Maui.Devices.Sensors
{
partial class GeolocationImplementation : IGeolocation
{
+ CLLocationManager listeningManager;
+
+ ///
+ /// Indicates if currently listening to location updates while the app is in foreground.
+ ///
+ public bool IsListeningForeground { get => listeningManager != null; }
+
public async Task GetLastKnownLocationAsync()
{
if (!CLLocationManager.LocationServicesEnabled)
@@ -31,7 +39,7 @@ public async Task GetLastKnownLocationAsync()
public async Task GetLocationAsync(GeolocationRequest request, CancellationToken cancellationToken)
{
- _ = request ?? throw new ArgumentNullException(nameof(request));
+ ArgumentNullException.ThrowIfNull(request);
if (!CLLocationManager.LocationServicesEnabled)
throw new FeatureNotEnabledException("Location services are not enabled on device.");
@@ -91,6 +99,94 @@ void Cancel()
tcs.TrySetResult(null);
}
}
+
+ ///
+ /// Starts listening to location updates using the
+ /// event or the event. Events may only sent when
+ /// the app is in the foreground. Requests
+ /// from the user.
+ ///
+ /// Thrown when is .
+ /// Thrown if listening is not supported on this platform.
+ /// Thrown if already listening and returns .
+ /// The listening request parameters to use.
+ /// when listening was started, or when listening couldn't be started.
+ public async Task StartListeningForegroundAsync(GeolocationListeningRequest request)
+ {
+ ArgumentNullException.ThrowIfNull(request);
+
+ if (IsListeningForeground)
+ throw new InvalidOperationException("Already listening to location changes.");
+
+ if (!CLLocationManager.LocationServicesEnabled)
+ throw new FeatureNotEnabledException("Location services are not enabled on device.");
+
+ await Permissions.EnsureGrantedAsync();
+
+ // the location manager requires an active run loop
+ // so just use the main loop
+ listeningManager = MainThread.InvokeOnMainThread(() => new CLLocationManager());
+
+ var reducedAccuracy = false;
+#if __IOS__
+ if (OperatingSystem.IsIOSVersionAtLeast(14, 0))
+ {
+ reducedAccuracy = listeningManager.AccuracyAuthorization == CLAccuracyAuthorization.ReducedAccuracy;
+ }
+#endif
+
+ var listener = new ContinuousLocationListener();
+ listener.LocationHandler += HandleLocation;
+ listener.ErrorHandler += HandleError;
+
+ listeningManager.DesiredAccuracy = request.PlatformDesiredAccuracy;
+ listeningManager.Delegate = listener;
+
+#if __IOS__
+#pragma warning disable CA1416 // https://github.com/xamarin/xamarin-macios/issues/14619
+ // allow pausing updates
+ listeningManager.PausesLocationUpdatesAutomatically = true;
+#pragma warning restore CA1416
+#endif
+
+ listeningManager.StartUpdatingLocation();
+
+ return true;
+
+ void HandleLocation(CLLocation clLocation)
+ {
+ OnLocationChanged(clLocation?.ToLocation(reducedAccuracy));
+ }
+
+ void HandleError(GeolocationError error)
+ {
+ StopListeningForeground();
+ OnLocationError(error);
+ }
+ }
+
+ ///
+ /// Stop listening for location updates when the app is in the foreground.
+ /// Has no effect when not listening and
+ /// is currently .
+ ///
+ public void StopListeningForeground()
+ {
+ if (!IsListeningForeground)
+ return;
+
+ listeningManager.StopUpdatingLocation();
+
+ if (listeningManager.Delegate is ContinuousLocationListener listener)
+ {
+ listener.LocationHandler = null;
+ listener.ErrorHandler = null;
+ }
+
+ listeningManager.Delegate = null;
+
+ listeningManager = null;
+ }
}
class SingleLocationListener : CLLocationManagerDelegate
@@ -99,6 +195,7 @@ class SingleLocationListener : CLLocationManagerDelegate
internal Action LocationHandler { get; set; }
+ ///
public override void LocationsUpdated(CLLocationManager manager, CLLocation[] locations)
{
if (wasRaised)
@@ -114,6 +211,43 @@ public override void LocationsUpdated(CLLocationManager manager, CLLocation[] lo
LocationHandler?.Invoke(location);
}
+ ///
+ public override bool ShouldDisplayHeadingCalibration(CLLocationManager manager) => false;
+ }
+
+ class ContinuousLocationListener : CLLocationManagerDelegate
+ {
+ internal Action LocationHandler { get; set; }
+
+ internal Action ErrorHandler { get; set; }
+
+ ///
+ public override void LocationsUpdated(CLLocationManager manager, CLLocation[] locations)
+ {
+ var location = locations?.LastOrDefault();
+
+ if (location == null)
+ return;
+
+ LocationHandler?.Invoke(location);
+ }
+
+ ///
+ public override void Failed(CLLocationManager manager, NSError error)
+ {
+ if ((CLError)error.Code == CLError.Network)
+ ErrorHandler?.Invoke(GeolocationError.PositionUnavailable);
+ }
+
+ ///
+ public override void AuthorizationChanged(CLLocationManager manager, CLAuthorizationStatus status)
+ {
+ if (status == CLAuthorizationStatus.Denied ||
+ status == CLAuthorizationStatus.Restricted)
+ ErrorHandler?.Invoke(GeolocationError.Unauthorized);
+ }
+
+ ///
public override bool ShouldDisplayHeadingCalibration(CLLocationManager manager) => false;
}
}
diff --git a/src/Essentials/src/Geolocation/Geolocation.netstandard.tvos.watchos.cs b/src/Essentials/src/Geolocation/Geolocation.netstandard.tvos.watchos.cs
index 67c10b2ec813..4fc89b6e5a1e 100644
--- a/src/Essentials/src/Geolocation/Geolocation.netstandard.tvos.watchos.cs
+++ b/src/Essentials/src/Geolocation/Geolocation.netstandard.tvos.watchos.cs
@@ -1,3 +1,4 @@
+using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Maui.ApplicationModel;
@@ -11,5 +12,13 @@ public Task GetLastKnownLocationAsync() =>
public Task GetLocationAsync(GeolocationRequest request, CancellationToken cancellationToken) =>
throw ExceptionUtils.NotSupportedOrImplementedException;
+
+ public bool IsListeningForeground { get => false; }
+
+ public Task StartListeningForegroundAsync(GeolocationListeningRequest request) =>
+ throw ExceptionUtils.NotSupportedOrImplementedException;
+
+ public void StopListeningForeground() =>
+ throw ExceptionUtils.NotSupportedOrImplementedException;
}
}
diff --git a/src/Essentials/src/Geolocation/Geolocation.shared.cs b/src/Essentials/src/Geolocation/Geolocation.shared.cs
index 753d13ed5fc0..64809d25cd89 100644
--- a/src/Essentials/src/Geolocation/Geolocation.shared.cs
+++ b/src/Essentials/src/Geolocation/Geolocation.shared.cs
@@ -1,6 +1,8 @@
#nullable enable
+using System;
using System.Threading;
using System.Threading.Tasks;
+using Microsoft.Maui.ApplicationModel;
namespace Microsoft.Maui.Devices.Sensors
{
@@ -27,6 +29,41 @@ public interface IGeolocation
/// The location permissions will be requested at runtime if needed. You might still need to declare something in your app manifest.
/// A object containing current location information or if no location could be determined.
Task GetLocationAsync(GeolocationRequest request, CancellationToken cancelToken);
+
+ ///
+ /// Indicates if currently listening to location updates while the app is in foreground.
+ ///
+ bool IsListeningForeground { get; }
+
+ ///
+ /// Occurs while listening to location updates.
+ ///
+ event EventHandler? LocationChanged;
+
+ ///
+ /// Occurs when an error during listening for location updates arises. When the event is
+ /// fired, listening for further location updates has been stopped and no further
+ /// events are sent.
+ ///
+ event EventHandler? ListeningFailed;
+
+ ///
+ /// Starts listening to location updates using the event. Events
+ /// may only sent when the app is in the foreground. Requests
+ /// from the user.
+ ///
+ /// Thrown when is .
+ /// Thrown if listening is not supported on this platform.
+ /// Thrown if already listening and returns .
+ /// The listening request parameters to use.
+ /// when listening was started, or when listening couldn't be started.
+ Task StartListeningForegroundAsync(GeolocationListeningRequest request);
+
+ ///
+ /// Stop listening for location updates when the app is in the foreground.
+ /// Has no effect when is currently .
+ ///
+ void StopListeningForeground();
}
///
@@ -72,6 +109,53 @@ public static partial class Geolocation
public static Task GetLocationAsync(GeolocationRequest request, CancellationToken cancelToken) =>
Current.GetLocationAsync(request, cancelToken);
+ ///
+ /// Indicates if currently listening to location updates while the app is in foreground.
+ ///
+ public static bool IsListeningForeground { get => Current.IsListeningForeground; }
+
+ ///
+ /// Occurs while listening to location updates.
+ ///
+ public static event EventHandler LocationChanged
+ {
+ add => Current.LocationChanged += value;
+ remove => Current.LocationChanged -= value;
+ }
+
+ ///
+ /// Occurs when an error during listening for location updates arises. When the event is
+ /// fired, listening for further location updates has been stopped and no further
+ /// events are sent.
+ ///
+ public static event EventHandler ListeningFailed
+ {
+ add => Current.ListeningFailed += value;
+ remove => Current.ListeningFailed -= value;
+ }
+
+ ///
+ /// Starts listening to location updates using the
+ /// event or the event. Events may only sent when
+ /// the app is in the foreground. Requests
+ /// from the user.
+ ///
+ /// Thrown when is .
+ /// Thrown if listening is not supported on this platform.
+ /// Thrown if already listening and returns .
+ /// The listening request parameters to use.
+ /// when listening was started, or when listening couldn't be started.
+ public static Task StartListeningForegroundAsync(GeolocationListeningRequest request) =>
+ Current.StartListeningForegroundAsync(request);
+
+ ///
+ /// Stop listening for location updates when the app is in the foreground.
+ /// Has no effect when not listening and
+ /// is currently .
+ ///
+ public static void StopListeningForeground() =>
+ Current.StopListeningForeground();
+
static IGeolocation Current => Devices.Sensors.Geolocation.Default;
static IGeolocation? defaultImplementation;
@@ -86,6 +170,22 @@ internal static void SetDefault(IGeolocation? implementation) =>
defaultImplementation = implementation;
}
+ partial class GeolocationImplementation : IGeolocation
+ {
+ public event EventHandler? LocationChanged;
+
+ public event EventHandler? ListeningFailed;
+
+ internal void OnLocationChanged(Location location) =>
+ OnLocationChanged(new GeolocationLocationChangedEventArgs(location));
+
+ internal void OnLocationChanged(GeolocationLocationChangedEventArgs e) =>
+ LocationChanged?.Invoke(null, e);
+
+ internal void OnLocationError(GeolocationError geolocationError) =>
+ ListeningFailed?.Invoke(null, new GeolocationListeningFailedEventArgs(geolocationError));
+ }
+
///
/// Static class with extension methods for the APIs.
///
diff --git a/src/Essentials/src/Geolocation/Geolocation.tizen.cs b/src/Essentials/src/Geolocation/Geolocation.tizen.cs
index 70f601cedbcb..9ed480844860 100644
--- a/src/Essentials/src/Geolocation/Geolocation.tizen.cs
+++ b/src/Essentials/src/Geolocation/Geolocation.tizen.cs
@@ -10,11 +10,13 @@ partial class GeolocationImplementation : IGeolocation
{
Location lastKnownLocation = new Location();
+ public bool IsListeningForeground { get => false; }
+
public Task GetLastKnownLocationAsync() => Task.FromResult(lastKnownLocation);
public async Task GetLocationAsync(GeolocationRequest request, CancellationToken cancellationToken)
{
- _ = request ?? throw new ArgumentNullException(nameof(request));
+ ArgumentNullException.ThrowIfNull(request);
await Permissions.EnsureGrantedAsync();
@@ -67,5 +69,11 @@ public async Task GetLocationAsync(GeolocationRequest request, Cancell
return lastKnownLocation;
}
+
+ public Task StartListeningForegroundAsync(GeolocationListeningRequest request) =>
+ throw ExceptionUtils.NotSupportedOrImplementedException;
+
+ public void StopListeningForeground() =>
+ throw ExceptionUtils.NotSupportedOrImplementedException;
}
}
diff --git a/src/Essentials/src/Geolocation/Geolocation.uwp.cs b/src/Essentials/src/Geolocation/Geolocation.uwp.cs
index ce9778380055..4c80fbd0b200 100644
--- a/src/Essentials/src/Geolocation/Geolocation.uwp.cs
+++ b/src/Essentials/src/Geolocation/Geolocation.uwp.cs
@@ -9,6 +9,13 @@ namespace Microsoft.Maui.Devices.Sensors
{
partial class GeolocationImplementation : IGeolocation
{
+ Geolocator? listeningGeolocator;
+
+ ///
+ /// Indicates if currently listening to location updates while the app is in foreground.
+ ///
+ public bool IsListeningForeground { get => listeningGeolocator != null; }
+
public async Task GetLastKnownLocationAsync()
{
// no need for permissions as AllowFallbackToConsentlessPositions
@@ -27,7 +34,7 @@ partial class GeolocationImplementation : IGeolocation
public async Task GetLocationAsync(GeolocationRequest request, CancellationToken cancellationToken)
{
- _ = request ?? throw new ArgumentNullException(nameof(request));
+ ArgumentNullException.ThrowIfNull(request);
await Permissions.EnsureGrantedAsync();
@@ -43,16 +50,98 @@ partial class GeolocationImplementation : IGeolocation
var location = await geolocator.GetGeopositionAsync().AsTask(cancellationToken);
return location?.Coordinate?.ToLocation();
+ }
- static void CheckStatus(PositionStatus status)
+ static void CheckStatus(PositionStatus status)
+ {
+ switch (status)
{
- switch (status)
- {
- case PositionStatus.Disabled:
- case PositionStatus.NotAvailable:
- throw new FeatureNotEnabledException("Location services are not enabled on device.");
- }
+ case PositionStatus.Disabled:
+ case PositionStatus.NotAvailable:
+ throw new FeatureNotEnabledException("Location services are not enabled on device.");
}
}
+
+ ///
+ /// Starts listening to location updates using the
+ /// event or the event. Events may only sent when
+ /// the app is in the foreground. Requests
+ /// from the user.
+ ///
+ /// Thrown when is .
+ /// Thrown if listening is not supported on this platform.
+ /// Thrown if already listening and returns .
+ /// The listening request parameters to use.
+ /// when listening was started, or when listening couldn't be started.
+ public async Task StartListeningForegroundAsync(GeolocationListeningRequest request)
+ {
+ ArgumentNullException.ThrowIfNull(request);
+
+ if (request.MinimumTime.TotalMilliseconds < 0)
+ throw new ArgumentOutOfRangeException(nameof(request), "MinimumTime must be positive.");
+
+ if (IsListeningForeground)
+ throw new InvalidOperationException("Already listening to location updates.");
+
+ await Permissions.EnsureGrantedAsync();
+
+ listeningGeolocator = new Geolocator
+ {
+ DesiredAccuracyInMeters = request.PlatformDesiredAccuracy,
+ ReportInterval = (uint)request.MinimumTime.TotalMilliseconds,
+ MovementThreshold = request.PlatformDesiredAccuracy,
+ };
+
+ CheckStatus(listeningGeolocator.LocationStatus);
+
+ listeningGeolocator.PositionChanged += OnLocatorPositionChanged;
+ listeningGeolocator.StatusChanged += OnLocatorStatusChanged;
+
+ return true;
+ }
+
+ ///
+ /// Stop listening for location updates when the app is in the foreground.
+ /// Has no effect when not listening and
+ /// is currently .
+ ///
+ public void StopListeningForeground()
+ {
+ if (!IsListeningForeground || listeningGeolocator == null)
+ return;
+
+ listeningGeolocator.PositionChanged -= OnLocatorPositionChanged;
+ listeningGeolocator.StatusChanged -= OnLocatorStatusChanged;
+
+ listeningGeolocator = null;
+ }
+
+ void OnLocatorPositionChanged(Geolocator sender, PositionChangedEventArgs e) =>
+ OnLocationChanged(e.Position.ToLocation());
+
+ void OnLocatorStatusChanged(Geolocator sender, StatusChangedEventArgs e)
+ {
+ if (!IsListeningForeground)
+ return;
+
+ StopListeningForeground();
+
+ GeolocationError error;
+ switch (e.Status)
+ {
+ case PositionStatus.Disabled:
+ error = GeolocationError.Unauthorized;
+ break;
+
+ case PositionStatus.NoData:
+ error = GeolocationError.PositionUnavailable;
+ break;
+
+ default:
+ return;
+ }
+
+ OnLocationError(error);
+ }
}
}
diff --git a/src/Essentials/src/Geolocation/GeolocationAccuracyExtensionMethods.ios.macos.cs b/src/Essentials/src/Geolocation/GeolocationAccuracyExtensionMethods.ios.macos.cs
new file mode 100644
index 000000000000..be42c328cf9a
--- /dev/null
+++ b/src/Essentials/src/Geolocation/GeolocationAccuracyExtensionMethods.ios.macos.cs
@@ -0,0 +1,28 @@
+#nullable enable
+using CoreLocation;
+
+namespace Microsoft.Maui.Devices.Sensors
+{
+ static class GeolocationAccuracyExtensionMethods
+ {
+ internal static double PlatformDesiredAccuracy(this GeolocationAccuracy desiredAccuracy)
+ {
+ switch (desiredAccuracy)
+ {
+ case GeolocationAccuracy.Lowest:
+ return CLLocation.AccuracyThreeKilometers;
+ case GeolocationAccuracy.Low:
+ return CLLocation.AccuracyKilometer;
+ case GeolocationAccuracy.Default:
+ case GeolocationAccuracy.Medium:
+ return CLLocation.AccuracyHundredMeters;
+ case GeolocationAccuracy.High:
+ return CLLocation.AccuracyNearestTenMeters;
+ case GeolocationAccuracy.Best:
+ return CLLocation.AccurracyBestForNavigation;
+ default:
+ return CLLocation.AccuracyHundredMeters;
+ }
+ }
+ }
+}
diff --git a/src/Essentials/src/Geolocation/GeolocationAccuracyExtensionMethods.uwp.cs b/src/Essentials/src/Geolocation/GeolocationAccuracyExtensionMethods.uwp.cs
new file mode 100644
index 000000000000..aa5bad7d6e05
--- /dev/null
+++ b/src/Essentials/src/Geolocation/GeolocationAccuracyExtensionMethods.uwp.cs
@@ -0,0 +1,25 @@
+namespace Microsoft.Maui.Devices.Sensors
+{
+ static class GeolocationAccuracyExtensionMethods
+ {
+ internal static uint PlatformGetDesiredAccuracy(this GeolocationAccuracy desiredAccuracy)
+ {
+ switch (desiredAccuracy)
+ {
+ case GeolocationAccuracy.Lowest:
+ return 3000;
+ case GeolocationAccuracy.Low:
+ return 1000;
+ case GeolocationAccuracy.Default:
+ case GeolocationAccuracy.Medium:
+ return 100;
+ case GeolocationAccuracy.High:
+ return 10; // Equivalent to PositionAccuracy.High
+ case GeolocationAccuracy.Best:
+ return 1;
+ default:
+ return 500; // Equivalent to PositionAccuracy.Default
+ }
+ }
+ }
+}
diff --git a/src/Essentials/src/Geolocation/GeolocationError.shared.cs b/src/Essentials/src/Geolocation/GeolocationError.shared.cs
new file mode 100644
index 000000000000..5008f4660953
--- /dev/null
+++ b/src/Essentials/src/Geolocation/GeolocationError.shared.cs
@@ -0,0 +1,30 @@
+#nullable enable
+
+namespace Microsoft.Maui.Devices.Sensors
+{
+ ///
+ /// Error values for listening for geolocation changes
+ ///
+ public enum GeolocationError
+ {
+ ///
+ /// The provider was unable to retrieve any position data.
+ ///
+ ///
+ /// Android: Sent when no location provider is available that satisfies the requested geolocation accuracy.
+ /// iOS: Getting location data has failed.
+ /// Windows: No location data is available from any source.
+ ///
+ PositionUnavailable,
+
+ ///
+ /// The app is not, or no longer, authorized to receive location data.
+ ///
+ ///
+ /// Android: Not used.
+ /// iOS: Authorization for getting locations has changed.
+ /// Windows: Location sources are turned off.
+ ///
+ Unauthorized,
+ }
+}
\ No newline at end of file
diff --git a/src/Essentials/src/Geolocation/GeolocationListeningFailedEventArgs.shared.cs b/src/Essentials/src/Geolocation/GeolocationListeningFailedEventArgs.shared.cs
new file mode 100644
index 000000000000..f32ca843d6c3
--- /dev/null
+++ b/src/Essentials/src/Geolocation/GeolocationListeningFailedEventArgs.shared.cs
@@ -0,0 +1,25 @@
+#nullable enable
+using System;
+
+namespace Microsoft.Maui.Devices.Sensors
+{
+ ///
+ /// Event args for the geolocation listening error event.
+ ///
+ public class GeolocationListeningFailedEventArgs : EventArgs
+ {
+ ///
+ /// The geolocation error that describes the error that occurred.
+ ///
+ public GeolocationError Error { get; }
+
+ ///
+ /// Creates a new geolocation error event args object
+ ///
+ /// gelocation error to use for this object
+ public GeolocationListeningFailedEventArgs(GeolocationError geolocationError)
+ {
+ Error = geolocationError;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Essentials/src/Geolocation/GeolocationListeningRequest.ios.macos.cs b/src/Essentials/src/Geolocation/GeolocationListeningRequest.ios.macos.cs
new file mode 100644
index 000000000000..2bfa09596819
--- /dev/null
+++ b/src/Essentials/src/Geolocation/GeolocationListeningRequest.ios.macos.cs
@@ -0,0 +1,15 @@
+#nullable enable
+
+namespace Microsoft.Maui.Devices.Sensors
+{
+ public partial class GeolocationListeningRequest
+ {
+ internal double PlatformDesiredAccuracy
+ {
+ get
+ {
+ return DesiredAccuracy.PlatformDesiredAccuracy();
+ }
+ }
+ }
+}
diff --git a/src/Essentials/src/Geolocation/GeolocationListeningRequest.shared.cs b/src/Essentials/src/Geolocation/GeolocationListeningRequest.shared.cs
new file mode 100644
index 000000000000..7420ca575551
--- /dev/null
+++ b/src/Essentials/src/Geolocation/GeolocationListeningRequest.shared.cs
@@ -0,0 +1,51 @@
+#nullable enable
+using System;
+
+namespace Microsoft.Maui.Devices.Sensors
+{
+ ///
+ /// Request options for listening to geolocations
+ ///
+ public partial class GeolocationListeningRequest
+ {
+ ///
+ /// Creates a new request object with default values
+ ///
+ public GeolocationListeningRequest()
+ : this(GeolocationAccuracy.Default)
+ {
+ }
+
+ ///
+ /// Creates a new request object with given accuracy.
+ ///
+ /// The desired geolocation accuracy.
+ public GeolocationListeningRequest(GeolocationAccuracy accuracy)
+ : this(accuracy, TimeSpan.FromSeconds(1))
+ {
+ }
+
+ ///
+ /// Creates a new request object with given accuracy and minimum time.
+ ///
+ /// The desired geolocation accuracy.
+ /// The minimum time between location updates being sent.
+ public GeolocationListeningRequest(GeolocationAccuracy accuracy, TimeSpan minimumTime)
+ {
+ DesiredAccuracy = accuracy;
+ MinimumTime = minimumTime;
+ }
+
+ ///
+ /// Minimum time between location updates being sent. This value must positive. Most location
+ /// sensors may not return locations in intervals shorter than 1 second.
+ ///
+ public TimeSpan MinimumTime { get; set; } = TimeSpan.FromSeconds(1);
+
+ ///
+ /// The desired minimum accuracy for the location updates being sent. Locations that don't
+ /// satisfy this accuracy are not sent using the event handler.
+ ///
+ public GeolocationAccuracy DesiredAccuracy { get; set; } = GeolocationAccuracy.Default;
+ }
+}
diff --git a/src/Essentials/src/Geolocation/GeolocationListeningRequest.uwp.cs b/src/Essentials/src/Geolocation/GeolocationListeningRequest.uwp.cs
new file mode 100644
index 000000000000..d6b276d792e1
--- /dev/null
+++ b/src/Essentials/src/Geolocation/GeolocationListeningRequest.uwp.cs
@@ -0,0 +1,15 @@
+#nullable enable
+
+namespace Microsoft.Maui.Devices.Sensors
+{
+ public partial class GeolocationListeningRequest
+ {
+ internal uint PlatformDesiredAccuracy
+ {
+ get
+ {
+ return DesiredAccuracy.PlatformGetDesiredAccuracy();
+ }
+ }
+ }
+}
diff --git a/src/Essentials/src/Geolocation/GeolocationLocationChangedEventArgs.shared.cs b/src/Essentials/src/Geolocation/GeolocationLocationChangedEventArgs.shared.cs
new file mode 100644
index 000000000000..4cb3f8bb6f06
--- /dev/null
+++ b/src/Essentials/src/Geolocation/GeolocationLocationChangedEventArgs.shared.cs
@@ -0,0 +1,18 @@
+#nullable enable
+using System;
+
+namespace Microsoft.Maui.Devices.Sensors
+{
+ public class GeolocationLocationChangedEventArgs : EventArgs
+ {
+ public Location Location { get; }
+
+ public GeolocationLocationChangedEventArgs(Location location)
+ {
+ if (location == null)
+ throw new ArgumentNullException(nameof(location));
+
+ Location = location;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Essentials/src/Geolocation/GeolocationRequest.ios.macos.cs b/src/Essentials/src/Geolocation/GeolocationRequest.ios.macos.cs
index a6a96532e782..616cffec59a9 100644
--- a/src/Essentials/src/Geolocation/GeolocationRequest.ios.macos.cs
+++ b/src/Essentials/src/Geolocation/GeolocationRequest.ios.macos.cs
@@ -1,7 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-using CoreLocation;
+#nullable enable
namespace Microsoft.Maui.Devices.Sensors
{
@@ -11,22 +8,7 @@ internal double PlatformDesiredAccuracy
{
get
{
- switch (DesiredAccuracy)
- {
- case GeolocationAccuracy.Lowest:
- return CLLocation.AccuracyThreeKilometers;
- case GeolocationAccuracy.Low:
- return CLLocation.AccuracyKilometer;
- case GeolocationAccuracy.Default:
- case GeolocationAccuracy.Medium:
- return CLLocation.AccuracyHundredMeters;
- case GeolocationAccuracy.High:
- return CLLocation.AccuracyNearestTenMeters;
- case GeolocationAccuracy.Best:
- return CLLocation.AccurracyBestForNavigation;
- default:
- return CLLocation.AccuracyHundredMeters;
- }
+ return DesiredAccuracy.PlatformDesiredAccuracy();
}
}
}
diff --git a/src/Essentials/src/Geolocation/GeolocationRequest.uwp.cs b/src/Essentials/src/Geolocation/GeolocationRequest.uwp.cs
index f4670c35d0b2..c35c2605fad3 100644
--- a/src/Essentials/src/Geolocation/GeolocationRequest.uwp.cs
+++ b/src/Essentials/src/Geolocation/GeolocationRequest.uwp.cs
@@ -1,7 +1,3 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-
namespace Microsoft.Maui.Devices.Sensors
{
public partial class GeolocationRequest
@@ -10,22 +6,7 @@ internal uint PlatformDesiredAccuracy
{
get
{
- switch (DesiredAccuracy)
- {
- case GeolocationAccuracy.Lowest:
- return 3000;
- case GeolocationAccuracy.Low:
- return 1000;
- case GeolocationAccuracy.Default:
- case GeolocationAccuracy.Medium:
- return 100;
- case GeolocationAccuracy.High:
- return 10; // Equivalent to PositionAccuracy.High
- case GeolocationAccuracy.Best:
- return 1;
- default:
- return 500; // Equivalent to PositionAccuracy.Default
- }
+ return DesiredAccuracy.PlatformGetDesiredAccuracy();
}
}
}
diff --git a/src/Essentials/src/PublicAPI/net-android/PublicAPI.Unshipped.txt b/src/Essentials/src/PublicAPI/net-android/PublicAPI.Unshipped.txt
index 59a09cb0ab11..c64aedf4601a 100644
--- a/src/Essentials/src/PublicAPI/net-android/PublicAPI.Unshipped.txt
+++ b/src/Essentials/src/PublicAPI/net-android/PublicAPI.Unshipped.txt
@@ -7,6 +7,33 @@ Microsoft.Maui.Authentication.WebAuthenticatorOptions.ResponseDecoder.set -> voi
~Microsoft.Maui.Authentication.WebAuthenticatorResult.WebAuthenticatorResult(System.Uri uri, Microsoft.Maui.Authentication.IWebAuthenticatorResponseDecoder responseDecoder) -> void
*REMOVED*Microsoft.Maui.Storage.ISecureStorage.GetAsync(string! key) -> System.Threading.Tasks.Task!
*REMOVED*static Microsoft.Maui.Storage.SecureStorage.GetAsync(string! key) -> System.Threading.Tasks.Task!
+Microsoft.Maui.Devices.Sensors.GeolocationError
+Microsoft.Maui.Devices.Sensors.GeolocationError.PositionUnavailable = 0 -> Microsoft.Maui.Devices.Sensors.GeolocationError
+Microsoft.Maui.Devices.Sensors.GeolocationError.Unauthorized = 1 -> Microsoft.Maui.Devices.Sensors.GeolocationError
+Microsoft.Maui.Devices.Sensors.GeolocationListeningFailedEventArgs
+Microsoft.Maui.Devices.Sensors.GeolocationListeningFailedEventArgs.Error.get -> Microsoft.Maui.Devices.Sensors.GeolocationError
+Microsoft.Maui.Devices.Sensors.GeolocationListeningFailedEventArgs.GeolocationListeningFailedEventArgs(Microsoft.Maui.Devices.Sensors.GeolocationError geolocationError) -> void
+Microsoft.Maui.Devices.Sensors.IGeolocation.ListeningFailed -> System.EventHandler?
Microsoft.Maui.Storage.ISecureStorage.GetAsync(string! key) -> System.Threading.Tasks.Task!
+static Microsoft.Maui.Devices.Sensors.Geolocation.ListeningFailed -> System.EventHandler!
static Microsoft.Maui.Storage.SecureStorage.GetAsync(string! key) -> System.Threading.Tasks.Task!
-*REMOVED*static Microsoft.Maui.ApplicationModel.Communication.PhoneDialer.Current.get -> Microsoft.Maui.ApplicationModel.Communication.IPhoneDialer!
\ No newline at end of file
+Microsoft.Maui.Devices.Sensors.IGeolocation.IsListeningForeground.get -> bool
+Microsoft.Maui.Devices.Sensors.IGeolocation.LocationChanged -> System.EventHandler?
+Microsoft.Maui.Devices.Sensors.IGeolocation.StartListeningForegroundAsync(Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest! request) -> System.Threading.Tasks.Task!
+Microsoft.Maui.Devices.Sensors.IGeolocation.StopListeningForeground() -> void
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest.DesiredAccuracy.get -> Microsoft.Maui.Devices.Sensors.GeolocationAccuracy
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest.DesiredAccuracy.set -> void
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest.GeolocationListeningRequest() -> void
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest.GeolocationListeningRequest(Microsoft.Maui.Devices.Sensors.GeolocationAccuracy accuracy) -> void
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest.GeolocationListeningRequest(Microsoft.Maui.Devices.Sensors.GeolocationAccuracy accuracy, System.TimeSpan minimumTime) -> void
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest.MinimumTime.get -> System.TimeSpan
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest.MinimumTime.set -> void
+Microsoft.Maui.Devices.Sensors.GeolocationLocationChangedEventArgs
+Microsoft.Maui.Devices.Sensors.GeolocationLocationChangedEventArgs.Location.get -> Microsoft.Maui.Devices.Sensors.Location!
+Microsoft.Maui.Devices.Sensors.GeolocationLocationChangedEventArgs.GeolocationLocationChangedEventArgs(Microsoft.Maui.Devices.Sensors.Location! location) -> void
+static Microsoft.Maui.Devices.Sensors.Geolocation.IsListeningForeground.get -> bool
+static Microsoft.Maui.Devices.Sensors.Geolocation.LocationChanged -> System.EventHandler!
+static Microsoft.Maui.Devices.Sensors.Geolocation.StartListeningForegroundAsync(Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest! request) -> System.Threading.Tasks.Task!
+static Microsoft.Maui.Devices.Sensors.Geolocation.StopListeningForeground() -> void
+*REMOVED*static Microsoft.Maui.ApplicationModel.Communication.PhoneDialer.Current.get -> Microsoft.Maui.ApplicationModel.Communication.IPhoneDialer!
diff --git a/src/Essentials/src/PublicAPI/net-ios/PublicAPI.Unshipped.txt b/src/Essentials/src/PublicAPI/net-ios/PublicAPI.Unshipped.txt
index 59a09cb0ab11..c64aedf4601a 100644
--- a/src/Essentials/src/PublicAPI/net-ios/PublicAPI.Unshipped.txt
+++ b/src/Essentials/src/PublicAPI/net-ios/PublicAPI.Unshipped.txt
@@ -7,6 +7,33 @@ Microsoft.Maui.Authentication.WebAuthenticatorOptions.ResponseDecoder.set -> voi
~Microsoft.Maui.Authentication.WebAuthenticatorResult.WebAuthenticatorResult(System.Uri uri, Microsoft.Maui.Authentication.IWebAuthenticatorResponseDecoder responseDecoder) -> void
*REMOVED*Microsoft.Maui.Storage.ISecureStorage.GetAsync(string! key) -> System.Threading.Tasks.Task!
*REMOVED*static Microsoft.Maui.Storage.SecureStorage.GetAsync(string! key) -> System.Threading.Tasks.Task!
+Microsoft.Maui.Devices.Sensors.GeolocationError
+Microsoft.Maui.Devices.Sensors.GeolocationError.PositionUnavailable = 0 -> Microsoft.Maui.Devices.Sensors.GeolocationError
+Microsoft.Maui.Devices.Sensors.GeolocationError.Unauthorized = 1 -> Microsoft.Maui.Devices.Sensors.GeolocationError
+Microsoft.Maui.Devices.Sensors.GeolocationListeningFailedEventArgs
+Microsoft.Maui.Devices.Sensors.GeolocationListeningFailedEventArgs.Error.get -> Microsoft.Maui.Devices.Sensors.GeolocationError
+Microsoft.Maui.Devices.Sensors.GeolocationListeningFailedEventArgs.GeolocationListeningFailedEventArgs(Microsoft.Maui.Devices.Sensors.GeolocationError geolocationError) -> void
+Microsoft.Maui.Devices.Sensors.IGeolocation.ListeningFailed -> System.EventHandler?
Microsoft.Maui.Storage.ISecureStorage.GetAsync(string! key) -> System.Threading.Tasks.Task!
+static Microsoft.Maui.Devices.Sensors.Geolocation.ListeningFailed -> System.EventHandler!
static Microsoft.Maui.Storage.SecureStorage.GetAsync(string! key) -> System.Threading.Tasks.Task!
-*REMOVED*static Microsoft.Maui.ApplicationModel.Communication.PhoneDialer.Current.get -> Microsoft.Maui.ApplicationModel.Communication.IPhoneDialer!
\ No newline at end of file
+Microsoft.Maui.Devices.Sensors.IGeolocation.IsListeningForeground.get -> bool
+Microsoft.Maui.Devices.Sensors.IGeolocation.LocationChanged -> System.EventHandler?
+Microsoft.Maui.Devices.Sensors.IGeolocation.StartListeningForegroundAsync(Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest! request) -> System.Threading.Tasks.Task!
+Microsoft.Maui.Devices.Sensors.IGeolocation.StopListeningForeground() -> void
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest.DesiredAccuracy.get -> Microsoft.Maui.Devices.Sensors.GeolocationAccuracy
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest.DesiredAccuracy.set -> void
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest.GeolocationListeningRequest() -> void
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest.GeolocationListeningRequest(Microsoft.Maui.Devices.Sensors.GeolocationAccuracy accuracy) -> void
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest.GeolocationListeningRequest(Microsoft.Maui.Devices.Sensors.GeolocationAccuracy accuracy, System.TimeSpan minimumTime) -> void
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest.MinimumTime.get -> System.TimeSpan
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest.MinimumTime.set -> void
+Microsoft.Maui.Devices.Sensors.GeolocationLocationChangedEventArgs
+Microsoft.Maui.Devices.Sensors.GeolocationLocationChangedEventArgs.Location.get -> Microsoft.Maui.Devices.Sensors.Location!
+Microsoft.Maui.Devices.Sensors.GeolocationLocationChangedEventArgs.GeolocationLocationChangedEventArgs(Microsoft.Maui.Devices.Sensors.Location! location) -> void
+static Microsoft.Maui.Devices.Sensors.Geolocation.IsListeningForeground.get -> bool
+static Microsoft.Maui.Devices.Sensors.Geolocation.LocationChanged -> System.EventHandler!
+static Microsoft.Maui.Devices.Sensors.Geolocation.StartListeningForegroundAsync(Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest! request) -> System.Threading.Tasks.Task!
+static Microsoft.Maui.Devices.Sensors.Geolocation.StopListeningForeground() -> void
+*REMOVED*static Microsoft.Maui.ApplicationModel.Communication.PhoneDialer.Current.get -> Microsoft.Maui.ApplicationModel.Communication.IPhoneDialer!
diff --git a/src/Essentials/src/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt b/src/Essentials/src/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt
index 59a09cb0ab11..c64aedf4601a 100644
--- a/src/Essentials/src/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt
+++ b/src/Essentials/src/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt
@@ -7,6 +7,33 @@ Microsoft.Maui.Authentication.WebAuthenticatorOptions.ResponseDecoder.set -> voi
~Microsoft.Maui.Authentication.WebAuthenticatorResult.WebAuthenticatorResult(System.Uri uri, Microsoft.Maui.Authentication.IWebAuthenticatorResponseDecoder responseDecoder) -> void
*REMOVED*Microsoft.Maui.Storage.ISecureStorage.GetAsync(string! key) -> System.Threading.Tasks.Task!
*REMOVED*static Microsoft.Maui.Storage.SecureStorage.GetAsync(string! key) -> System.Threading.Tasks.Task!
+Microsoft.Maui.Devices.Sensors.GeolocationError
+Microsoft.Maui.Devices.Sensors.GeolocationError.PositionUnavailable = 0 -> Microsoft.Maui.Devices.Sensors.GeolocationError
+Microsoft.Maui.Devices.Sensors.GeolocationError.Unauthorized = 1 -> Microsoft.Maui.Devices.Sensors.GeolocationError
+Microsoft.Maui.Devices.Sensors.GeolocationListeningFailedEventArgs
+Microsoft.Maui.Devices.Sensors.GeolocationListeningFailedEventArgs.Error.get -> Microsoft.Maui.Devices.Sensors.GeolocationError
+Microsoft.Maui.Devices.Sensors.GeolocationListeningFailedEventArgs.GeolocationListeningFailedEventArgs(Microsoft.Maui.Devices.Sensors.GeolocationError geolocationError) -> void
+Microsoft.Maui.Devices.Sensors.IGeolocation.ListeningFailed -> System.EventHandler?
Microsoft.Maui.Storage.ISecureStorage.GetAsync(string! key) -> System.Threading.Tasks.Task!
+static Microsoft.Maui.Devices.Sensors.Geolocation.ListeningFailed -> System.EventHandler!
static Microsoft.Maui.Storage.SecureStorage.GetAsync(string! key) -> System.Threading.Tasks.Task!
-*REMOVED*static Microsoft.Maui.ApplicationModel.Communication.PhoneDialer.Current.get -> Microsoft.Maui.ApplicationModel.Communication.IPhoneDialer!
\ No newline at end of file
+Microsoft.Maui.Devices.Sensors.IGeolocation.IsListeningForeground.get -> bool
+Microsoft.Maui.Devices.Sensors.IGeolocation.LocationChanged -> System.EventHandler?
+Microsoft.Maui.Devices.Sensors.IGeolocation.StartListeningForegroundAsync(Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest! request) -> System.Threading.Tasks.Task!
+Microsoft.Maui.Devices.Sensors.IGeolocation.StopListeningForeground() -> void
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest.DesiredAccuracy.get -> Microsoft.Maui.Devices.Sensors.GeolocationAccuracy
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest.DesiredAccuracy.set -> void
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest.GeolocationListeningRequest() -> void
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest.GeolocationListeningRequest(Microsoft.Maui.Devices.Sensors.GeolocationAccuracy accuracy) -> void
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest.GeolocationListeningRequest(Microsoft.Maui.Devices.Sensors.GeolocationAccuracy accuracy, System.TimeSpan minimumTime) -> void
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest.MinimumTime.get -> System.TimeSpan
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest.MinimumTime.set -> void
+Microsoft.Maui.Devices.Sensors.GeolocationLocationChangedEventArgs
+Microsoft.Maui.Devices.Sensors.GeolocationLocationChangedEventArgs.Location.get -> Microsoft.Maui.Devices.Sensors.Location!
+Microsoft.Maui.Devices.Sensors.GeolocationLocationChangedEventArgs.GeolocationLocationChangedEventArgs(Microsoft.Maui.Devices.Sensors.Location! location) -> void
+static Microsoft.Maui.Devices.Sensors.Geolocation.IsListeningForeground.get -> bool
+static Microsoft.Maui.Devices.Sensors.Geolocation.LocationChanged -> System.EventHandler!
+static Microsoft.Maui.Devices.Sensors.Geolocation.StartListeningForegroundAsync(Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest! request) -> System.Threading.Tasks.Task!
+static Microsoft.Maui.Devices.Sensors.Geolocation.StopListeningForeground() -> void
+*REMOVED*static Microsoft.Maui.ApplicationModel.Communication.PhoneDialer.Current.get -> Microsoft.Maui.ApplicationModel.Communication.IPhoneDialer!
diff --git a/src/Essentials/src/PublicAPI/net-tizen/PublicAPI.Unshipped.txt b/src/Essentials/src/PublicAPI/net-tizen/PublicAPI.Unshipped.txt
index 59a09cb0ab11..c64aedf4601a 100644
--- a/src/Essentials/src/PublicAPI/net-tizen/PublicAPI.Unshipped.txt
+++ b/src/Essentials/src/PublicAPI/net-tizen/PublicAPI.Unshipped.txt
@@ -7,6 +7,33 @@ Microsoft.Maui.Authentication.WebAuthenticatorOptions.ResponseDecoder.set -> voi
~Microsoft.Maui.Authentication.WebAuthenticatorResult.WebAuthenticatorResult(System.Uri uri, Microsoft.Maui.Authentication.IWebAuthenticatorResponseDecoder responseDecoder) -> void
*REMOVED*Microsoft.Maui.Storage.ISecureStorage.GetAsync(string! key) -> System.Threading.Tasks.Task!
*REMOVED*static Microsoft.Maui.Storage.SecureStorage.GetAsync(string! key) -> System.Threading.Tasks.Task!
+Microsoft.Maui.Devices.Sensors.GeolocationError
+Microsoft.Maui.Devices.Sensors.GeolocationError.PositionUnavailable = 0 -> Microsoft.Maui.Devices.Sensors.GeolocationError
+Microsoft.Maui.Devices.Sensors.GeolocationError.Unauthorized = 1 -> Microsoft.Maui.Devices.Sensors.GeolocationError
+Microsoft.Maui.Devices.Sensors.GeolocationListeningFailedEventArgs
+Microsoft.Maui.Devices.Sensors.GeolocationListeningFailedEventArgs.Error.get -> Microsoft.Maui.Devices.Sensors.GeolocationError
+Microsoft.Maui.Devices.Sensors.GeolocationListeningFailedEventArgs.GeolocationListeningFailedEventArgs(Microsoft.Maui.Devices.Sensors.GeolocationError geolocationError) -> void
+Microsoft.Maui.Devices.Sensors.IGeolocation.ListeningFailed -> System.EventHandler?
Microsoft.Maui.Storage.ISecureStorage.GetAsync(string! key) -> System.Threading.Tasks.Task!
+static Microsoft.Maui.Devices.Sensors.Geolocation.ListeningFailed -> System.EventHandler!
static Microsoft.Maui.Storage.SecureStorage.GetAsync(string! key) -> System.Threading.Tasks.Task!
-*REMOVED*static Microsoft.Maui.ApplicationModel.Communication.PhoneDialer.Current.get -> Microsoft.Maui.ApplicationModel.Communication.IPhoneDialer!
\ No newline at end of file
+Microsoft.Maui.Devices.Sensors.IGeolocation.IsListeningForeground.get -> bool
+Microsoft.Maui.Devices.Sensors.IGeolocation.LocationChanged -> System.EventHandler?
+Microsoft.Maui.Devices.Sensors.IGeolocation.StartListeningForegroundAsync(Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest! request) -> System.Threading.Tasks.Task!
+Microsoft.Maui.Devices.Sensors.IGeolocation.StopListeningForeground() -> void
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest.DesiredAccuracy.get -> Microsoft.Maui.Devices.Sensors.GeolocationAccuracy
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest.DesiredAccuracy.set -> void
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest.GeolocationListeningRequest() -> void
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest.GeolocationListeningRequest(Microsoft.Maui.Devices.Sensors.GeolocationAccuracy accuracy) -> void
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest.GeolocationListeningRequest(Microsoft.Maui.Devices.Sensors.GeolocationAccuracy accuracy, System.TimeSpan minimumTime) -> void
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest.MinimumTime.get -> System.TimeSpan
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest.MinimumTime.set -> void
+Microsoft.Maui.Devices.Sensors.GeolocationLocationChangedEventArgs
+Microsoft.Maui.Devices.Sensors.GeolocationLocationChangedEventArgs.Location.get -> Microsoft.Maui.Devices.Sensors.Location!
+Microsoft.Maui.Devices.Sensors.GeolocationLocationChangedEventArgs.GeolocationLocationChangedEventArgs(Microsoft.Maui.Devices.Sensors.Location! location) -> void
+static Microsoft.Maui.Devices.Sensors.Geolocation.IsListeningForeground.get -> bool
+static Microsoft.Maui.Devices.Sensors.Geolocation.LocationChanged -> System.EventHandler!
+static Microsoft.Maui.Devices.Sensors.Geolocation.StartListeningForegroundAsync(Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest! request) -> System.Threading.Tasks.Task!
+static Microsoft.Maui.Devices.Sensors.Geolocation.StopListeningForeground() -> void
+*REMOVED*static Microsoft.Maui.ApplicationModel.Communication.PhoneDialer.Current.get -> Microsoft.Maui.ApplicationModel.Communication.IPhoneDialer!
diff --git a/src/Essentials/src/PublicAPI/net-windows/PublicAPI.Unshipped.txt b/src/Essentials/src/PublicAPI/net-windows/PublicAPI.Unshipped.txt
index 59a09cb0ab11..c64aedf4601a 100644
--- a/src/Essentials/src/PublicAPI/net-windows/PublicAPI.Unshipped.txt
+++ b/src/Essentials/src/PublicAPI/net-windows/PublicAPI.Unshipped.txt
@@ -7,6 +7,33 @@ Microsoft.Maui.Authentication.WebAuthenticatorOptions.ResponseDecoder.set -> voi
~Microsoft.Maui.Authentication.WebAuthenticatorResult.WebAuthenticatorResult(System.Uri uri, Microsoft.Maui.Authentication.IWebAuthenticatorResponseDecoder responseDecoder) -> void
*REMOVED*Microsoft.Maui.Storage.ISecureStorage.GetAsync(string! key) -> System.Threading.Tasks.Task!
*REMOVED*static Microsoft.Maui.Storage.SecureStorage.GetAsync(string! key) -> System.Threading.Tasks.Task!
+Microsoft.Maui.Devices.Sensors.GeolocationError
+Microsoft.Maui.Devices.Sensors.GeolocationError.PositionUnavailable = 0 -> Microsoft.Maui.Devices.Sensors.GeolocationError
+Microsoft.Maui.Devices.Sensors.GeolocationError.Unauthorized = 1 -> Microsoft.Maui.Devices.Sensors.GeolocationError
+Microsoft.Maui.Devices.Sensors.GeolocationListeningFailedEventArgs
+Microsoft.Maui.Devices.Sensors.GeolocationListeningFailedEventArgs.Error.get -> Microsoft.Maui.Devices.Sensors.GeolocationError
+Microsoft.Maui.Devices.Sensors.GeolocationListeningFailedEventArgs.GeolocationListeningFailedEventArgs(Microsoft.Maui.Devices.Sensors.GeolocationError geolocationError) -> void
+Microsoft.Maui.Devices.Sensors.IGeolocation.ListeningFailed -> System.EventHandler?
Microsoft.Maui.Storage.ISecureStorage.GetAsync(string! key) -> System.Threading.Tasks.Task!
+static Microsoft.Maui.Devices.Sensors.Geolocation.ListeningFailed -> System.EventHandler!
static Microsoft.Maui.Storage.SecureStorage.GetAsync(string! key) -> System.Threading.Tasks.Task!
-*REMOVED*static Microsoft.Maui.ApplicationModel.Communication.PhoneDialer.Current.get -> Microsoft.Maui.ApplicationModel.Communication.IPhoneDialer!
\ No newline at end of file
+Microsoft.Maui.Devices.Sensors.IGeolocation.IsListeningForeground.get -> bool
+Microsoft.Maui.Devices.Sensors.IGeolocation.LocationChanged -> System.EventHandler?
+Microsoft.Maui.Devices.Sensors.IGeolocation.StartListeningForegroundAsync(Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest! request) -> System.Threading.Tasks.Task!
+Microsoft.Maui.Devices.Sensors.IGeolocation.StopListeningForeground() -> void
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest.DesiredAccuracy.get -> Microsoft.Maui.Devices.Sensors.GeolocationAccuracy
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest.DesiredAccuracy.set -> void
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest.GeolocationListeningRequest() -> void
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest.GeolocationListeningRequest(Microsoft.Maui.Devices.Sensors.GeolocationAccuracy accuracy) -> void
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest.GeolocationListeningRequest(Microsoft.Maui.Devices.Sensors.GeolocationAccuracy accuracy, System.TimeSpan minimumTime) -> void
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest.MinimumTime.get -> System.TimeSpan
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest.MinimumTime.set -> void
+Microsoft.Maui.Devices.Sensors.GeolocationLocationChangedEventArgs
+Microsoft.Maui.Devices.Sensors.GeolocationLocationChangedEventArgs.Location.get -> Microsoft.Maui.Devices.Sensors.Location!
+Microsoft.Maui.Devices.Sensors.GeolocationLocationChangedEventArgs.GeolocationLocationChangedEventArgs(Microsoft.Maui.Devices.Sensors.Location! location) -> void
+static Microsoft.Maui.Devices.Sensors.Geolocation.IsListeningForeground.get -> bool
+static Microsoft.Maui.Devices.Sensors.Geolocation.LocationChanged -> System.EventHandler!
+static Microsoft.Maui.Devices.Sensors.Geolocation.StartListeningForegroundAsync(Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest! request) -> System.Threading.Tasks.Task!
+static Microsoft.Maui.Devices.Sensors.Geolocation.StopListeningForeground() -> void
+*REMOVED*static Microsoft.Maui.ApplicationModel.Communication.PhoneDialer.Current.get -> Microsoft.Maui.ApplicationModel.Communication.IPhoneDialer!
diff --git a/src/Essentials/src/PublicAPI/net/PublicAPI.Unshipped.txt b/src/Essentials/src/PublicAPI/net/PublicAPI.Unshipped.txt
index b47dafce2fc3..c64aedf4601a 100644
--- a/src/Essentials/src/PublicAPI/net/PublicAPI.Unshipped.txt
+++ b/src/Essentials/src/PublicAPI/net/PublicAPI.Unshipped.txt
@@ -7,6 +7,33 @@ Microsoft.Maui.Authentication.WebAuthenticatorOptions.ResponseDecoder.set -> voi
~Microsoft.Maui.Authentication.WebAuthenticatorResult.WebAuthenticatorResult(System.Uri uri, Microsoft.Maui.Authentication.IWebAuthenticatorResponseDecoder responseDecoder) -> void
*REMOVED*Microsoft.Maui.Storage.ISecureStorage.GetAsync(string! key) -> System.Threading.Tasks.Task!
*REMOVED*static Microsoft.Maui.Storage.SecureStorage.GetAsync(string! key) -> System.Threading.Tasks.Task!
+Microsoft.Maui.Devices.Sensors.GeolocationError
+Microsoft.Maui.Devices.Sensors.GeolocationError.PositionUnavailable = 0 -> Microsoft.Maui.Devices.Sensors.GeolocationError
+Microsoft.Maui.Devices.Sensors.GeolocationError.Unauthorized = 1 -> Microsoft.Maui.Devices.Sensors.GeolocationError
+Microsoft.Maui.Devices.Sensors.GeolocationListeningFailedEventArgs
+Microsoft.Maui.Devices.Sensors.GeolocationListeningFailedEventArgs.Error.get -> Microsoft.Maui.Devices.Sensors.GeolocationError
+Microsoft.Maui.Devices.Sensors.GeolocationListeningFailedEventArgs.GeolocationListeningFailedEventArgs(Microsoft.Maui.Devices.Sensors.GeolocationError geolocationError) -> void
+Microsoft.Maui.Devices.Sensors.IGeolocation.ListeningFailed -> System.EventHandler?
Microsoft.Maui.Storage.ISecureStorage.GetAsync(string! key) -> System.Threading.Tasks.Task!
+static Microsoft.Maui.Devices.Sensors.Geolocation.ListeningFailed -> System.EventHandler!
static Microsoft.Maui.Storage.SecureStorage.GetAsync(string! key) -> System.Threading.Tasks.Task!
+Microsoft.Maui.Devices.Sensors.IGeolocation.IsListeningForeground.get -> bool
+Microsoft.Maui.Devices.Sensors.IGeolocation.LocationChanged -> System.EventHandler?
+Microsoft.Maui.Devices.Sensors.IGeolocation.StartListeningForegroundAsync(Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest! request) -> System.Threading.Tasks.Task!
+Microsoft.Maui.Devices.Sensors.IGeolocation.StopListeningForeground() -> void
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest.DesiredAccuracy.get -> Microsoft.Maui.Devices.Sensors.GeolocationAccuracy
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest.DesiredAccuracy.set -> void
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest.GeolocationListeningRequest() -> void
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest.GeolocationListeningRequest(Microsoft.Maui.Devices.Sensors.GeolocationAccuracy accuracy) -> void
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest.GeolocationListeningRequest(Microsoft.Maui.Devices.Sensors.GeolocationAccuracy accuracy, System.TimeSpan minimumTime) -> void
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest.MinimumTime.get -> System.TimeSpan
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest.MinimumTime.set -> void
+Microsoft.Maui.Devices.Sensors.GeolocationLocationChangedEventArgs
+Microsoft.Maui.Devices.Sensors.GeolocationLocationChangedEventArgs.Location.get -> Microsoft.Maui.Devices.Sensors.Location!
+Microsoft.Maui.Devices.Sensors.GeolocationLocationChangedEventArgs.GeolocationLocationChangedEventArgs(Microsoft.Maui.Devices.Sensors.Location! location) -> void
+static Microsoft.Maui.Devices.Sensors.Geolocation.IsListeningForeground.get -> bool
+static Microsoft.Maui.Devices.Sensors.Geolocation.LocationChanged -> System.EventHandler!
+static Microsoft.Maui.Devices.Sensors.Geolocation.StartListeningForegroundAsync(Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest! request) -> System.Threading.Tasks.Task!
+static Microsoft.Maui.Devices.Sensors.Geolocation.StopListeningForeground() -> void
*REMOVED*static Microsoft.Maui.ApplicationModel.Communication.PhoneDialer.Current.get -> Microsoft.Maui.ApplicationModel.Communication.IPhoneDialer!
diff --git a/src/Essentials/src/PublicAPI/netstandard/PublicAPI.Unshipped.txt b/src/Essentials/src/PublicAPI/netstandard/PublicAPI.Unshipped.txt
index 59a09cb0ab11..c64aedf4601a 100644
--- a/src/Essentials/src/PublicAPI/netstandard/PublicAPI.Unshipped.txt
+++ b/src/Essentials/src/PublicAPI/netstandard/PublicAPI.Unshipped.txt
@@ -7,6 +7,33 @@ Microsoft.Maui.Authentication.WebAuthenticatorOptions.ResponseDecoder.set -> voi
~Microsoft.Maui.Authentication.WebAuthenticatorResult.WebAuthenticatorResult(System.Uri uri, Microsoft.Maui.Authentication.IWebAuthenticatorResponseDecoder responseDecoder) -> void
*REMOVED*Microsoft.Maui.Storage.ISecureStorage.GetAsync(string! key) -> System.Threading.Tasks.Task!
*REMOVED*static Microsoft.Maui.Storage.SecureStorage.GetAsync(string! key) -> System.Threading.Tasks.Task!
+Microsoft.Maui.Devices.Sensors.GeolocationError
+Microsoft.Maui.Devices.Sensors.GeolocationError.PositionUnavailable = 0 -> Microsoft.Maui.Devices.Sensors.GeolocationError
+Microsoft.Maui.Devices.Sensors.GeolocationError.Unauthorized = 1 -> Microsoft.Maui.Devices.Sensors.GeolocationError
+Microsoft.Maui.Devices.Sensors.GeolocationListeningFailedEventArgs
+Microsoft.Maui.Devices.Sensors.GeolocationListeningFailedEventArgs.Error.get -> Microsoft.Maui.Devices.Sensors.GeolocationError
+Microsoft.Maui.Devices.Sensors.GeolocationListeningFailedEventArgs.GeolocationListeningFailedEventArgs(Microsoft.Maui.Devices.Sensors.GeolocationError geolocationError) -> void
+Microsoft.Maui.Devices.Sensors.IGeolocation.ListeningFailed -> System.EventHandler?
Microsoft.Maui.Storage.ISecureStorage.GetAsync(string! key) -> System.Threading.Tasks.Task!
+static Microsoft.Maui.Devices.Sensors.Geolocation.ListeningFailed -> System.EventHandler!
static Microsoft.Maui.Storage.SecureStorage.GetAsync(string! key) -> System.Threading.Tasks.Task!
-*REMOVED*static Microsoft.Maui.ApplicationModel.Communication.PhoneDialer.Current.get -> Microsoft.Maui.ApplicationModel.Communication.IPhoneDialer!
\ No newline at end of file
+Microsoft.Maui.Devices.Sensors.IGeolocation.IsListeningForeground.get -> bool
+Microsoft.Maui.Devices.Sensors.IGeolocation.LocationChanged -> System.EventHandler?
+Microsoft.Maui.Devices.Sensors.IGeolocation.StartListeningForegroundAsync(Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest! request) -> System.Threading.Tasks.Task!
+Microsoft.Maui.Devices.Sensors.IGeolocation.StopListeningForeground() -> void
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest.DesiredAccuracy.get -> Microsoft.Maui.Devices.Sensors.GeolocationAccuracy
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest.DesiredAccuracy.set -> void
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest.GeolocationListeningRequest() -> void
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest.GeolocationListeningRequest(Microsoft.Maui.Devices.Sensors.GeolocationAccuracy accuracy) -> void
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest.GeolocationListeningRequest(Microsoft.Maui.Devices.Sensors.GeolocationAccuracy accuracy, System.TimeSpan minimumTime) -> void
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest.MinimumTime.get -> System.TimeSpan
+Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest.MinimumTime.set -> void
+Microsoft.Maui.Devices.Sensors.GeolocationLocationChangedEventArgs
+Microsoft.Maui.Devices.Sensors.GeolocationLocationChangedEventArgs.Location.get -> Microsoft.Maui.Devices.Sensors.Location!
+Microsoft.Maui.Devices.Sensors.GeolocationLocationChangedEventArgs.GeolocationLocationChangedEventArgs(Microsoft.Maui.Devices.Sensors.Location! location) -> void
+static Microsoft.Maui.Devices.Sensors.Geolocation.IsListeningForeground.get -> bool
+static Microsoft.Maui.Devices.Sensors.Geolocation.LocationChanged -> System.EventHandler!
+static Microsoft.Maui.Devices.Sensors.Geolocation.StartListeningForegroundAsync(Microsoft.Maui.Devices.Sensors.GeolocationListeningRequest! request) -> System.Threading.Tasks.Task!
+static Microsoft.Maui.Devices.Sensors.Geolocation.StopListeningForeground() -> void
+*REMOVED*static Microsoft.Maui.ApplicationModel.Communication.PhoneDialer.Current.get -> Microsoft.Maui.ApplicationModel.Communication.IPhoneDialer!