Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En este artículo se describe cómo puedes utilizar la interfaz IGeolocation de .NET Multi-platform App UI (.NET MAUI). Esta interfaz proporciona API para recuperar las coordenadas de geolocalización actuales del dispositivo.
La implementación predeterminada de la interfaz IGeolocation
está disponible a través de la propiedad Geolocation.Default. Tanto la interfaz IGeolocation
como la clase Geolocation
se encuentran en el espacio de nombres Microsoft.Maui.Devices.Sensors
.
Comienza
Para acceder a la funcionalidad de geolocalización , se requiere la siguiente configuración específica de la plataforma:
Los permisos de ubicación general o fina, o ambos, deben especificarse y configurarse en el proyecto de Android.
Además, si la aplicación tiene como destino Android 5.0 (nivel de API 21) o superior, debes declarar que la aplicación usa las características de hardware en el archivo de manifiesto. Esto se puede agregar de las siguientes maneras:
Agregue el permiso basado en el ensamblado:
Abra el archivo Platforms/Android/MainApplication.cs y agregue los siguientes atributos de ensamblado después de las directivas
using
.[assembly: UsesPermission(Android.Manifest.Permission.AccessCoarseLocation)] [assembly: UsesPermission(Android.Manifest.Permission.AccessFineLocation)] [assembly: UsesFeature("android.hardware.location", Required = false)] [assembly: UsesFeature("android.hardware.location.gps", Required = false)] [assembly: UsesFeature("android.hardware.location.network", Required = false)]
Si la aplicación tiene como destino Android 10 - Q (nivel de API 29 o superior) y solicita
LocationAlways
, también debe agregar esta solicitud de permiso:[assembly: UsesPermission(Android.Manifest.Permission.AccessBackgroundLocation)]
- o -
Actualice el manifiesto de Android:
Abra el archivo Platforms/Android/AndroidManifest.xml y agregue lo siguiente en el nodo
manifest
:<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-feature android:name="android.hardware.location" android:required="false" /> <uses-feature android:name="android.hardware.location.gps" android:required="false" /> <uses-feature android:name="android.hardware.location.network" android:required="false" />
Si la aplicación tiene como destino Android 10 - Q (nivel de API 29 o superior) y solicita
LocationAlways
, también debe agregar esta solicitud de permiso:<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
- o -
Actualice el manifiesto de Android en el editor de manifiestos:
En Visual Studio, haga doble clic en el archivo Platforms/Android/AndroidManifest.xml para abrir el editor de manifiestos de Android. A continuación, en Permisos necesarios , compruebe los permisos enumerados anteriormente. Esto actualizará automáticamente el archivo AndroidManifest.xml.
Sugerencia
Asegúrese de leer la documentación de Android sobre las actualizaciones de ubicación en segundo plano, ya que hay muchas restricciones que deben tenerse en cuenta.
Obtención de la última ubicación conocida
Es posible que el dispositivo haya almacenado en caché la ubicación más reciente del dispositivo. Use el GetLastKnownLocationAsync() método para acceder a la ubicación almacenada en caché, si está disponible. Esto suele ser más rápido que realizar una consulta de ubicación completa, pero puede ser menos precisa. Si no existe ninguna ubicación almacenada en caché, este método devuelve null
.
Nota:
Cuando sea necesario, la API de geolocalización solicita al usuario los permisos.
En el ejemplo de código siguiente se muestra la comprobación de una ubicación almacenada en caché:
public async Task<string> GetCachedLocation()
{
try
{
Location location = await Geolocation.Default.GetLastKnownLocationAsync();
if (location != null)
return $"Latitude: {location.Latitude}, Longitude: {location.Longitude}, Altitude: {location.Altitude}";
}
catch (FeatureNotSupportedException fnsEx)
{
// Handle not supported on device exception
}
catch (FeatureNotEnabledException fneEx)
{
// Handle not enabled on device exception
}
catch (PermissionException pEx)
{
// Handle permission exception
}
catch (Exception ex)
{
// Unable to get location
}
return "None";
}
Dependiendo del dispositivo, no todos los valores de ubicación pueden estar disponibles. Por ejemplo, la Altitude propiedad podría ser null
, tener un valor de 0 o tener un valor positivo que indique los metros sobre el nivel del mar. Otros valores que pueden no estar presentes incluyen las Speed propiedades y Course .
Obtención de la ubicación actual
Aunque la comprobación de la última ubicación conocida del dispositivo puede ser más rápida, puede ser inexacta. Use el GetLocationAsync método para consultar el dispositivo para la ubicación actual. Puede configurar la precisión y el tiempo de espera de la consulta. Es mejor utilizar la sobrecarga del método que utiliza los parámetros GeolocationRequest y CancellationToken, ya que puede tardar algún tiempo en obtener la ubicación del dispositivo.
Nota:
Cuando sea necesario, la API de geolocalización solicita al usuario los permisos.
En el ejemplo de código siguiente se muestra cómo solicitar la ubicación del dispositivo, al tiempo que se admite la cancelación:
private CancellationTokenSource _cancelTokenSource;
private bool _isCheckingLocation;
public async Task GetCurrentLocation()
{
try
{
_isCheckingLocation = true;
GeolocationRequest request = new GeolocationRequest(GeolocationAccuracy.Medium, TimeSpan.FromSeconds(10));
_cancelTokenSource = new CancellationTokenSource();
Location location = await Geolocation.Default.GetLocationAsync(request, _cancelTokenSource.Token);
if (location != null)
Console.WriteLine($"Latitude: {location.Latitude}, Longitude: {location.Longitude}, Altitude: {location.Altitude}");
}
// Catch one of the following exceptions:
// FeatureNotSupportedException
// FeatureNotEnabledException
// PermissionException
catch (Exception ex)
{
// Unable to get location
}
finally
{
_isCheckingLocation = false;
}
}
public void CancelRequest()
{
if (_isCheckingLocation && _cancelTokenSource != null && _cancelTokenSource.IsCancellationRequested == false)
_cancelTokenSource.Cancel();
}
No todos los valores de ubicación pueden estar disponibles, en función del dispositivo. Por ejemplo, la Altitude propiedad podría ser null
, tener un valor de 0 o tener un valor positivo que indique los metros sobre el nivel del mar. Otros valores que pueden no estar presentes incluyen Speed y Course.
Advertencia
GetLocationAsync puede devolver null
en algunos escenarios. Esto indica que la plataforma subyacente no puede obtener la ubicación actual.
Escuchar cambios de ubicación
Además de consultar el dispositivo para la ubicación actual, puede escuchar los cambios de ubicación mientras una aplicación está en primer plano.
Para comprobar si la aplicación está escuchando actualmente los cambios de ubicación, hay una IsListeningForeground propiedad que puede consultar. Una vez que estés listo para empezar a escuchar los cambios de ubicación, debes llamar al método StartListeningForegroundAsync. Este método comienza a escuchar las actualizaciones de ubicación y genera el LocationChanged evento cuando cambia la ubicación, siempre que la aplicación esté en primer plano. El GeolocationLocationChangedEventArgs objeto que acompaña a este evento tiene una Location propiedad, de tipo Location, que representa la nueva ubicación que se ha detectado.
Nota:
Cuando sea necesario, la API de geolocalización solicita al usuario los permisos.
En el ejemplo de código siguiente se muestra cómo escuchar un cambio de ubicación y cómo procesar la ubicación modificada:
async void OnStartListening()
{
try
{
Geolocation.LocationChanged += Geolocation_LocationChanged;
var request = new GeolocationListeningRequest((GeolocationAccuracy)Accuracy);
var success = await Geolocation.StartListeningForegroundAsync(request);
string status = success
? "Started listening for foreground location updates"
: "Couldn't start listening";
}
catch (Exception ex)
{
// Unable to start listening for location changes
}
}
void Geolocation_LocationChanged(object sender, GeolocationLocationChangedEventArgs e)
{
// Process e.Location to get the new location
}
El control de errores se puede implementar registrando un controlador de eventos para el ListeningFailed evento. El GeolocationListeningFailedEventArgs objeto que acompaña a este evento tiene una propiedad Error, de tipo GeolocationError, que indica por qué la escucha falló. Cuando el evento ListeningFailed se genera, se detiene la escucha de cambios adicionales de ubicación y no se generan más eventos LocationChanged.
Para dejar de escuchar los cambios de ubicación, llame al método StopListeningForeground.
void OnStopListening()
{
try
{
Geolocation.LocationChanged -= Geolocation_LocationChanged;
Geolocation.StopListeningForeground();
string status = "Stopped listening for foreground location updates";
}
catch (Exception ex)
{
// Unable to stop listening for location changes
}
}
Nota:
El StopListeningForeground método no tiene ningún efecto cuando la aplicación no escucha los cambios de ubicación.
Comprobación de si los servicios de ubicación están habilitados
La Geolocation clase tiene una propiedad IsEnabled
de solo lectura que se puede usar para determinar si los servicios de ubicación se han habilitado en el dispositivo.
Precisión
En las secciones siguientes se describe la distancia de precisión de ubicación, por plataforma:
Importante
iOS tiene algunas limitaciones con respecto a la precisión. Para obtener más información, consulte la sección Diferencias de plataforma.
Más bajo
Plataforma | Distancia (en metros) |
---|---|
Androide | 500 |
Ios | 3000 |
Windows | 1000 - 5000 |
Bajo nivel
Plataforma | Distancia (en metros) |
---|---|
Androide | 500 |
Ios | 1 000 |
Windows | 300 - 3000 |
Medio (valor predeterminado)
Plataforma | Distancia (en metros) |
---|---|
Androide | 100 - 500 |
Ios | 100 |
Windows | 30-500 |
Alto
Plataforma | Distancia (en metros) |
---|---|
Androide | 0 - 100 |
Ios | 10 |
Windows | <= 10 |
Mejores
Plataforma | Distancia (en metros) |
---|---|
Androide | 0 - 100 |
Ios | ~0 |
Windows | <= 10 |
Detección de ubicaciones ficticias
Algunos dispositivos pueden devolver una ubicación ficticia del proveedor o de una aplicación que proporcione ubicaciones ficticias. Puede detectarlo mediante IsFromMockProvider en cualquier Location:
public async Task CheckMock()
{
GeolocationRequest request = new GeolocationRequest(GeolocationAccuracy.Medium);
Location location = await Geolocation.Default.GetLocationAsync(request);
if (location != null && location.IsFromMockProvider)
{
// location is from a mock provider
}
}
Distancia entre dos ubicaciones
El CalculateDistance método calcula la distancia entre dos ubicaciones geográficas. Esta distancia calculada no tiene en cuenta las carreteras u otras vías, y es simplemente la distancia más corta entre los dos puntos a lo largo de la superficie de la Tierra. Este cálculo se conoce como cálculo de distancia de gran círculo .
El código siguiente calcula la distancia entre las ciudades de Estados Unidos de América de Boston y San Francisco:
Location boston = new Location(42.358056, -71.063611);
Location sanFrancisco = new Location(37.783333, -122.416667);
double miles = Location.CalculateDistance(boston, sanFrancisco, DistanceUnits.Miles);
El Location(Double, Double, Double) constructor acepta los argumentos de latitud y longitud, respectivamente. Los valores de latitud positiva son al norte del ecuador y los valores de longitud positivas son este del Meridiano Primo. Usa el argumento final en CalculateDistance
para especificar millas o kilómetros. La UnitConverters clase también define los métodos KilometersToMiles y MilesToKilometers para convertir entre las dos unidades.
Diferencias de plataforma
En esta sección se describen las diferencias específicas de la plataforma con la API de geolocalización.
La altitud se calcula de forma diferente en cada plataforma.
En Android, altitud, si está disponible, se devuelve en metros por encima del elipsoide de referencia WGS 84. Si esta ubicación no tiene una altitud, 0.0
se devuelve.
La propiedad Location.ReducedAccuracy es utilizada solo por iOS y en todas las demás plataformas devuelve false
.