Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Determinare la posizione dell'utente

Link copiato negli appunti

Per determinare la posizione dell'utente, WinRT mette a disposizione una semplicissima API, esposta tramite il namespace Windows.Devices.Geolocation, che incapsula la logica necessaria a geolocalizzare il device, a seconda che sia o meno disponibile un sensore GPS installato sul device. Ci sono infatti due modi di determinare la posizione:

  • la prima, piuttosto imprecisa, si basa sulla ricostruzione operata dal Windows Location Provider (parte della Windows Sensor and Location Platform), che utilizza la triangolazione tramite reti wireless e l'analisi dell'indirizzo IP.
  • la seconda, assai più affidabile, si basa sul sensore GPS, quando presente sul device.

L'API è comunque la stessa e rende trasparente il meccanismo effettivo utilizzato dal sistema per determinare la posizione. Sarà infatti WinRT a determinare quale dei due provider sia il più adatto nel caso specifico. Se entrambi disponibili, WinRT utilizzerà quello in grado di assicurare i dati più precisi in quel preciso momento.

Nel caso di applicazioni Windows Store in esecuzione su un normale PC desktop (normalmente sprovvisto di sensore GPS), possiamo non aspettarci dati troppo accurati in merito alla geolocalizzazione: la posizione ottenuta triangolando le reti Wi-Fi ha un margine d'errore di 350 metri nelle aree urbane (dove le reti wireless sono numerose), aumentando al rarefarsi di hot-spot e reti wireless; nel caso di analisi dell'indirizzo IP, invece, l'approssimazione è di circa 50 km.

Per testare un'applicazione con dati più accurati, è possibile usare il Windows 8 Simulator. Il simulatore permette di impostare le coordinate geografiche, inclusa l'altitudine e il margine d'errore, che verranno utilizzate per testare il comportamento della tua app. La prossima immagine mostra il dialog del simulatore.

La posizione degli utenti è considerarsi un "dato sensibile" e potenzialmente lesivo della privacy dell'utente. Perciò per accedere alla Location API via codice dovremo sia aggiungere la "capability" Location nell'application manifest, sia richiedere il consenso esplicito dell'utente all'uso della sua posizione.

Per tutti i cosiddetti "sensitive device", quindi quei sensori o periferiche che abilitano le app alla raccolta di dati sensibili degli utenti (es. webcam e GPS), la documentazione ufficiale Microsoft prevede delle specifiche linee guida).

Quando l'applicazione dovrà effettuare il primo accesso alle API per la posizione geografica, WinRT richiederà l'autorizzazione all'utente con un dialog box, come illustrato nella prossima immagine. Per questo bisogna fare in modo che l'app gestisca anche l'eventuale rifiuto.

Recuperare i dati sulla posizione dell'utente

Come si è accennato nell'introduzione, il namespace Windows.Devices.Geolocation mette a disposizione l'API necessaria a recuperare le informazioni sulla posizione geografica dell'utente. La classe responsabile per gestire le varie operazioni è la classe Geolocator.

Il seguente codice HTML può servire come riferimento per testare il codice presentato in questo articolo:

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8" />
	<title>Demo.Html.it.GeolocationSample.JS</title>
	<!-- WinJS references -->
	<link href="//Microsoft.WinJS.2.0/css/ui-dark.css" rel="stylesheet" />
	<script src="//Microsoft.WinJS.2.0/js/base.js"></script>
	<script src="//Microsoft.WinJS.2.0/js/ui.js"></script>
	<!-- Demo.Html.it.GeolocationSample.JS references -->
	<link href="/css/default.css" rel="stylesheet" />
	<script src="/js/default.js"></script>
</head>
<body>
<div class="buttonRow">
	<span>
	<button class="button" id="btnTrackPosition">Traccia posizione</button>
	<button class="button" id="btnGetLocation">Ottieni posizione</button>
	</span>
</div>
<div id="coordinates">
	<div id="errorMessage"></div>
	<div id="sensorStatus"></div>
	<div id="latitude"></div>
	<div id="longitude"></div>
	<div id="accuracy"></div>
	<div id="timestamp"></div>
</div>
</body>
</html>

Il prossimo listato mostra come usare la classe Geolocator per determinare la posizione dell'utente.

var geolocator;
app.onloaded = function () {
	geolocator = new Windows.Devices.Geolocation.Geolocator();
	btnGetLocation.addEventListener("click", getLocation_click);
}
function getLocation_click(args) {
	try {
		geolocator.desiredAccuracy = Windows.Devices.Geolocation.PositionAccuracy.high;
		geolocator.getGeopositionAsync().then(displayPosition, function (err) {
			errorMessage.innerHTML = "Qualcosa è andato storto. Controlla i permessi";
		});
	} catch (ex) {
		errorMessage.innerHTML = "<p>Qualcosa è andato storto.</p>";
	}
}
function displayPosition(position) {
	latitude.innerHTML = "<p>Latitudine: " + position.coordinate.latitude + " gradi</p>";
	longitude.innerHTML = "<p>Longitudine: " + position.coordinate.longitude + " gradi</p>";
	accuracy.innerHTML = "<p>Accuratezza: " + position.coordinate.accuracy + " metri</p>";
	timestamp.innerHTML = "<p>Timestamp: " + position.coordinate.timestamp + "</p>";
}

Dopo aver istanziato un nuovo oggetto di tipo Geolocator, il codice sfrutta la proprietà DesiredAccuracy per impostare il livello di accuratezza delle rilevazioni.

Per consumare il meno possibile le batterie, è meglio impostare la proprietà su Default e utilizzare l'opzione High solo quando abbiamo bisogno di rilevamenti della maggior precisione possibile. Inoltre, anche impostando la proprietà su High, l'accuratezza effettiva dei dati registrati dal sensore dipende da numerosi altri fattori.

Per recuperare la posizione del device, invochiamo il metodo GetGeopositionAsync con il solito pattern asincrono basato su promise. Al termine dell'operazione asincrona, la promise restituisce un oggetto Geoposition che contiene i dati relativi alla posizione geografica dell'utente.

Più in particolare, la classe Geoposition espone due tipi di dati:

  • La proprietà Coordinate (di tipo Geocoordinate). Questa proprietà rappresenta le coordinate geografiche (come longitudine e latitudine), assieme ad altri dati complementari, come l'altitudine (espressa in metri sopra il livello del mare), la direzione corrente (espressa in gradi rispetto al nord geografico), la velocità (in metri per secondo), l'accuratezza della rilevazione e un timestamp che indica il momento della rilevazione. La disponibilità di alcuni di questi dati, come altitudine e velocità, dipendono dall'implementazione concreta del dispositivo GPS montato sul device, per cui è sempre buona regola verificare che non siano null prima di usarli. Il Windows Location Provider, invece, mette a disposizione unicamente dati relativi a longitudine, latitudine e accuratezza.
  • La proprietà CivicAddress, che rappresenta l'indirizzo civico associato ad una determinata posizione geografica. Tuttavia, questa informazione è disponibile solo se è stato installato un Civic Address provider. In caso contrario, l'API restituirà solo le informazioni regionali accessibili tramite il Control Panel. Windows 8 non fornisce infatti alcun Civic Address provider di default (almeno per adesso), né al momento risultano disponibili provider di terze parti. Se la tua app ha bisogno di questo tipo di informazioni, potresti considerare la possibilità di utilizzare servizi esterni, come il servizio Bing Maps Geocode.

La classe Geolocator espone anche un overload del metodo GetGeopositionAsync che accetta come parametri due oggetti di tipo TimeSpan: il primo indica l'età massima dei dati geolocalizzati eventualmente presenti in cache, mentre il secondo rappresenta il time-out per concludere l'operazione (il tempo di default è di 7 secondi).

Tracciare la posizione dell'utente

Oltre a determinare la posizione geografica dell'utente in un certo momento, la classe Geolocator permette anche di tenere traccia dei movimenti dell'utente, grazie all'evento PositionChanged. Questo evento viene sollevato ogni volta che il location provider si accorge che la posizione geografica dell'utente è cambiata. Ecco come utilizzare questo evento:

app.onloaded = function () {
	geolocator = new Windows.Devices.Geolocation.Geolocator();
	btnTrackPosition.addEventListener("click", trackPosition_click);
	btnGetLocation.addEventListener("click", getLocation_click);
}
// (codice omesso per brevità)
function trackPosition_click(args) {
	try {
		geolocator.desiredAccuracy = Windows.Devices.Geolocation.PositionAccuracy.default;
		geolocator.movementThreshold = 5.0;
		geolocator.addEventListener("positionchanged", geolocatorPositionChanged);
		geolocator.getGeopositionAsync()
		.then(displayPosition, function (err) {
			errorMessage.innerHTML = "<p>Qualcosa è andato storto. Controlla i permessi</p>";
		});
	} catch (e) {
		errorMessage.innerHTML = "<p>Qualcosa è andato storto</p>";
	}
}
function geolocatorPositionChanged(args) {
	displayPosition(args.position);
}

Per evitare che l'evento sia invocato a fronte anche del più piccolo spostamento dell'utente, è possibile impostare la proprietà MovementThreshold con la distanza minima (espressa in metri) da percorrere prima che l'evento PositionChanged venga sollevato (il valore di default di questa proprietà è zero).

È anche possibile sfruttare l'evento StatusChanged per determinare lo stato del location provider. Questo evento viene sollevato quando lo stato del sensore, espresso dalla proprietà Status dell'oggetto PositionChangedEventArgs ricevuto come parametro dall'event handler, cambia. La proprietà Status può assumere uno dei seguenti valori (espresso tramite l'enum PositionStatus):

Valore Descrizione
Ready Sono disponibili dati sulla posizione
Initializing Il location provider è in corso di inizializzazione (ad esempio, perché sta cercando il numero minimo di satelliti necessari per determinare la posizione)
NoData Nessun dato disponibile
Disabled L'utente non ha prestato all'applicazione il suo consenso per accedere alla posizione. Accertati che la tua app sia in grado di gestire questa eventualità
NotInitialized Il location provider non è stato ancora inizializzato
NotAvailable La Windows Sensor and Location platform non è disponibile sul sistema

Lo stato corrente del location provider può essere verificato in ogni momento tramite la proprietà LocationStatus della classe Geolocator.

Il seguente snippet modifica il codice sopra riportato per sfruttare l'evento StatusChanged e mostrare all'utente lo stato del location provider.

app.onloaded = function () {
	geolocator = new Windows.Devices.Geolocation.Geolocator();
	geolocator.addEventListener("statuschanged", geolocatorStatusChanged);
	btnTrackPosition.addEventListener("click", trackPosition_click);
	btnGetLocation.addEventListener("click", getLocation_click);
}
// (codice omesso)
function geolocatorStatusChanged(args) {
	if (args.status != null) {
		switch (args.status) {
			case Windows.Devices.Geolocation.PositionStatus.ready:
					sensorStatus.innerHTML += "<p>Geolocation: Ready</p>";
					break;
			case Windows.Devices.Geolocation.PositionStatus.initializing:
				sensorStatus.innerHTML += "<p>Geolocation: Initializing</p>";
				break;
			case Windows.Devices.Geolocation.PositionStatus.noData:
				sensorStatus.innerHTML += "<p>Geolocation: No data</p>";
				break;
			case Windows.Devices.Geolocation.PositionStatus.disabled:
				sensorStatus.innerHTML += "<p>Geolocation: Disabled</p>";
				break;
			case Windows.Devices.Geolocation.PositionStatus.notInitialized:
				sensorStatus.innerHTML += "<p>Geolocation: Not initialized</p>";
				break;
			case Windows.Devices.Geolocation.PositionStatus.notAvailable:
				sensorStatus.innerHTML += "<p>Geolocation: Not available</p>";
				break;
			default:
				sensorStatus.innerHTML += "<p>Geolocation: Unknown</p>";
				break;
		}
	}
}

Il risultato è mostrato nella prossima immagine.

Ti consigliamo anche