Fused Location Provider comportamiento inesperado

Esto es cómo registro mi aplicación para recibir actualizaciones de ubicación:

mLocationRequest = LocationRequest.create(); mLocationRequest.setInterval(Consts.ONE_MINUTE * 10); mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY); mLocationRequest.setFastestInterval(Consts.ONE_MINUTE); Builder builder = new GoogleApiClient.Builder(context); builder.addApi(ActivityRecognition.API); mGoogleApiClient = builder.addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .build(); mGoogleApiClient.connect(); .... .... @Override public void onConnected(Bundle connectionHint) { LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, locationUpdatespendingInent); } 

Mi intención pendiente fue invocada en segundo plano casi en los intervalos requeridos exactos …

Hasta aquí todo bien.

El problema: cuando WIFI está deshabilitado / no conectado a ninguna red, o cuando no hay datos de red 3G / 4G habilitado – el proveedor de ubicación fusionado no proporciona nuevas actualizaciones de ubicación !!

Mi configuración de acceso a la ubicación está activada y se comprueban los satélites GPS y la ubicación de la red WI-FI y móvil.

El problema aún más grande: a veces en ese caso, recibo las devoluciones de las actualizaciones de la ubicación a través de la intención pendiente, pero con la última ubicación que sabía (incluso si era hace una hora, y estoy mucho tiempo lejos millas lejos de ese lugar)

De acuerdo con la documentación de PRIORITY_BALANCED_POWER_ACCURACY :

Se utiliza con setPriority (int) para solicitar la precisión del nivel de "bloque". Se considera que la precisión del nivel de bloque es de unos 100 metros de precisión. El uso de una precisión gruesa como ésta a menudo consume menos energía.

Espero que el proveedor de ubicación fusionado abra el GPS cuando no tenga otra opción, o al menos no proporcionará una nueva ubicación si no tiene ninguna.

Otra cuestión impredecible e inquietante:

He cambiado PRIORITY_BALANCED_POWER_ACCURACY a PRIORITY_HIGH_ACCURACY para ver cómo se comporta (durante 24 horas). Todos los intervalos permanecieron iguales (intervalo de 10 minutos entre actualizaciones). La localización exacta recibió de hecho incluso en los teléfonos sin la tarjeta de la red / del sim, pero – la batería drenada hacia fuera rápidamente! Cuando miré en la historia de la batería, me sorprendió ver que la radio GPS estaba en modo de transmisión completa todo el tiempo !!!! Y vi también en mi registro que loction se recibió cada minuto, incluso que solicité la ubicación cada diez minutos (no tengo ninguna otra aplicación instalada que abre GPS para recibir ubicaciones ..)

He notado este comportamiento en varios dispositivos (como Moto X 2013, HTC One X, Nexus 5), todos con los últimos servicios de Google Play (versión 6.1.11) y Android KITKAT 4.4.4

Mi aplicación depende mucho de la ubicación actual del usuario y periódicamente recibe actualizaciones de ubicación en el intervalo especificado, siempre y cuando el usuario haya iniciado sesión, por lo que no quiero usar el modo PRIORITY_HIGH_ACCURACY para evitar el agotamiento de la batería.

Mis preguntas:

  • Es el proveedor de ubicación fusionado suponga utilizar GPS en absoluto si se establece para recibir actualizaciones con PRIORITY_BALANCED_POWER_ACCURACY y no tiene ninguna WI-FI o información de torres de celda?

  • Si lo hace, entonces ¿qué estoy haciendo mal?

  • ¿Por qué estoy recibiendo estas actualizaciones de ubicación engañosas que no son correctas? (Como he explicado en el "problema aún más grande" sección.

  • ¿Por qué la radio GPS está abierta todo el tiempo en lugar de ser abierta durante los 10 minutos de intervalo cuando utilicé el parámetro PRIORITY_HIGH_ACCURACY ? (No tengo otras aplicaciones instaladas que activan las actualizaciones de ubicación más rápido ..)

Para las preguntas especificadas,

1. ¿ Es el proveedor de ubicación fusionado supone utilizar GPS en absoluto si se establece para recibir actualizaciones con PRIORITY_BALANCED_POWER_ACCURACY y no tiene WI-FI o información de torres de celda? &
2. si lo hace, entonces ¿qué estoy haciendo mal?

Al parecer, no se especifica ninguna fuente explícitamente única en ningún lugar dentro de la documentación. Con cualquiera de las opciones PRIORITY , incluso a través del código, la "fuente" de la location obtenida está "fusionada".
[ location.getProvider() devuelve: "fusionado"]
He visto que el GPS se utiliza sólo cuando el LocationRequest tiene PRIORITY_HIGH_ACCURACY. Por lo tanto, no utiliza GPS bajo otras condiciones.

4. ¿por qué la radio GPS está abierta todo el tiempo en vez de ser abierta durante los 10 minutos de intervalo cuando utilicé el parámetro PRIORITY_HIGH_ACCURACY? (No tengo otras aplicaciones instaladas que activan las actualizaciones de ubicación más rápido ..)

El intervalo más rápido se ha establecido durante 1 minuto. Por lo que he entendido, el setFastestInterval se da precedencia sobre setInterval cuando el valor para el intervalo más rápido es más corto en duración que el valor de setInterval.
En su caso, 1 minuto contra 10.
Acerca de no tener otras aplicaciones instaladas que desencadena actualizaciones de ubicación, es sólo dado como un ejemplo y no se especifica que sólo ese caso explícitamente.

Esto controla la velocidad más rápida en la que su aplicación recibirá actualizaciones de ubicación, que podría ser más rápido que setInterval (largo) en algunas situaciones (por ejemplo, si otras aplicaciones activan actualizaciones de ubicación).

Por lo tanto, lo que sucede es con PRIORITY_HIGH_ACCURACY , que solicita la location en el conjunto de intervalo más rápido – 1min, mediante GPS (tipo de exclusivamente).

3. ¿por qué estoy recibiendo esta localización errónea de actualizaciones que no son correctas? (Como he explicado en el "problema aún más grande" sección.

Necesidad de comprobar el código de pendingIntent mecanismo también. Aunque podría haber algunas cosas para tomar nota de:
Puede agregar un location.getTime() para asegurar y verificar la hora de la ubicación obtenida. Es muy probable que no se esté actualizando, si no hay torres de celdas wifi en el rango y se utiliza PRIORITY_BALANCED_POWER_ACCURACY .
Una precisión a nivel de bloque de la ubicación en el primer lugar, que se utiliza cuando "lastKnown" se llama no ayudaría.

El consumo de la batería se debió a la combinación de GPS y actualizaciones de 1 minuto. Trate de establecer el intervalo más rápido como 5 o 10 minutos, si eso es adecuado para su implementación, pero PRIORITY_BALANCED_POWER puede no ayudar si necesita una ubicación absolutamente precisa. Normalmente agrego una comprobación para la localización obtenida en onLocationChanged y dependiendo de eso, cambie la prioridad en LocationRequest. Ayuda en, seguramente, la obtención de una ubicación en general, a menos que esté dentro de un edificio sin línea de visión para GPS y Wifi-Red están apagados.

Le sugiero que utilice AlarmManager y FusedLocationProvider juntos de tal manera que su alarma de incendio AlarmManager cada 10 minutos con el fin de iniciar las actualizaciones de ubicación.

Una vez que obtenga la ubicación actualizada, desconecte el cliente de ubicación. No es necesario mantenerlo en funcionamiento todo el tiempo estableciendo el intervalo de tiempo en LocationRequest . En su lugar, puede invocar el proceso en cada intervalo de tiempo mediante AlarmManager .

En este tipo de mecanismo, tendrá los siguientes beneficios que resolverán sus problemas:

  • La radio del GPS permanecerá abierta solamente por algunos segundos mientras que recupera la localización porque usted va a desconectar después de conseguir la primera actualización de la localización. Por lo tanto la radio del GPS no permanecerá abierta todo el tiempo así que la batería será ahorrada.
  • Usted será capaz de obtener nueva ubicación en cada 10 minutos sin jugar con la antigua ubicación o algo así.

Espero que sea util.

Las torres de la célula cubren una zona de varias millas por lo que no son los mejores para obtener una ubicación de. Observe la precisión de la ubicación cuando trabaje con ubicaciones.

 @Override public void onLocationChanged(Location location) { //it happens if (location == null) { return; } // all locations should have an accuracy if (!location.hasAccuracy()) { return; } // if its not accurate enough don't use it // this value is in meters if (location.getAccuracy() > 200) { return; } } 

Usted podría poner un broadcastreceiver en el estado de la red y cuando no hay ninguna conexión usted podría reiniciar su abastecedor de la localización con priority_high_accuracy que utilizará el GPS solamente cuando el usuario tiene el GPS permitido de otra manera cae detrás en las torres del wifi y de la célula.

 <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/> /** Checks whether the device currently has a network connection */ private boolean isDeviceOnline() { ConnectivityManager connMgr = (ConnectivityManager) activity .getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = connMgr.getActiveNetworkInfo(); if (networkInfo != null && networkInfo.isConnected()) { return true; } return false; } 

Para la actualización de las coordenadas GPS puede utilizar también los proveedores de GPS y WI-FI. Para actualizar el uso de la posición así como el parámetro de distancia mínima. Le proporcionaré un pequeño ejemplo de servicio GPS.

Respuestas:

1) PRIORITY_BALANCED_POWER_ACCURACY no utiliza GPS.

2) Utilice GPS y WI-FI para detectar la ubicación.

3) PRIORITY_BALANCED_POWER_ACCURACY probablemente debido a que no hay WI-FI en el área.

Ejemplo de código:

 public class GPSservice extends Service implements LocationListener { private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 2; private static final long MIN_TIME_BW_UPDATES = 1000 * 1; double latitude, longitude; boolean isGPSEnabled = false; boolean isNetworkEnabled = false; boolean canGetLocation = false; Location location; protected LocationManager locationManager; @Override public IBinder onBind(Intent intent) { return null; } @Override public int onStartCommand(Intent intent, int flags, int startId) { getLocation(); return super.onStartCommand(intent, flags, startId); } @Override public void onLocationChanged(Location location) { new LocationReceiver(location, getApplicationContext()); } @Override public void onStatusChanged(String provider, int status, Bundle extras) { } @Override public void onProviderEnabled(String provider) { } @Override public void onProviderDisabled(String provider) { } public Location getLocation() { try { locationManager = (LocationManager) getSystemService(LOCATION_SERVICE); // getting GPS status isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); if (!isGPSEnabled && !isNetworkEnabled) { Log.d("Network", "NO network"); } else { this.canGetLocation = true; if (isNetworkEnabled) { locationManager.requestLocationUpdates( LocationManager.NETWORK_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this); Log.d("Network", "Network"); if (locationManager != null) { location = locationManager .getLastKnownLocation(LocationManager.NETWORK_PROVIDER); if (location != null) { latitude = location.getLatitude(); longitude = location.getLongitude(); } } } if (isGPSEnabled) { if (location == null) { locationManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this); Log.d("GPS Enabled", "GPS Enabled"); if (locationManager != null) { location = locationManager .getLastKnownLocation(LocationManager.GPS_PROVIDER); if (location != null) { latitude = location.getLatitude(); longitude = location.getLongitude(); } } } } } } catch (Exception e) { e.printStackTrace(); } return location; } } 
  • ¿Cómo obtener la cantidad de satélites utilizados en gps en android?
  • Sigo obteniendo una ubicación incorrecta en Android
  • Error de tiempo de ejecución: java.lang.IllegalArgumentException: provider = gps
  • Usar ubicación simulada sin configurarla en la configuración
  • Obtener la ubicación / posición más precisa? (GPS / Kalman / Android)
  • ¿Cómo obtener sólo la ubicación de GPS con sencha touch?
  • ¿Encontrando las coordenadas cartesianas de otro smartphone?
  • Android GPS retrasa al enviar a la base de datos
  • El receptor / receptor de Gps despierta CPU
  • Obtener ubicación * gruesa * del proveedor de GPS en Android
  • Cómo obtener el nombre de satélite o el número cuando estamos recibiendo la ubicación a través de GPS en Android?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.