Xamarin.Essentials: Geolocalização
A classe Geolocation fornece APIs para recuperar as coordenadas atuais de geolocalização do dispositivo.
Introdução
Para começar a usar essa API, leia o guia de introdução para Xamarin.Essentials garantir que a biblioteca esteja instalada e configurada corretamente em seus projetos.
Para acessar a funcionalidade de Geolocalização, a seguinte configuração específica da plataforma é necessária:
As permissões Coarse Location e Fine Location são necessárias e devem ser configuradas no projeto do Android. Além disso, se o seu aplicativo for destinado ao Android 5.0 (API nível 21) ou superior, você deverá declarar que ele usa os recursos de hardware no arquivo de manifesto. Isso pode ser usado das seguintes maneiras:
Abra o arquivo AssemblyInfo.cs na pasta Propriedades e adicione:
[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)]
Ou atualize o manifesto do Android:
Abra o arquivo AndroidManifest.xml na pasta Propriedades e adicione o seguinte dentro do nó do manifesto:
<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" />
Ou clique com o botão direito no projeto do Android e abra as propriedades do projeto. Em Manifesto do Android, localize a área Permissões necessárias: e marque as permissões ACCESS_COARSE_LOCATION e ACCESS_FINE_LOCATION. Isso atualizará automaticamente o arquivo AndroidManifest.xml.
Se o aplicativo for direcionado ao Android 10 - Q (API de nível 29 ou mais recente) e solicitar LocationAlways, também será necessário adicionar a seguinte permissão a AssemblyInfo.cs:
[assembly: UsesPermission(Manifest.Permission.AccessBackgroundLocation)]
Ou diretamente em sua AndroidManifest.xml:
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
Recomenda-se ler a documentação do Android sobre atualizações de localização em segundo plano, pois há muitas restrições que precisam ser consideradas.
Essa API usa permissões de tempo de execução no Android. Certifique-se de que Xamarin.Essentials esteja totalmente inicializado e que o tratamento de permissões esteja configurado em seu aplicativo.
No projeto MainLauncher
Android ou em qualquer Activity
um que seja iniciado Xamarin.Essentials deve ser inicializado no OnCreate
método:
protected override void OnCreate(Bundle savedInstanceState)
{
//...
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState); // add this line to your code, it may also be called: bundle
//...
}
Para lidar com permissões de tempo de execução no Android, Xamarin.Essentials o deve receber qualquer OnRequestPermissionsResult
arquivo . Adicione o seguinte código a todas as classes Activity
:
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Android.Content.PM.Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
Usar a geolocalização
Adicione uma referência a Xamarin.Essentials em sua classe:
using Xamarin.Essentials;
A API de Geolocalização também solicitará ao usuário permissões quando for necessário.
Você pode obter o último local conhecido do dispositivo chamando o método GetLastKnownLocationAsync
. Isso geralmente é mais rápido do que fazer uma consulta completa, mas pode ser menos precisa e pode retornar null
se não houver nenhum local armazenado em cache.
try
{
var location = await Geolocation.GetLastKnownLocationAsync();
if (location != null)
{
Console.WriteLine($"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
}
Para consultar as coordenadas do local atual do dispositivo, use GetLocationAsync
. É melhor passar um GeolocationRequest
e CancellationToken
completo, pois pode demorar um pouco para obter o local do dispositivo.
CancellationTokenSource cts;
async Task GetCurrentLocation()
{
try
{
var request = new GeolocationRequest(GeolocationAccuracy.Medium, TimeSpan.FromSeconds(10));
cts = new CancellationTokenSource();
var location = await Geolocation.GetLocationAsync(request, cts.Token);
if (location != null)
{
Console.WriteLine($"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
}
}
protected override void OnDisappearing()
{
if (cts != null && !cts.IsCancellationRequested)
cts.Cancel();
base.OnDisappearing();
}
Observe que todos os valores podem estar disponíveis devido à forma como cada dispositivo consulta a geolocalização por meio de diferentes provedores. Por exemplo, a Altitude
propriedade pode ser null
, ter um valor de 0 ou ter um valor positivo, que está em metros acima do nível do mar. Outros valores que podem não estar presentes incluem Speed
e Course
.
Precisão da geolocalização
A tabela a seguir descreve a precisão por plataforma:
O menor
Plataforma | Distância (em metros) |
---|---|
Android | 500 |
iOS | 3000 |
UWP | 1.000–5.000 |
Baixo
Plataforma | Distância (em metros) |
---|---|
Android | 500 |
iOS | 1000 |
UWP | 300–3.000 |
Médio (padrão)
Plataforma | Distância (em metros) |
---|---|
Android | 100–500 |
iOS | 100 |
UWP | 30–500 |
Alto
Plataforma | Distância (em metros) |
---|---|
Android | 0–100 |
iOS | 10 |
UWP | <= 10 |
Melhor
Plataforma | Distância (em metros) |
---|---|
Android | 0–100 |
iOS | ~0 |
UWP | <= 10 |
Detectando locais fictícios
Alguns dispositivos podem retornar um local fictício do provedor ou por um aplicativo que fornece locais fictícios. Você pode detectar isso usando o IsFromMockProvider
em qualquer Location
.
var request = new GeolocationRequest(GeolocationAccuracy.Medium);
var location = await Geolocation.GetLocationAsync(request);
if (location != null)
{
if(location.IsFromMockProvider)
{
// location is from a mock provider
}
}
Distância entre dois locais
As classes Location
e LocationExtensions
definem métodos CalculateDistance
que permitem o cálculo da distância entre duas localizações geográficas. Essa distância calculada não considera estradas ou outros caminhos e é simplesmente a distância mais curta entre os dois pontos ao longo da superfície da Terra, também conhecido como ortodromia ou, coloquialmente, a distância "em linha reta".
Veja um exemplo:
Location boston = new Location(42.358056, -71.063611);
Location sanFrancisco = new Location(37.783333, -122.416667);
double miles = Location.CalculateDistance(boston, sanFrancisco, DistanceUnits.Miles);
O construtor Location
tem argumentos de latitude e longitude, nessa ordem. Os valores de latitude positiva estão ao norte do Equador, e os valores de longitude positiva estão a leste do Meridiano primário. Use o argumento final para CalculateDistance
a fim de especificar milhas ou quilômetros. A classe UnitConverters
também define os métodos KilometersToMiles
e MilesToKilometers
para conversão entre as duas unidades.
Diferenças entre plataformas
A altitude é calculada de forma diferente em cada plataforma.
No Android, a altitude, se disponível, é retornada em metros acima do elipsóide de referência do WGS 84. Se esse local não tiver uma altitude, 0,0 será retornado.
API
Vídeo relacionados
Encontre mais vídeos sobre o Xamarin no Channel 9 e no YouTube.