Подтвердить что ты не робот

LocationClient getLastLocation() return null

Как и те, с кем встречались раньше Я тестировал одну из них: (4.0.4 с сервисом google play) и avd (4.2.2 с google api), в обоих случаях locationclient 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(), но все равно не получится. Где ошибка, спасибо заранее.

4b9b3361

Ответ 1

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

Ответ 2

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

Решение

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

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

:

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

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

Ответ 3

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

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

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

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

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

Ответ 4

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

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

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

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

Ответ 5

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

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

startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));

Ответ 6

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

LocationManager и LocationClient не получают GPS от поставщиков. Их нужно начинать каждый раз, когда вам нужно место от них. Сделайте это перед вызовами LocationManager.getLastKnownLocation OR 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) {
        }
    });

Ответ 7

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

1) onCreate() компонента Android (например, Активность, Фрагмент или Сервис. Примечание: Not IntentService), build, а затем подключиться к 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() интерфейса LocalListener, вы получите новое местоположение.

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

Ответ 8

В версиях SDK 23

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

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

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

Ответ 9

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

Ответ 10

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

Ответ 11

Вам просто нужен запрос на обновление для местоположения. Если с 26 версиями Android SDK все в порядке:

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<LocationSettingsResult> result = LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build());
    result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
        @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:
                    l.a(" 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;
            }
        }
    });
}

и в onConnected метод обратного вызова:

 @Override
    public void onConnected(@Nullable Bundle bundle) {
        l.a(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();
    }

Ответ 12

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

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

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

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

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

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

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

Спасибо.

Ответ 13

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

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.