LocationClient getLastLocation () return null

Как и те, с кем вы столкнулись, перед тем, как я протестировал один из них, вы можете использовать nexus s (4.0.4 с сервисом google play) и avd (4.2.2 с google api), в обоих случаях getLastLocation() всегда возвращает 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) {} } 

Большинство из них взято из примеров, данных Google. В приведенном выше коде hava попробовал такой метод:

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

а также

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

В onConnected() перед вызовом getLastLocation() , но все равно не повезло. Где ошибка, спасибо заранее.

Solutions Collecting From Web of "LocationClient getLastLocation () return null"

В настоящее время Fused Location Provider будет поддерживать только фоновое местоположение, если к нему подключен хотя бы один клиент. Как только первый клиент подключится, он немедленно попытается получить местоположение. Если ваша деятельность является первым клиентом для подключения, и вы сразу вызываете getLastLocation() прямо в onConnected() , для этого может оказаться недостаточно времени для первого местоположения.

У меня была такая же проблема, следуя инструкциям из учебника . На телефоне это сработало, и на эмуляторе (Genymotion) этого не произошло.

Решение

В вашем AndroidManifest.xml измените это:

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

к этому:

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

… и вы сразу же получите место. Не нужно менять код (для прослушивания обновлений местоположения).

Проблема также может быть вызвана тем, что на вашем устройстве не установлено «Wi-Fi и местоположение мобильной сети».

LocationClient (поставщик плавного доступа) использует GPS и WiFi. GPS занимает некоторое время, чтобы найти ваше местоположение, а Wi-Fi – намного быстрее. Однако, если какая-либо из этих двух служб подключена, будет вызван метод обратного вызова onConnected. И если вы сразу же вызываете метод LocationClient.getLastLocation () в методе onConnected, скорее всего, вы получите нулевое значение, если ваша служба определения местоположения отключена. Просто потому, что GPS просто недостаточно быстрый.

Чтобы решить проблему для себя локально, включите «Wi-Fi и местоположение мобильной сети». Вы можете сделать это, перейдя в «Настройки»> «Личные»> «Доступ к местоположению»> «Местоположение Wi-Fi и мобильной сети».

Однако, если вы хотите решить проблему для пользователей своего приложения, вам лучше проверить, возвращает ли getLastLocation () значение null. Если это так, попросите своего пользователя включить службу, как это делает карта google.

Надеюсь, это поможет.

Я столкнулся с подобной проблемой.

Вызовите mLocationClient.getLastLocation() в onConnected или после подключения к сервисам Google Play. Если вы вызываете этот метод до того, как Клиент местоположения подключен, возвращаемое местоположение будет null .

Вы можете проверить, подключен ли клиент местоположения посредством mLocationClient.isConnected() .

Надеюсь это поможет.

Вы должны проверить, разрешено ли пользователю местоположение через Wi-Fi / GSM или GPS. Если у вас нет доступного провайдера, вы получите null .

Этот код отображает экран с настройками местоположения:

 startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)); 

Я столкнулся с подобными проблемами в своих тестах с телефонами Samsung (высоко настраиваемый Android и поддержка разработчиков).

LocationManager и LocationClient не получают GPS от поставщиков. Их нужно начинать каждый раз, когда вам нужно место от них. Сделайте это до того, как вы назовете LocationClient.getLastLocation или LocationClient.getLastLocation . Эти API вернутся.

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

В версиях SDK 23

Вам также необходимо будет явно запрашивать разрешение на местоположение во время выполнения , как https://developer.android.com/training/permissions/requesting.html, а также иметь его в файле манифеста.

Явная ошибка не возникает, если у вас нет разрешений во время выполнения, поставщик местоположения просто вернет null.

Это поможет, если Google задокументирует это, а также выбросит исключение, а не просто вернет null. Возвращение null – это наименее полезная вещь в этой ситуации.

Это точно рабочее решение, вероятно, при незначительных разных обстоятельствах. Но я хотел добавить несколько небольших шагов для объяснения, чтобы кто-то понял точные понятия:

1) onCreate () Android-компонента (например, Activity , Fragment или Service . Примечание: Not IntentService ), выполните сборку и затем подключите GoogleApiClient, как показано ниже.

 buildGoogleApiClient(); mGoogleApiClient.connect(); 

Где реализация buildGoogleApiClient () – это,

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

Позже onDestroy () вы можете отключить GoogleApiClient как,

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

Шаг 1 гарантирует, что вы создадите и подключите GoogleApiClient.

1) Первый экземпляр GoogleApiClient подключается по методу onConnected (). Теперь ваш следующий шаг должен выглядеть в методеConnected ().

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

Выше вы вызываете метод createLocationRequest () для создания запроса местоположения. Метод createLocationRequest () выглядит следующим образом.

 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) Теперь на onLocationChange () обратном вызове интерфейса LocationListener вы получите новое местоположение.

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

Вы получаете такой результат в Logcat: 03-22 18: 34: 17.336 817-817 / com.LiveEarthquakesAlerts I / LocationTracker: Местоположение: Местоположение [fused 37.421998, -122.084000 acc = 20 et = + 15m35s840ms alt = 0.0]

Чтобы выполнить эти три шага, вы должны были сконфигурировать свой build.gradle, как показано ниже:

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

Я также столкнулся с одной и той же проблемой в своем приложении, и единственное, что произошло, это то, что приложение запрашивает только ACCESS_COARSE_LOCATION, а не ACCESS_FINE_LOCATION. Я добавил более позднее разрешение, и все работает нормально.

Геолокация Google play не может работать без подключения к Интернету, равномерно для GPS. Итак, проверьте приложение с включенными мобильными данными.

Я бегу и работаю над ним в устройстве Nexus 7. Вы, ребята, ошибочно написали старую версию LocationListener, которая не используется с новым API.

Вы должны установить новый LocationListener.

Вам нужно импортировать этот класс, а затем попробовать.

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

И он переопределяет единственный метод в соответствии с новым API

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

Пожалуйста, попробуйте этот путь и сообщите мне, если вы все еще сталкиваетесь с какой-либо проблемой.

Благодарю.

Самое простое исправление, хотя и немного замедляет его, заключается в использовании вспомогательной функции. Моя проблема заключалась в том, что он будет подключаться, но до того, как было обнаружено местоположение, я попытался бы получить к нему доступ и нанести нулевой указатель.

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

Просто используйте это в onConnected и установите все, что вы хотите, чтобы местоположение использовало эту функцию, передавая ваш клиент местоположения.

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

Кроме того, если вы не хотите получать местоположение из onConnected по какой-либо причине, вы можете использовать ту же вспомогательную функцию в любом месте, пока вы передаете свой locationClient .