0

This is the code that gets called when the GoogleApiClient gets created. All this does it retrieve the last location of the user.

  //omitted code

@Override
public void onConnected(Bundle bundle) {
    Location location = LocationServices.FusedLocationApi.getLastLocation(mApiClient);
    if (location != null) {
        mLongitude = String.valueOf(location.getLongitude());
        mLatitude = String.valueOf(location.getLatitude());
        Log.d(TAG, mLongitude + "___" + mLatitude); //this one doesn't return null
    } else {
        Log.d(TAG, "Location is null");
        LocationServices.FusedLocationApi.requestLocationUpdates(mApiClient, mLocationRequest, this);
    }
}

This is for the google api client:

private void buildGoogleApiClient() {
    mApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API)
            .build();
}

This snippet is from my onCreate() method:

buildGoogleApiClient();
Log.d(TAG, mLongitude + "___" + mLatitude); //this one returns null

So when the code gets run, i build a google api client and the onConnected method gets called. Inside of that method, i will update the mLongitude and mLatitude variables which are instance variables. However in the log, they return as null. I was wondering why this happened so i put another log INSIDE the if statement of my onConnected() method as you can see in the first block of code and this one successfully brings back the longitude and latitude. I dont know why its not updating the instance variables. I believe it's because the callback isn't being run on the main thread and so the log happens before the update. So I tried running the code in the main thread like this:

runOnUiThread(new Runnable() {
            @Override
            public void run() {
                buildGoogleApiClient();
            }
        });
Log.d(TAG, mLongitude + "___" + mLatitude);

unfortunately this doesnt work either. I searched for things relating to this topic and tried implementing them in my code however none seem to work as i dont even know the real cause for this problem.

Anyone know how to fix this?

Thank you

Kevin
  • 9
  • 1

1 Answers1

1

The buildGoogleApiClient call is asynchronous. The data will come back later - your variables will print before the call is complete.

You need to find a way to wait for the data to return. There are many ways of implementing that.

EDIT:

Just to verify, you can run a loop on a non-UI thread and wait for the data to change... like:

new Runnable() {
        @Override
        public void run() {
            while (mLongitude == null) {
                wait(100);
            }
            Log.d(TAG, mLongitude + "___" + mLatitude);
        }
    });

You may want to refine it, but there are many ways to wait, just not on the UI thread. But the problem is what you want to do with the data once it's available. If you need to update a database vs. the UI, then you will want different implementations. Fundamentally, it is implemented like listeners are in general.

Jim
  • 10,172
  • 1
  • 27
  • 36
  • what's a common way of going about this? – Kevin Oct 19 '15 at 00:12
  • @Kevin the common way is to [implement a callback](http://stackoverflow.com/questions/3398363/how-to-define-callbacks-in-android) so that when the call is done, the callback can do the next step. In other word, use [`GoogleApiClient.ConnectionListener.onConnected()`](https://developers.google.com/android/reference/com/google/android/gms/common/api/GoogleApiClient.ConnectionCallbacks.html#onConnected(android.os.Bundle)) – Andrew T. Nov 24 '15 at 03:45