LocationClient getLastLocation() retourneert null

Zoals de vragen die iemand eerder tegenkwam
Ik heb een van de nexus s (4.0.4 met google play-service beschikbaar) en avd (4.2.2 met google api) getest, in beide gevallen getLastLocation()van locationclient retourneert altijd 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) {}
}

De meesten van hen kwamen uit voorbeelden van Google. In de bovenstaande code probeerde HAVA de methode zoals dat:

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

en

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

In onConnected()Voordat u getLastLocation(), maar nog steeds geen geluk krijgt.
Waar is de fout, van tevoren bedankt.


Antwoord 1, Autoriteit 100%

Momenteel de Fused Location Provideronderhoudt alleen de achtergrondlocatie als er ten minste één klant erop is aangesloten. Zodra de eerste klant aansluit, probeert het onmiddellijk een locatie te krijgen. Als uw activiteit de eerste client is om verbinding te maken en belt u getLastLocation()meteen in onConnected(), die mogelijk niet genoeg tijd is voor de eerste locatie om binnen te komen.


Antwoord 2, Autoriteit 39%

Ik had hetzelfde probleem bij het volgen van de instructies van de tutorial .
Telefonisch werkte het en op de (genymotion) emulator die het niet heeft gedaan.

Oplossing

Verander dit in uw Androidmanifest.xml dit:

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

naar dit:

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

…en je krijgt meteen de locatie. U hoeft uw code niet te wijzigen (om naar locatie-updates te luisteren).


Antwoord 3, autoriteit 36%

Het probleem kan ook worden veroorzaakt doordat uw apparaat “Wi-Fi en mobiele netwerklocatie” niet heeft ingeschakeld.

LocationClient (de gefuseerde locatieprovider) gebruikt zowel GPS als wifi. GPS duurt even om je locatie te vinden, terwijl wifi veel sneller is. Als echter een van deze 2 services is verbonden, wordt de terugbelmethode onConnected aangeroepen. En als u LocationClient.getLastLocation() onmiddellijk in de onConnected-methode probeert aan te roepen, is de kans groot dat u een null-waarde krijgt als uw wifi-locatieservice is uitgeschakeld. Het is gewoon omdat GPS gewoon niet snel genoeg is.

Als u het probleem zelf lokaal wilt oplossen, schakelt u ‘Wi-Fi en mobiele netwerklocatie’ in. U kunt dit doen door naar “Instellingen > Persoonlijke > Locatietoegang > Wi-Fi & mobiele netwerklocatie” te gaan.

Als u het probleem echter voor de gebruikers van uw app wilt oplossen, kunt u beter controleren of getLastLocation() null retourneert. Als dit het geval is, vraagt ​​u uw gebruiker om de service in te schakelen, net zoals Google Maps doet.

Hopelijk helpt dat.


Antwoord 4, autoriteit 12%

Ik had een soortgelijk probleem.

Bel mLocationClient.getLastLocation()in onConnectedof nadat de verbinding met Google Play-services tot stand is gebracht. Als u deze methode aanroept voordat de Location Client is verbonden, is de geretourneerde locatie null.

U kunt controleren of de locatieclient is verbonden door mLocationClient.isConnected().

Hopelijk helpt dit.


Antwoord 5, autoriteit 11%

Ik heb soortgelijke problemen ondervonden tijdens mijn tests met Samsung-telefoons (zeer aangepaste Android en geen ondersteuning voor ontwikkelaars).

LocationManager en LocationClient krijgen de GPS niet van de providers. Ze moeten elke keer dat je de locatie van ze nodig hebt, worden opgestart. Doe dit voordat je LocationManager.getLastKnownLocationOF LocationClient.getLastLocationaanroept. Deze API’s zullen terugkeren.

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

Antwoord 6, autoriteit 11%

Dit is de exact werkende oplossing, waarschijnlijk in iets andere omstandigheden. Maar ik wilde wat kleine uitlegstappen toevoegen zodat iedereen de exacte concepten krijgt:

1) onCreate() van Android Component (bijv. Activiteit, Fragmentof Service. Opmerking: niet IntentService), bouwen verbindvervolgens de GoogleApiClient zoals hieronder.

buildGoogleApiClient();
mGoogleApiClient.connect();

waar, buildGoogleApiClient() implementatie is,

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

Later onDestroy(), kunt u GoogleApiClient loskoppelen als,

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

Stap 1 zorgt ervoor dat u de GoogleApiClient bouwt en verbindt.

1) GoogleApiClient-instantie wordt voor het eerst verbonden via methode onConnected(). Nu zou uw volgende stap de methode onConnected() moeten zijn.

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

Hierboven heb je een methode createLocationRequest()aangeroepen om een ​​locatieverzoek te maken. De methode createLocationRequest()ziet er als volgt uit.

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) Nu, op onLocationChange() callback van LocationListener-interface, krijgt u een nieuwe locatie.

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

Je krijgt het resultaat als volgt in Logcat:
03-22 18:34:17.336 817-817/com.LiveEarthquakesAlerts I/LocationTracker: Locatie: Locatie [fused 37.421998,-122.084000 acc=20 et=+15m35s840ms alt=0.0]

Om deze drie stappen te kunnen uitvoeren, moet u uw build.gradle als volgt hebben geconfigureerd:

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

Antwoord 7, autoriteit 9%

U moet controleren of de gebruiker locatie via Wi-Fi/GSM of GPS heeft ingeschakeld. Als er geen beschikbare locatieprovider is, krijg je null.

Deze code geeft het scherm met locatie-instellingen weer:

startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));

Antwoord 8, autoriteit 5%

Op SDK-versies 23

U moet ook expliciet de locatietoestemming aanvragen tijdens runtime, zoals aangegeven in
https://developer.android.com/training/permissions/requesting.html
evenals het hebben van het in het manifestbestand.

Er zal geen expliciete fout optreden als u tijdens runtime niet over de machtigingen beschikt, de locatieprovider retourneert gewoon null.

Het zou helpen als Google dit zou documenteren en ook een uitzondering zou maken in plaats van alleen null terug te geven. Null retourneren is ongeveer het minst nuttige om te doen in deze situatie.


Antwoord 9, autoriteit 4%

Ik had hetzelfde probleem met mijn app, en het enige wat ontbrak was dat de app alleen om ACCESS_COARSE_LOCATION vroeg en niet ACCESS_FINE_LOCATION.
Ik heb de latere toestemming toegevoegd en alles werkte goed.


Antwoord 10, autoriteit 2%

Je hebt alleen een updateverzoek voor de locatie nodig. Als alles in orde is met 26 Android SDK-machtigingen:

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

en in de onConnected terugbelmethode:

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

Antwoord 11

Ik ren en het werkt perfect op het Nexus 7-apparaat.
Jullie hebben per ongeluk de oude versie LocationListener geschreven die niet wordt gebruikt met de nieuwe API.

Je moet instellen met de nieuwe LocationListener.

Je moet deze klas importeren en het dan proberen.

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

En het overschrijft de enige methode volgens de nieuwe API

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

Probeer het op deze manier en laat het me weten als je nog steeds een probleem hebt.

Bedankt.


Antwoord 12

Geolocatie van Google Play-service kan niet werken zonder internetverbinding, onverschillig voor GPS. Controleer dus de app met mobiele data ingeschakeld.


Antwoord 13

De eenvoudigste oplossing, hoewel het een beetje vertraagt, is om een ​​hulpfunctie te gebruiken. Mijn probleem was dat het verbinding zou maken, maar voordat er een locatie was gevonden, probeerde ik het te openen en raakte ik een null-aanwijzer.

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

Gebruik dit gewoon in onConnecteden stel in wat je wilt dat de locatie deze functie gebruikt, waarbij je je locatieclient passeert.

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

Ook als je de locatie om welke reden dan ook niet van onConnectedwilt krijgen, kun je dezelfde helperfunctie overal gebruiken zolang je je locationClientpasseert.

Other episodes