FusedLocationApi.getLastLocation siempre nulo

Me gustaría simplemente recuperar la ubicación del dispositivo en mi proyecto de Android y para hacerlo uso el enfoque de servicios de reproducción:

protected synchronized void buildGoogleApiClient() { mGoogleApiClient = new GoogleApiClient.Builder( MainSearchActivity.this ) .addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() { @Override public void onConnected( Bundle bundle ){ Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); if( location == null ){ LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, new LocationListener() { @Override public void onLocationChanged(Location location) { lastLocation = location; } }); } } @Override public void onConnectionSuspended( int i ){ } }) .addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() { @Override public void onConnectionFailed( ConnectionResult connectionResult ){ if( connectionResult.hasResolution() ){ try { // Start an Activity that tries to resolve the error connectionResult.startResolutionForResult(MainSearchActivity.this, CONNECTION_FAILURE_RESOLUTION_REQUEST); }catch( IntentSender.SendIntentException e ){ e.printStackTrace(); } }else{ Utils.logger("Location services connection failed with code " + connectionResult.getErrorCode(), Utils.LOG_DEBUG ); } } }) .addApi(LocationServices.API) .build(); mGoogleApiClient.connect(); } public Location retrieveLastLocation(){ Location loc = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); if( loc == null) { } return loc; //TODO: What if loc is null? } 

pero la variable loc SIEMPRE es nula. Es como tal en diferentes teléfonos, cada vez. También lastLocation, que trato de asignar en el onLocationChanged, nunca cambia. Siempre nulo.

Estos son los permisos que establecí para la aplicación

         

Simplemente no lo entiendo: ¿por qué los LocationServices no pueden recuperar una posición? Tengo todas las configuraciones de geolocalización habilitadas en los tres dispositivos que he probado: – /

Gracias por cualquier ayuda

El Location Provider fusionadas solo mantendrá la ubicación de fondo si al menos un cliente está conectado a ella. Ahora, solo encender el servicio de ubicación no garantiza almacenar la última ubicación conocida.

Una vez que el primer cliente se conecta, inmediatamente intentará obtener una ubicación. Si su actividad es el primer cliente que se conecta y getLastLocation() se invoca de inmediato en onConnected() , puede que no sea suficiente tiempo para que llegue la primera ubicación.

Le sugiero que inicie la aplicación Mapas primero, para que haya al menos alguna ubicación confirmada y luego pruebe su aplicación.

Creo que hay una pequeña falla que no es visible para mí en el código que se muestra.

El mGoogleApiClient está creado, pero parece no estar conectado. Puedes verificarlo llamando a mGoogleApiClient.isConnected() .

Puede anular el método onStart y llamar a connect allí. O puede anular onResume() en caso de que quiera acceder a la ubicación siempre que su actividad sea visible.

  @Override protected void onStart() { super.onStart(); if (mGoogleApiClient != null) { mGoogleApiClient.connect(); } } 

Primero, crea un objeto LocationRequest :

  // Create the LocationRequest object mLocationRequest = LocationRequest.create() .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY) .setInterval(10 * 1000) // 10 seconds, in milliseconds .setFastestInterval(1 * 1000); // 1 second, in milliseconds 

Luego, asegúrese de que el usuario haya otorgado permiso para usar la ubicación. De ser así, obtenga la ubicación de requestLocationUpdates siguiente manera:

 void getLocation() { Location location = null; if (ContextCompat.checkSelfPermission(activity, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 1); /*TODO!! INSERT CODE TO PROMPT USER TO GIVE PERMISSION*/ } else { LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this); } mLastLocation = location; LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient,this); } 

Asegúrese de eliminar las actualizaciones si solo necesita una ubicación sin supervisión constante. De esta manera, nunca obtendrás una Location nula.

Para obtener más información, vaya a http://blog.teamtreehouse.com/beginners-guide-location-android .

Si getLastLocation () siempre devuelve nulo, pruebe este truco. Lo he usado para resolver mi problema. Implemente LocationListener (importe com.google.android.gms.location.LocationListener) en su actividad.

 protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_splash); Context mContext = this; manager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE); createLocationRequest(); mGoogleApiClient = new GoogleApiClient.Builder(mContext) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .addApi(LocationServices.API) .build(); mGoogleApiClient.connect(); } private void createLocationRequest(){ mLocationRequest = LocationRequest.create(); mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); mLocationRequest.setInterval(SET_INTERVAL); mLocationRequest.setFastestInterval(FASTEST_INTERVAL); } 

onStart o onResume (prefiero onResume)

 @Override protected void onResume() { super.onResume(); if (manager.isProviderEnabled(LocationManager.GPS_PROVIDER) ) { if (mGoogleApiClient != null) { mGoogleApiClient.connect(); } }else{ // Showyourmesg(); } } @Override protected void onPause() { super.onPause(); if (mGoogleApiClient != null) { mGoogleApiClient.disconnect(); } } protected void startLocationUpdates(){ LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest,this); } protected void stopLocationUpdates() { LocationServices.FusedLocationApi.removeLocationUpdates( mGoogleApiClient, this); } 

Ahora, en su método onLocationChanged, verifique si googleApiClient está conectado o no. Si está conectado, desconéctelo y vuelva a conectarse.

 @Override public void onLocationChanged(Location location) { Log.d("SplashAct", "LocatinChngListner, loc: " + location.getLatitude() + "," + location.getLongitude()); if (mGoogleApiClient != null) if (mGoogleApiClient.isConnected() || mGoogleApiClient.isConnecting()){ mGoogleApiClient.disconnect(); mGoogleApiClient.connect(); } else if (!mGoogleApiClient.isConnected()){ mGoogleApiClient.connect(); } } 

Y finalmente, en su método onContected ()

 @Override public void onConnected(Bundle bundle) { Log.d("ACTIVITY", "ApiClient: OnConnected"); mLastLocation = LocationServices.FusedLocationApi.getLastLocation( mGoogleApiClient); if (mLastLocation == null){ startLocationUpdates(); // bind interface if your are not getting the lastlocation. or bind as per your requirement. } if (mLastLocation != null){ while (latitude == 0 || longitude == 0){ pDialog.setMessage("Getting Location"); pDialog.show(); latitude = mLastLocation.getLatitude(); longitude = mLastLocation.getLongitude(); if (latitude != 0 && longitude != 0){ stopLocationUpdates(); // unbind the locationlistner here or wherever you want as per your requirement. pDialog.dismiss(); // location data received, dismiss dialog, call your method or perform your task. } } } } 

Intentamos conectarnos repetidamente con googleApiClient, incluso si ya está conectado, de modo que podamos obtener los datos de lastLocation. Esto dependerá de los intervalos de LocationRequest. También puede obtener los datos de ubicación en onLocationChanged y realizar su tarea desde allí.

Como se indica en esta publicación, el Proveedor de ubicaciones fusionadas solo mantendrá la ubicación de fondo si al menos un cliente está conectado a ella.

Pero no queremos lanzar la aplicación Maps para obtener la última ubicación, y tampoco podemos decir que nuestros usuarios inicien la aplicación Maps para obtener la última ubicación.

Lo que tenemos que hacer es

  1. Tenemos que solicitar la actualización de ubicación de FusedLocationProviderClient
  2. Entonces podemos obtener la última ubicación de FusedLocationProviderClient , no sería nulo.

Solicitud de ubicación

 LocationRequest mLocationRequest = LocationRequest.create(); mLocationRequest.setInterval(60000); mLocationRequest.setFastestInterval(5000); mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); LocationCallback mLocationCallback = new LocationCallback() { @Override public void onLocationResult(LocationResult locationResult) { if (locationResult == null) { return; } for (Location location : locationResult.getLocations()) { if (location != null) { //TODO: UI updates. } } } }; LocationServices.getFusedLocationProviderClient(context).requestLocationUpdates(mLocationRequest, mLocationCallback, null); 

Obtener la última ubicación

 LocationServices.getFusedLocationProviderClient(context).getLastLocation().addOnSuccessListener(new OnSuccessListener() { @Override public void onSuccess(Location location) { //TODO: UI updates. } }); 

Para obtener el mejor resultado al inicio de la solicitud de Actividad para la actualización de la ubicación, y luego puede obtener la última ubicación.

Si está utilizando Android Marshmallow (API 23) o una versión más reciente de Android, puede enfrentar el mismo problema porque no se concede el permiso . Debe solicitar explícitamente el permiso en tiempo de ejecución para la ubicación o, si se trata de un proyecto de prueba, puede otorgar permiso de ubicación desde la configuración de la aplicación en su teléfono.

Aquí está la respuesta exacta y la explicación.

LocationClient getLastLocation () return null

Esto está relacionado con la respuesta de Amit K. Saha, pero para mí, en uno de mis dispositivos Lollipop , seguí recibiendo null . Así que abrí la aplicación de mapas y obtuve la siguiente pantalla pidiéndome que activara todo ese jazz para mejorar mi ubicación.

Una vez que lo hice una vez, mi dispositivo pudo recibir la ubicación con solo una llamada para getLastLocation() ;

Supongo que entonces uno tendría que pedir estos permisos en la instalación de la aplicación para los usuarios que aún no hayan usado su aplicación de mapas.

enter image description here