update studio services play google fusedlocationproviderclient example android gps google-play-services android-location location-services

studio - location update android



Comportamiento inesperado del proveedor de localizaciĆ³n fusionado (4)

Así es como 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 intento pendiente ha sido invocado en segundo plano casi en los intervalos exactos solicitados ...

hasta ahora tan bueno.

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

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

el problema aún más grande: a veces, en ese caso, recibo devoluciones de llamadas de actualizaciones de ubicación a través de la intención pendiente, pero con la última ubicación que conocía (incluso si fue hace una hora, y hace mucho que estoy 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". La precisión del nivel de bloque se considera una precisión de aproximadamente 100 metros. El uso de una precisión aproximada como esta a menudo consume menos energía.

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

Otro tema impredecible e inquietante:

Cambié PRIORITY_BALANCED_POWER_ACCURACY a PRIORITY_HIGH_ACCURACY para ver cómo se comporta (durante 24 horas). Todos los intervalos se mantuvieron igual (intervalo de 10 minutos entre actualizaciones). la ubicación precisa fue recibida incluso en teléfonos sin red / tarjeta SIM, pero la batería se agotó rápidamente! cuando miré el historial de la batería, me sorprendió ver que la radio GPS estaba en modo de transmisión completa todo el tiempo. y también vi en mi registro que la ubicación se recibía cada minuto, incluso que solicité la ubicación cada diez minutos (no tengo ninguna otra aplicación instalada que abra el GPS para recibir ubicaciones ...)

Noté 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 recibe periódicamente 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 que la batería se agote.

Mis preguntas:

  • ¿Se supone que el proveedor de ubicación fusionada usa GPS si está configurado para recibir actualizaciones con PRIORITY_BALANCED_POWER_ACCURACY y no tiene ninguna información de WI-FI o torres celulares?

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

  • ¿Por qué recibo estas actualizaciones de ubicación engañosas que no son correctas? (como expliqué en la sección "problema aún mayor" ..

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


Las torres celulares cubren un área de varias millas, por lo que no son las mejores para obtener una ubicación. Observe la precisión de la ubicación cuando trabaja 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; } }

Puede poner un transmisor de radio en el estado de la red y, cuando no haya conexión, puede reiniciar su proveedor de ubicación con prioridad_de alta_que utilizará el GPS solo cuando el usuario tenga el GPS habilitado; de lo contrario, recurre al wifi y a las torres celulares.

<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; }


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

Una vez que obtenga la ubicación actualizada, desconecte el cliente de ubicación. No es necesario que siga funcionando durante todo el tiempo configurando el intervalo de tiempo en LocationRequest . En su lugar, puede invocar el proceso en cada intervalo de tiempo utilizando AlarmManager .

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

  • La radio GPS permanecerá abierta solo durante unos segundos mientras se recupera la ubicación porque se desconectará después de recibir la primera actualización de la ubicación. Por lo tanto, la radio GPS no permanecerá abierta todo el tiempo, por lo que se guardará la batería.
  • Podrás obtener una nueva ubicación en cada 10 minutos sin perder el tiempo con la ubicación antigua o algo así.

Espero que sea util.


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

Respuestas:

1) PRIORITY_BALANCED_POWER_ACCURACY not utiliza GPS.

2) Usa 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; } }


Para las preguntas especificadas,

1. ¿Se supone que el proveedor de ubicación fusionada utiliza GPS si está configurado para recibir actualizaciones con PRIORITY_BALANCED_POWER_ACCURACY y no tiene ninguna información de WI-FI o torres celulares? Y
2. Si lo hace, entonces, ¿qué estoy haciendo mal?

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

4. ¿Por qué la radio GPS está abierta todo el tiempo en lugar de estar abierta durante el intervalo de 10 minutos cuando usé 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 en 1 minuto. Por lo que setFastestInterval entendido, el setFastestInterval tiene prioridad sobre setInterval cuando el valor del intervalo más rápido tiene una duración más corta que el valor de setInterval.
En tu caso, 1 minuto contra 10.
Acerca de no tener otras aplicaciones instaladas que activan actualizaciones de ubicación, solo se ofrece como un ejemplo y no se especifica solo ese caso explícitamente.

Esto controla la velocidad más rápida a la que su aplicación recibirá actualizaciones de ubicación, que pueden ser más rápidas que setInterval (long) en algunas situaciones (por ejemplo, si otras aplicaciones están activando actualizaciones de ubicación).

Entonces, lo que sucede es que con PRIORITY_HIGH_ACCURACY , solicita la location en el intervalo más rápido establecido: 1 minuto, mediante el uso de GPS (tipo de uso exclusivo).

3. ¿Por qué recibo estas actualizaciones de ubicación engañosas que no son correctas? (como expliqué en la sección "problema aún mayor" ..

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

El consumo de batería se debió a la combinación de GPS y actualizaciones de 1 minuto. Intente establecer el intervalo más rápido en 5 o 10 minutos, si es adecuado para su implementación, pero PRIORITY_BALANCED_POWER puede no ayudarlo si necesita una ubicación absolutamente precisa. Normalmente agrego un cheque para la ubicación obtenida en onLocationChanged y, dependiendo de eso, cambio la prioridad en LocationRequest. Sin duda, es útil obtener una ubicación en general, a menos que esté dentro de un edificio sin línea de visión para que el GPS y la red Wifi estén apagados.