traduccion studio requestlocationupdates last known fusedlocationproviderclient fused example android permissions gps android-location fusedlocationproviderapi

studio - El permiso ACCESS_COARSE_LOCATION otorga una precisión de torre celular en Android



last known location android studio (2)

Cuando solicita el permiso ACCESS_COARSE_LOCATION, el cliente de ubicación fusionada le dará una precisión de bloque de la ciudad, ese es el comportamiento previsto y está escrito en la documentación. Eche un vistazo here en "Especificar permisos de aplicación"
Lo que puedo sugerir es que utilice el proveedor de ubicación de Android normal (no la ubicación fusionada) e intente acceder al proveedor de RED. Debe darle la precisión de WIFI.

Estoy haciendo algunas pruebas con la función requestLocationUpdates() del FusedLocationApi . Estoy usando el PRIORITY_BALANCED_POWER_ACCURACY . La precisión de una manzana está bien para mí.

Cuando solicito el permiso ACCESS_FINE_LOCATION , obtengo una precisión de 100 m, lo cual es excelente con el GPS apagado. Como no necesito una precisión de GPS sino una precisión de bloque de ciudad, me gustaría solicitar solo el permiso ACCESS_COARSE_LOCATION . Sin embargo, cuando solicito el permiso ACCESS_COARSE_LOCATION , obtengo una precisión de 2 km. Parece que el dispositivo ya no usa el permiso de Wifi y solo una precisión de torre celular.

¿Cómo puedo tener una mejor precisión con el permiso ACCESS_COARSE_LOCATION ?

Nota: el GPS está deshabilitado en mi dispositivo de prueba.


Este es un problema interesante, y tenía la impresión de que usar ACCESS_COARSE_LOCATION usaría WiFi, ya que eso es lo que dice la documentación.

La documentación para ACCESS_COARSE_LOCATION establece:

Permite que una aplicación acceda a una ubicación aproximada derivada de fuentes de ubicación de red, como torres de telefonía móvil y Wi-Fi.

Entonces, lo puse a prueba, y los resultados son sorprendentes.

Aquí está el código que solía probar 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''

La primera prueba que hice fue con PRIORITY_BALANCED_POWER_ACCURACY , y no con WiFi. Tenga en cuenta que también deshabilité Always Allow Scanning , ya que dice:

Permita que Google Location Service y otras aplicaciones busquen redes Wi-Fi, incluso cuando el Wi-Fi está apagado

Entonces, eso ciertamente sesgaría los resultados si estuviera habilitado.

Tenga en cuenta que también tuve el Modo de ubicación configurado en Modo de ahorro de batería para todas las pruebas, por lo que la radio GPS estuvo apagada todo el tiempo.

Aquí están los resultados de PRIORITY_BALANCED_POWER_ACCURACY , ACCESS_COARSE_LOCATION , y no WiFi:

accuracy: 2000.0 lat: 37.78378378378378 lon: -122.40320943772021

Entonces, dice 2000 metros de precisión, y aquí está lo lejos que están las coordenadas reales, la flecha verde muestra dónde estoy realmente:

Luego, habilité el WiFi, volví a ejecutar la prueba y, sorprendentemente, ¡los resultados fueron exactamente los mismos!

accuracy: 2000.0 lat: 37.78378378378378 lon: -122.40320943772021

Luego, cambié a LocationRequest.PRIORITY_LOW_POWER en LocationRequest mientras mantenía android.permission.ACCESS_COARSE_LOCATION en el AndroidManifest.xml.

No wifi:

accuracy: 2000.0 lat: 37.78378378378378 lon: -122.40320943772021

Con WiFi:

accuracy: 2000.0 lat: 37.78378378378378 lon: -122.40320943772021

¡Los resultados fueron exactamente los mismos otra vez! El uso de PRIORITY_LOW_POWER tuvo los mismos resultados que el uso de PRIORITY_BALANCED_POWER_ACCURACY , ya que el estado de WiFi no pareció tener ningún efecto en la precisión de las coordenadas.

Luego, solo para cubrir todas las bases, cambié de nuevo a LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY , y cambié AndroidManifest.xml a ACCESS_FINE_LOCATION :

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

Primera prueba, sin WiFi:

accuracy: 826.0 lat: 37.7825458 lon: -122.3948752

Entonces, dice una precisión de 826 metros, y aquí está lo cerca que estaba en el mapa:

Entonces, encendí WiFi, y aquí está el resultado:

accuracy: 18.847 lat: 37.779679 lon: -122.3930918

Es literalmente en el lugar, como se puede ver en el mapa:

Parece que importa menos lo que use en su LocationRequest en el código Java, y más qué permiso que use en el AndroidManifest.xml, ya que los resultados aquí muestran claramente que al usar ACCESS_FINE_LOCATION , tener la radio WiFi encendida o apagada se convierte en una gran diferencia en la precisión, y también fue más precisa en general.

Ciertamente, parece que la documentación es un poco errónea, y que al usar android.permission.ACCESS_COARSE_LOCATION , tener la radio WiFi activada o desactivada no hace ninguna diferencia cuando su aplicación es la única que realiza solicitudes de ubicación.

Otra cosa que indica la documentación es que el uso de PRIORITY_BALANCED_POWER_ACCURACY permitirá que su aplicación se "enrolle" a las solicitudes de ubicación realizadas por otras aplicaciones. De la documentación:

Solo se les asignará la culpa de energía para el intervalo establecido por setInterval (long), pero aún pueden recibir ubicaciones activadas por otras aplicaciones a una tasa de hasta setFastestInterval (long).

Entonces, si el usuario abre Google Maps, de acuerdo con la documentación, su aplicación puede obtener una ubicación más precisa en ese momento. Esa es una de las ventajas principales de usar el nuevo Fused Location Provider en lugar de las API más antiguas, ya que disminuye la cantidad de batería agotada de su aplicación sin mucho trabajo de su parte.

Edición: realicé una prueba de esta funcionalidad para ver qué sucedería al usar ACCESS_COARSE_LOCATION .

Primera prueba: ACCESS_COARSE_LOCATION , PRIORITY_BALANCED_POWER_ACCURACY y WiFi en:

accuracy: 2000.0 lat: 37.78378378378378 lon: -122.38041129850662

Eso me puso en el agua, muy lejos de mi ubicación actual. Luego, salí de la aplicación de prueba, inicié Google Maps, que me ubicó exactamente donde estoy, y luego volví a iniciar la aplicación de prueba. La aplicación de prueba no pudo incorporarse a la ubicación de Google Maps, ¡y el resultado fue exactamente el mismo que antes!

accuracy: 2000.0 lat: 37.78378378378378 lon: -122.38041129850662

Lo volví a probar unas cuantas veces, solo para estar seguro, pero realmente parece que el uso de ACCESS_COARSE_LOCATION también desactiva la capacidad de las aplicaciones para "incorporarse" a las ubicaciones obtenidas por otras aplicaciones.

Parece que usar ACCESS_COARSE_LOCATION en el AndroidManifest.xml realmente paraliza la aplicación en términos de obtener datos de ubicación precisos.

En conclusión, lo único que realmente puede hacer es definir la mejor combinación de configuraciones que funcione para usted y su aplicación, y esperamos que los resultados de esta prueba puedan ayudarlo a tomar esa decisión.