LocationClient getLastLocation () return null

Al igual que las preguntas que alguien hizo antes de probar uno de los nexus s (4.0.4 con google play service disponible) y avd (4.2.2 con google api), en ambos casos, ubicaciónclienteLocalizar getLastLocation() siempre devuelve null .

 public class MainActivity extends Activity implements LocationListener, GooglePlayServicesClient.ConnectionCallbacks, GooglePlayServicesClient.OnConnectionFailedListener { private LocationClient mLocationClient; private LocationRequest mLocationRequest; boolean mUpdatesRequested = false; boolean mConnected = false; SharedPreferences mPrefs; SharedPreferences.Editor mEditor; private TextView mText; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mText = (TextView) findViewById(R.id.text); mLocationRequest = LocationRequest.create(); mLocationRequest .setInterval(LocationUtils.UPDATE_INTERVAL_IN_MILLISECONDS); mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); mLocationRequest .setFastestInterval(LocationUtils.FAST_INTERVAL_CEILING_IN_MILLISECONDS); mUpdatesRequested = false; mPrefs = getSharedPreferences(LocationUtils.SHARED_PREFERENCES, Context.MODE_PRIVATE); mEditor = mPrefs.edit(); mLocationClient = new LocationClient(this, this, this); } @Override public void onStart() { super.onStart(); /* * Connect the client. Don't re-start any requests here; instead, wait * for onResume() */ mLocationClient.connect(); } @Override protected void onResume() { super.onResume(); // If the app already has a setting for getting location updates, get it if (mPrefs.contains(LocationUtils.KEY_UPDATES_REQUESTED)) { mUpdatesRequested = mPrefs.getBoolean( LocationUtils.KEY_UPDATES_REQUESTED, false); // Otherwise, turn off location updates until requested } else { mEditor.putBoolean(LocationUtils.KEY_UPDATES_REQUESTED, false); mEditor.commit(); } } @Override public void onStop() { // If the client is connected if (mLocationClient.isConnected()) { stopPeriodicUpdates(); } // After disconnect() is called, the client is considered "dead". mLocationClient.disconnect(); super.onStop(); } @Override public void onPause() { // Save the current setting for updates mEditor.putBoolean(LocationUtils.KEY_UPDATES_REQUESTED, mUpdatesRequested); mEditor.commit(); super.onPause(); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } public void getLocation(View v) { // If Google Play Services is available if (isGooglePlayServicesAvailable()) { if (!mConnected) mText.setText("location client is not connected to service yet"); else { // Get the current location Location currentLocation = mLocationClient.getLastLocation(); // Display the current location in the UI mText.setText(LocationUtils.getLocationString(currentLocation)); } } } private boolean isGooglePlayServicesAvailable() { // Check that Google Play services is available int resultCode = GooglePlayServicesUtil .isGooglePlayServicesAvailable(this); // If Google Play services is available if (ConnectionResult.SUCCESS == resultCode) { // In debug mode, log the status Log.d(LocationUtils.APPTAG, "google play service is available"); // Continue return true; // Google Play services was not available for some reason } else { // Display an error dialog Dialog dialog = GooglePlayServicesUtil.getErrorDialog(resultCode, this, 0); if (dialog != null) { Log.e(LocationUtils.APPTAG, "google play service is unavailable"); } return false; } } private void stopPeriodicUpdates() { mLocationClient.removeLocationUpdates(this); // mConnectionState.setText(R.string.location_updates_stopped); } @Override public void onConnectionFailed(ConnectionResult arg0) { mConnected = false; Log.d(LocationUtils.APPTAG, "connection failed"); } @Override public void onConnected(Bundle arg0) { mConnected = true; Log.d(LocationUtils.APPTAG, "location client connected to the location server"); LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE); lm.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER, 0, 0, new android.location.LocationListener() { @Override public void onStatusChanged(String provider, int status, Bundle extras) {} @Override public void onProviderEnabled(String provider) {} @Override public void onProviderDisabled(String provider) {} @Override public void onLocationChanged(final Location location) { } }); Log.d(LocationUtils.APPTAG, "done trying to get location"); } @Override public void onDisconnected() { // TODO Auto-generated method stub mConnected = false; Log.d(LocationUtils.APPTAG, "location client disconnected from the location server"); } @Override public void onLocationChanged(Location arg0) {} } 

la mayoría de ellos provienen de ejemplos dados por google. En el código anterior, hava intentado el método así:

 LocationRequest request = LocationRequest.create(); request.setNumUpdates(1); mLocationClient.requestLocationUpdates(request, this); 

y

 LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE); lm.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER, 0, 0, new android.location.LocationListener() { @Override public void onStatusChanged(String provider, int status,Bundle extras) {} @Override public void onProviderEnabled(String provider) {} @Override public void onProviderDisabled(String provider) {} @Override public void onLocationChanged(final Location location) {} }); 

En onConnected() antes de llamar a getLastLocation() , pero todavía no recibes suerte. ¿Dónde está el error? Gracias de antemano.

Actualmente, el Fused Location Provider solo mantendrá la ubicación de fondo si al menos un cliente está conectado a ella. 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 llama a getLastLocation() inmediato en onConnected() , puede que no sea suficiente tiempo para que onConnected() la primera ubicación.

Tuve el mismo problema al seguir las instrucciones del tutorial . En el teléfono funcionaba y en el emulador (Genymotion) no funcionaba.

Solución

En su AndroidManifest.xml, cambie esto:

  

a esto:

  

… y obtienes la ubicación de inmediato. No es necesario cambiar su código (para escuchar las actualizaciones de ubicación).

El problema también puede deberse a que su dispositivo no tiene habilitada la opción “Wi-Fi y ubicación de red móvil”.

LocationClient (el proveedor de ubicación fusionada) usa tanto GPS como WiFi. El GPS tarda un rato en encontrar su ubicación, mientras que el wifi es mucho más rápido. Sin embargo, si alguno de estos 2 servicios está conectado, se llamará al método de callback en Conectado. Y si intenta llamar a LocationClient.getLastLocation () en el método onConnected de inmediato, es muy probable que obtenga un valor nulo si su servicio de ubicación wifi está desactivado. Es solo porque el GPS simplemente no es lo suficientemente rápido.

Para resolver el problema por ti mismo localmente, habilita “Wi-Fi y ubicación de red móvil”. Puede hacerlo yendo a “Configuración> Personal> Acceso a la ubicación> Wi-Fi y la ubicación de la red móvil”.

Sin embargo, si desea resolver el problema para los usuarios de su aplicación, será mejor que compruebe si getLastLocation () devuelve null. Si lo hace, solicite a su usuario que habilite el servicio tal como lo hace google map.

Con suerte, eso ayuda.

Estaba enfrentando un problema similar.

Llame a mLocationClient.getLastLocation() en onConnected o después de que se haya establecido Connection to Google Play Services. Si llama a este método antes de que se conecte Location Client, la ubicación devuelta sería null .

Puede verificar si el cliente de ubicación está conectado por mLocationClient.isConnected() .

Espero que esto ayude.

Debe verificar si el usuario ha habilitado la ubicación a través de Wi-Fi / GSM o GPS. Si no hay ningún proveedor de ubicación disponible, obtienes null .

Este código muestra la pantalla con la configuración de ubicación:

 startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)); 

Esta es la solución que funciona exactamente, probablemente en circunstancias ligeramente diferentes. Pero quería agregar algunos pequeños pasos de explicación para que cualquiera obtenga los conceptos exactos:

1) onCreate () del Componente Android (por ejemplo, Actividad , Fragmento o Servicio . Nota: Not IntentService ), comstack y luego conecta el GoogleApiClient como se muestra a continuación.

 buildGoogleApiClient(); mGoogleApiClient.connect(); 

donde, la implementación de buildGoogleApiClient () es,

 protected synchronized void buildGoogleApiClient() { Log.i(TAG, "Building GoogleApiClient"); mGoogleApiClient = new GoogleApiClient.Builder(this) .addApi(LocationServices.API) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .build(); } 

Más adelante onDestroy (), puede desconectar GoogleApiClient como,

 @Override public void onDestroy() { Log.i(TAG, "Service destroyed!"); mGoogleApiClient.disconnect(); super.onDestroy(); } 

El paso 1 asegura que construye y conecta el GoogleApiClient.

1) La primera instancia de GoogleApiClient se conecta en el método onConnected (). Ahora, su próximo paso debería ser el método Connect ().

 @Override public void onConnected(@Nullable Bundle bundle) { Log.i(TAG, "GoogleApiClient connected!"); buildLocationSettingsRequest(); createLocationRequest(); location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); Log.i(TAG, " Location: " + location); //may return **null** because, I can't guarantee location has been changed immmediately } 

Arriba, llamó a un método createLocationRequest () para crear una solicitud de ubicación. El método createLocationRequest () se ve a continuación.

 protected void createLocationRequest() { //remove location updates so that it resets LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this); //Import should not be **android.Location.LocationListener** //import should be **import com.google.android.gms.location.LocationListener**; mLocationRequest = new LocationRequest(); mLocationRequest.setInterval(10000); mLocationRequest.setFastestInterval(5000); mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); //restart location updates with the new interval LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this); } 

3) Ahora, en la retrollamada onLocationChange () de la interfaz LocationListener, obtienes una nueva ubicación.

 @Override public void onLocationChanged(Location location) { Log.i(TAG, "Location Changed!"); Log.i(TAG, " Location: " + location); //I guarantee,I get the changed location here } 

Obtienes el resultado así en Logcat: 03-22 18: 34: 17.336 817-817 / com.LiveEarthquakesAlerts I / LocationTracker: Ubicación: Ubicación [fusionado 37.421998, -122.084000 acc = 20 et = + 15m35s840ms alt = 0.0]

Para poder hacer estos tres pasos, debe haber configurado su build.gradle de la siguiente manera:

  compile 'com.google.android.gms:play-services-location:10.2.1' 

Me enfrenté a problemas similares en mis pruebas con teléfonos Samsung (Android muy personalizado y sin soporte para desarrolladores).

LocationManager y LocationClient no obtienen el GPS de los proveedores. Deben ser kickstart cada vez que necesite la ubicación de ellos. Haga esto antes de las llamadas a LocationManager.getLastKnownLocation O LocationClient.getLastLocation . Estas API volverán.

 YOUR_APPLICATION_CONTEXT.getLocationManager().requestLocationUpdates( LocationManager.NETWORK_PROVIDER, 0, 0, new LocationListener() { @Override public void onStatusChanged(String provider, int status, Bundle extras) { } @Override public void onProviderEnabled(String provider) { } @Override public void onProviderDisabled(String provider) { } @Override public void onLocationChanged(final Location location) { } }); 

En las versiones SDK 23

También deberá solicitar explícitamente el permiso de ubicación durante el tiempo de ejecución , según https://developer.android.com/training/permissions/requesting.html , además de tenerlo en el archivo de manifiesto.

No se producirá ningún error explícito si no tiene los permisos durante el tiempo de ejecución, el proveedor de la ubicación simplemente devolverá nulo.

Ayudaría si Google documentara esto, y también lanzara una excepción en lugar de simplemente devolver el nulo. Regresar nulo es lo menos útil que se puede hacer en esta situación.

También estaba enfrentando el mismo problema en mi aplicación, y lo único que faltaba era que la aplicación solo solicitaba ACCESS_COARSE_LOCATION y no ACCESS_FINE_LOCATION. Agregué el permiso posterior y todo funcionó bien.

La geolocalización del servicio Google play no puede funcionar sin conexión a Internet, de manera indiferente para el GPS. Por lo tanto, verifique la aplicación con los datos móviles encendidos.

Solo necesita una solicitud de actualización para la ubicación. Si con 26 permiciones de Android SDK está bien:

 private void setLocation(Context context) { GoogleApiClient googleApiClient = new GoogleApiClient.Builder(context) .addApi(LocationServices.API).build(); googleApiClient.connect(); locationRequest = LocationRequest.create(); locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); locationRequest.setInterval(2000); locationRequest.setFastestInterval(2000); LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder().addLocationRequest(locationRequest); builder.setAlwaysShow(true); PendingResult result = LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build()); result.setResultCallback(new ResultCallback() { @Override public void onResult(LocationSettingsResult result) { final Status status = result.getStatus(); switch (status.getStatusCode()) { case LocationSettingsStatusCodes.SUCCESS: showMessage(" All location settings are satisfied."); mGoogleApiClient = new GoogleApiClient.Builder(MainActivity.this) .addApi(LocationServices.API) .addConnectionCallbacks(connectionCallbacks) .addOnConnectionFailedListener(connectionFailedListener) .build(); mGoogleApiClient.connect(); break; case LocationSettingsStatusCodes.RESOLUTION_REQUIRED: la(" Location settings are not satisfied. Show the user a dialog to upgrade location settings "); try { // Show the dialog by calling startResolutionForResult(), and check the result // in onActivityResult(). status.startResolutionForResult(MainActivity.this, REQUEST_CHECK_SETTINGS); } catch (IntentSender.SendIntentException e) { showMessage("PendingIntent unable to execute request."); } break; case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE: showMessage("Location settings are inadequate, and cannot be fixed here. Dialog not created."); break; } } }); } 

y en el método de callback conectado:

  @Override public void onConnected(@Nullable Bundle bundle) { la(3232); if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { return; } mLastLocation = LocationServices.FusedLocationApi.getLastLocation( mGoogleApiClient); if(null==mLastLocation){// !!!!!!!!!!!! here it can happen !!!!!!! LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, locationRequest, new LocationListener() { @Override public void onLocationChanged(Location location) { mLastLocation = location; locationWasFound = true; sevumPora.setLocation(mLastLocation); mGoogleApiClient.disconnect(); } }); return; } locationWasFound = true; sevumPora.setLocation(mLastLocation); mGoogleApiClient.disconnect(); } 

Corro y funciona perfectamente en el dispositivo Nexus 7. Ustedes, por error, escribieron la versión anterior LocationListener que no se usa con la nueva API.

Tienes que configurar el nuevo LocationListener.

Necesitas importar esta clase y luego probar.

 import com.google.android.gms.location.LocationListener; 

Y anula el único método según la nueva API

 @Override public void onLocationChanged(final Location newLocation) {} 

Por favor, intente de esta manera y avíseme si aún enfrenta algún problema.

Gracias.

La solución más fácil, aunque ralentiza un poco, es utilizar una función de ayuda. Mi problema era que se conectaría, pero antes de encontrar una ubicación, intentaría acceder a ella y presionar un puntero nulo.

 public Location getLocation(LocationClient locationClient){ if(locationClient.getLastLocation() == null){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } return getLocation(locationClient); }else{ return locationClient.getLastLocation(); } } 

Simplemente use esto en onConnected y configure lo que quiera que la ubicación use con esta función, pasando su cliente de ubicación.

 @Override public void onConnected(Bundle dataBundle) { Location temp = getLocation(mLocationClient); mLocation = temp; } 

Además, si no desea obtener la ubicación de onConnected por cualquier razón, puede usar la misma función auxiliar en cualquier lugar siempre que pase su locationClient onConnected .