Xamarin.Essentials: georilevazione
La classe Geolocation fornisce le API per recuperare le coordinate di georilevazione correnti del dispositivo.
Operazioni preliminari
Per iniziare a usare questa API, leggere la guida introduttiva per Xamarin.Essentials assicurarsi che la libreria sia installata e configurata correttamente nei progetti.
Per accedere alla funzionalità Geolocation, è necessaria la configurazione seguente specifica della piattaforma:
Le autorizzazioni Coarse e Fine Location sono obbligatorie e devono essere configurate nel progetto Android. Se inoltre l'app usa come destinazione Android 5.0 (livello API 21) o versione successiva, è necessario dichiarare che l'app usa le funzionalità hardware nel file manifesto. È possibile aggiungerla nei modi seguenti:
Aprire il file AssemblyInfo.cs nella cartella Proprietà e aggiungere:
[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)]
Oppure aggiornare il manifesto di Android:
Aprire il file AndroidManifest.xml nella cartella Proprietà e aggiungere quanto segue all'interno del 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" />
Oppure fare clic con il pulsante destro del mouse sul progetto Android e aprire le proprietà del progetto. In Manifesto Android trovare l'area Autorizzazioni necessarie e selezionare le autorizzazioni ACCESS_COARSE_LOCATION e ACCESS_FINE_LOCATION. Il file AndroidManifest.xml verrà aggiornato automaticamente.
Se l'applicazione ha come destinazione Android 10 - Q (livello API 29 o versione successiva) e richiede LocationAlways, è necessario aggiungere anche l'autorizzazione seguente in AssemblyInfo.cs:
[assembly: UsesPermission(Manifest.Permission.AccessBackgroundLocation)]
Oppure direttamente nel AndroidManifest.xml:
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
È consigliabile leggere la documentazione di Android sugli aggiornamenti della posizione in background perché sono necessarie molte restrizioni.
Questa API usa le autorizzazioni di runtime in Android. Assicurarsi che sia completamente inizializzata e che Xamarin.Essentials la gestione delle autorizzazioni sia configurata nell'app.
Nel progetto MainLauncher
Android o in qualsiasi Activity
elemento avviato Xamarin.Essentials deve essere inizializzato nel OnCreate
metodo :
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
//...
}
Per gestire le autorizzazioni di runtime in Android, Xamarin.Essentials deve ricevere qualsiasi OnRequestPermissionsResult
. Aggiungere il codice seguente a tutte le classi 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);
}
Uso di Geolocation
Aggiungere un riferimento a Xamarin.Essentials nella classe :
using Xamarin.Essentials;
L'API per la georilevazione richiederà anche le autorizzazioni all'utente quando necessario.
È possibile ottenere l'ultima posizione conosciuta del dispositivo chiamando il metodo GetLastKnownLocationAsync
. Questa procedura è spesso più veloce che eseguire una query completa, ma può essere meno accurata e potrebbe restituire null
in assenza di un percorso memorizzato nella 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
}
Per eseguire una query delle coordinate geografiche del dispositivo corrente, si può usare GetLocationAsync
. È preferibile passare GeolocationRequest
e CancellationToken
completi perché l'acquisizione della posizione del dispositivo potrebbe richiedere tempo.
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();
}
Si noti che tutti i valori possono essere disponibili a causa del modo in cui ogni dispositivo esegue query sulla georilevazione tramite provider diversi. Ad esempio, la Altitude
proprietà potrebbe essere null
, avere un valore pari a 0 o avere un valore positivo, espresso in metri sopra il livello del mare. Altri valori che potrebbero non essere presenti includono Speed
e Course
.
Accuratezza della georilevazione
La tabella seguente indica l'accuratezza per ogni piattaforma:
Più basso
Piattaforma | Distanza (in metri) |
---|---|
Android | 500 |
iOS | 3000 |
UWP | 1000 - 5000 |
Basso
Piattaforma | Distanza (in metri) |
---|---|
Android | 500 |
iOS | 1000 |
UWP | 300 - 3000 |
Media (impostazione predefinita)
Piattaforma | Distanza (in metri) |
---|---|
Android | 100 - 500 |
iOS | 100 |
UWP | 30 - 500 |
Alto
Piattaforma | Distanza (in metri) |
---|---|
Android | 0 - 100 |
iOS | 10 |
UWP | <= 10 |
Migliore
Piattaforma | Distanza (in metri) |
---|---|
Android | 0 - 100 |
iOS | ~0 |
UWP | <= 10 |
Rilevamento di località fittizie
Alcuni dispositivi possono restituire una località fittizia proposta dal provider o da un'applicazione che fornisce località fittizie. È possibile rilevarle usando IsFromMockProvider
su qualsiasi 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
}
}
Distanza tra due località
Le classi Location
e LocationExtensions
definiscono i metodi CalculateDistance
che consentono di calcolare la distanza tra due località geografiche. Questa distanza calcolata non tiene in considerazione le strade o altri percorsi, ma è semplicemente la distanza più breve tra due punti sulla superficie terrestre, nota anche come ortodromia o, colloquialmente, distanza "a volo d'uccello".
Ecco un esempio:
Location boston = new Location(42.358056, -71.063611);
Location sanFrancisco = new Location(37.783333, -122.416667);
double miles = Location.CalculateDistance(boston, sanFrancisco, DistanceUnits.Miles);
Il costruttore Location
ha gli argomenti di latitudine e longitudine in quest'ordine. I valori di latitudine positiva sono a nord dell'equatore e i valori di longitudine positiva sono a est del Meridiano di Greenwich. Usare l'argomento finale per CalculateDistance
per specificare miglia o chilometri. La classe UnitConverters
definisce anche i metodi KilometersToMiles
e MilesToKilometers
per eseguire la conversione da un'unità di misura all'altra.
Differenze tra le piattaforme
L'altitudine viene calcolata in modo diverso in ogni piattaforma.
In Android, l'altitudine, se disponibile, viene restituita in metri sopra l'ellissoide di riferimento WGS 84. Se questa posizione non ha un'altitudine, viene restituito 0,0.
API
Video correlato
Altri video di Xamarin sono disponibili su Channel 9 e YouTube.