Search code examples
androidgeolocationoncreatefusedlocationproviderapi

LocationServices.FusedLocationApi.getLastLocation not working in onCreate() method


Here is my code that uses the same method - once during onCreate() in my MainActivity and once after user clicks a button

// Below code not working during onCreate
 StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
    StrictMode.setThreadPolicy(policy);

    // Create an instance of GoogleAPIClient. From Google API demo code
    if (mGoogleApiClient == null) {
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
    }

    startLocationOnScreen.setText(getCurrentLocationViaPhoneLocation());

// Surprisingly same method works if it's called after a button press!

        startButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

                           startLocationOnScreen.setText(getCurrentLocationViaPhoneLocation());

So why would this be? I basically want to get user's current location when the app is loaded, not force user to press a button to get the same.

Implementation of getCurrentLocationViaPhoneLocation() Method -- (mostly taken from Google API docs)

protected String getCurrentLocationViaPhoneLocation() {

    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        // TODO: Consider calling
        //    ActivityCompat#requestPermissions
        // here to request the missing permissions, and then overriding
        //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
        //                                          int[] grantResults)
        // to handle the case where the user grants the permission. See the documentation
        // for ActivityCompat#requestPermissions for more details.
        return "Error - location services not available!";
    }
    startLocation = LocationServices.FusedLocationApi.getLastLocation(
            mGoogleApiClient);
    if (startLocation != null) {
        Log.e("We are at ", String.valueOf(startLocation.getLatitude()));
        Log.e("We are at ", String.valueOf(startLocation.getLongitude()));

        Geocoder geocoder = new Geocoder(this, Locale.getDefault());

        try {
            List<Address> addressList = geocoder.getFromLocation(startLocation.getLatitude(), startLocation.getLongitude(), 1);

            if (addressList != null && addressList.size() > 0) {


                currentCity = addressList.get(0).getLocality();


                Address address = addressList.get(0);
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < address.getMaxAddressLineIndex(); i++) {
                    sb.append(address.getAddressLine(i)).append("\n");
                }

                return (sb.toString());

            }

        } catch (IOException e) {
            e.printStackTrace();
        }


    }

    return ("Error - current location unavailable!");
}

Edit: I get: Error - current location unavailable! during onCreate() which means that startLocation==null when the method is called during onCreate().


Solution

  • I suspect the GoogleApiClient is not yet connected by the time you call the method the first time (i.e. during onCreate).

    You already call the addConnectionCallbacks method of the Builder. Therefore you should have implemented the onConnected(Bundle) method of GoogleApiClient.ConnectionCallbacks in your Activity. Call the getCurrentLocationViaPhoneLocation method here instead of in the onCreated, then you can be sure the GoogleApiClient is properly connected.

    If the onConnected method is not called, try to add mGoogleApiClient.connect() after creating the instance in your onCreate.

    I hope that helps!