Questo è un problema interessante e ho avuto l'impressione che l'utilizzo di ACCESS_COARSE_LOCATION
avrebbe utilizzato il WiFi, poiché è quello che dice la documentazione.
La documentazione per ACCESS_COARSE_LOCATION
stati:
Consente un app per accedere posizione approssimativa derivata dalla rete fonti di localizzazione, come torri cellulari e Wi-Fi.
Quindi, ho messo alla prova, ed i risultati sono sorprendenti.
Ecco il codice che ho usato per testare con:
public class MainActivity extends Activity implements
GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
LocationRequest mLocationRequest;
GoogleApiClient mGoogleApiClient;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
buildGoogleApiClient();
mGoogleApiClient.connect();
}
@Override
protected void onPause(){
super.onPause();
if (mGoogleApiClient != null) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
}
protected synchronized void buildGoogleApiClient() {
Toast.makeText(this,"buildGoogleApiClient",Toast.LENGTH_SHORT).show();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
@Override
public void onConnected(Bundle bundle) {
Toast.makeText(this,"onConnected",Toast.LENGTH_SHORT).show();
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(10);
mLocationRequest.setFastestInterval(10);
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
//mLocationRequest.setPriority(LocationRequest.PRIORITY_LOW_POWER);
//mLocationRequest.setSmallestDisplacement(0.1F);
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
@Override
public void onConnectionSuspended(int i) {
Toast.makeText(this,"onConnectionSuspended",Toast.LENGTH_SHORT).show();
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Toast.makeText(this,"onConnectionFailed",Toast.LENGTH_SHORT).show();
}
@Override
public void onLocationChanged(Location location) {
Log.d("locationtesting", "accuracy: " + location.getAccuracy() + " lat: " + location.getLatitude() + " lon: " + location.getLongitude());
Toast.makeText(this,"Location Changed",Toast.LENGTH_SHORT).show();
}
}
AndroidManifest.xml:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
build.gradle:
compile 'com.google.android.gms:play-services:7.3.0'
Il primo test ho fatto è stato con PRIORITY_BALANCED_POWER_ACCURACY
e senza WiFi. Si noti che ho anche disabilitato Always Allow Scanning
, in quanto afferma:
Let Google Location Service e altre applicazioni di scansione per il Wi-Fi reti, anche quando la connessione Wi-Fi è spento
Quindi, che sarebbe certamente distorce i risultati se è stato abilitato.
Nota che ho anche impostato la Modalità posizione in Modalità risparmio batteria per tutti i test, quindi la radio GPS era spenta per tutto il tempo.
Ecco i risultati di PRIORITY_BALANCED_POWER_ACCURACY
, ACCESS_COARSE_LOCATION
, e nessuna connessione WiFi:
accuracy: 2000.0 lat: 37.78378378378378 lon: -122.40320943772021
Così, si dice 2.000 accuratezza metro, ed ecco come lontano le coordinate reali sono, la freccia verde mostra dove ho effettivamente sono:

Poi, ho abilitato Wi-Fi, e corse di nuovo il test, e sorprendentemente, i risultati sono stati esattamente la stessa cosa!
accuracy: 2000.0 lat: 37.78378378378378 lon: -122.40320943772021
Poi, sono passato a LocationRequest.PRIORITY_LOW_POWER
nel LocationRequest
mantenendo android.permission.ACCESS_COARSE_LOCATION
nel AndroidManifest.xml.
No WiFi:
accuracy: 2000.0 lat: 37.78378378378378 lon: -122.40320943772021
con WiFi:
accuracy: 2000.0 lat: 37.78378378378378 lon: -122.40320943772021
I risultati sono stati esattamente la stessa cosa di nuovo! L'utilizzo di PRIORITY_LOW_POWER
ha avuto gli stessi risultati dell'uso di PRIORITY_BALANCED_POWER_ACCURACY
, in quanto lo stato WiFi non sembrava avere alcun effetto sull'accuratezza delle coordinate.
Poi, solo per coprire tutte le basi, ho cambiato di nuovo a LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY
, e acceso l'AndroidManifest.xml a ACCESS_FINE_LOCATION
:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Primo test, senza WiFi:
accuracy: 826.0 lat: 37.7825458 lon: -122.3948752
Quindi, dice accuratezza di 826 metri, ed ecco quanto era vicino sulla mappa:

.515.053.691,36321 milioni
Poi, ho acceso Wi-Fi, ed ecco il risultato:
accuracy: 18.847 lat: 37.779679 lon: -122.3930918
È letteralmente esatte, come si può vedere sulla mappa:

Sembra che conta meno quello che usi nel tuo codice LocationRequest
nel codice Java, e più quale permesso usi in AndroidManifest.xml, poiché i risultati qui mostrano chiaramente che quando si utilizza ACCESS_FINE_LOCATION
, avere la radio WiFi attivata o disattivata ha fatto un'enorme differenza nella precisione, ed era anche più acc urate in generale.
Sembra quasi che la documentazione sia un po 'trascurata e che mentre si utilizza android.permission.ACCESS_COARSE_LOCATION
, l'attivazione o la disattivazione della radio WiFi non fa la differenza quando l'app è l'unica a effettuare richieste di posizione.
Un'altra cosa che la documentazione afferma è che l'utilizzo di PRIORITY_BALANCED_POWER_ACCURACY
consentirà alla tua app di "fare il backup" sulle richieste di posizione effettuate da altre app. Dalla documentazione:
Saranno assegnati solo colpa di potenza per l'intervallo fissato dal setInterval (lungo), ma possono ancora ricevere posizioni innescati da altre applicazioni ad una velocità fino a setFastestInterval (lungo) .
Quindi, se l'utente apre Google Maps, in base alla documentazione, l'app può ottenere una posizione più precisa a quel punto. Questo è uno dei principali aspetti positivi dell'utilizzo del nuovo Fused Location Provider piuttosto che delle API precedenti, poiché diminuisce la quantità di esaurimento della batteria della tua app senza molto lavoro da parte tua.
Modifica: ho eseguito un test di questa funzionalità per vedere cosa accadrebbe durante l'utilizzo di ACCESS_COARSE_LOCATION
.
Primo test: ACCESS_COARSE_LOCATION
, PRIORITY_BALANCED_POWER_ACCURACY
, e WiFi su:
accuracy: 2000.0 lat: 37.78378378378378 lon: -122.38041129850662
Questo mi ha messi in acqua, abbastanza lontano dalla mia posizione attuale. Poi, sono uscito dall'app di test, ho lanciato Google Maps, che mi ha localizzato esattamente dove mi trovo, quindi ho riavviato l'app di test. L'app di test non è stata in grado di tornare nella posizione da Google Maps e il risultato era esattamente lo stesso di prima!
accuracy: 2000.0 lat: 37.78378378378378 lon: -122.38041129850662
ho ri-provato questo un paio di volte, giusto per essere sicuri, ma sembra davvero come l'utilizzo di ACCESS_COARSE_LOCATION
disattiva anche la capacità di applicazioni a "piggy-back" a posizioni ottenute da altre applicazioni.
Sembra che l'utilizzo di ACCESS_COARSE_LOCATION
in AndroidManifest.xml blocchi davvero l'app in termini di dati precisi sulla posizione.
In conclusione, l'unica cosa che puoi veramente fare è affinare la migliore combinazione di impostazioni che funzionano per te e per la tua app, e speriamo che i risultati di questo test possano aiutarti a prendere questa decisione.
Google crea il modello di posizione raccogliendo le informazioni sui punti di accesso dagli utenti che si connettono tramite wifi e torri cellulari. Più dati raccolgono, migliore è la precisione, quindi tecnicamente avresti bisogno di più utenti Android nella tua zona. D'altra parte sembra strano che il GPS possa avere una precisione dell'ordine di 100m o 2km per l'accesso grossolano. Sei sicuro di non aver calcolato male? – inmyth
La precisione del GPS è circa il metro. Sto facendo tutti i miei test con il GPS spento. Il dispositivo utilizza il wifi quando sto usando il permesso ACCESS_FINE_LOCATION (ho abbastanza utenti Android nella mia area). Dovrei ottenere lo stesso identico risultato quando utilizzo ACCESS_COARSE_LOCATION invece di una precisione di 2000m. – poiuytrez