Using GoogleApiClient + LocationServices not updating

TomDT picture TomDT · Jul 31, 2014 · Viewed 24.3k times · Source

I'm just trying to do a simple 'tutorial' app to get my phone's location (to learn how to use it later in some other app) but I'm just not getting anywhere.

What I've done

  1. Android Developer's tutorial : First of, I followed the tutorial in the Android's developer site (developer.android.com/training/location/receive-location-updates.html).

    Just like indicated in there, I used a Location, LocationClient and LocationRequest, initializing them (and setting them up) in onCreate. LocationClient is connected and disconnected in onStart and onStop.

    I'm requesting location update after I'm connected (in onConnected). I verify that GooglePlayServices are available before making this call and I'm still not getting any update in "onLocationChanged".

  2. GoogleApiClient : I noticed that LocationClient is deprecated and LocationServices are preferred (developer.android.com/reference/com/google/android/gms/location/LocationClient.html).

    As indicated here : https://developer.android.com/reference/com/google/android/gms/location/FusedLocationProviderApi.html, I use a GoogleApiClient and set it to LocationServices (also https://stackoverflow.com/a/25013850/3802589). So then I set it all to use this but still I'm not getting any updates on the location.

onLocationChanged it should print if there's a response. I also put a button that prints location or 'nothing'.

Remarks

I checked using Google Maps to see if maybe I had something off but it's working just fine.

Project

build.gradle

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.google.android.gms:play-services:5.0.77'
    compile "com.android.support:support-v4:20.0.+"
}

Manifest

...
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
...
<meta-data android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />
...

Code

public class MyActivity extends Activity  implements
        GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener,
        LocationListener {

    private GoogleApiClient mLocationClient;
    private Location mCurrentLocation;
    LocationRequest mLocationRequest;

    ...
    /* Constant fields - request interval */
    ...

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my);

        mLocationClient = new GoogleApiClient.Builder(getApplicationContext())
                                .addApi(LocationServices.API)
                                .addConnectionCallbacks(this)
                                .addOnConnectionFailedListener(this)
                                 .build();

        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(UPDATE_INTERVAL);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

        mLocationRequest.setFastestInterval(FASTEST_INTERVAL);

    }

    @Override
    protected void onStart() {
        super.onStart();
        mLocationClient.connect();
    }

    @Override
    protected void onStop() {
        super.onStop();

        LocationServices.FusedLocationApi.removeLocationUpdates(mLocationClient, this);

        mLocationClient.disconnect();
    }

    public void onClick(View view) {

        if (mCurrentLocation != null) {
            Log.i("Location", mCurrentLocation.toString());
        } else {
            Log.i("Location", "nothing");
        }

    }

    @Override
    public void onLocationChanged(Location location) {
        Log.d("Location Update", "CHANGED");
        mCurrentLocation = location;
    }

    @Override
    public void onConnected(Bundle bundle) {
        // Display the connection status
        Toast.makeText(this, "Connected", Toast.LENGTH_SHORT).show();
        if(servicesConnected()) {
            LocationServices.FusedLocationApi.requestLocationUpdates(mLocationClient, mLocationRequest, this);
        }
    }

    @Override
    public void onConnectionSuspended(int i) {
        Toast.makeText(this, "Disconnected. Please re-connect.",
                Toast.LENGTH_SHORT).show();
    }

logcat

8948-8948/example.android.com.test D/Location Updates﹕ Google Play services is available.
8948-8948/example.android.com.test I/Location﹕ nothing

I feel that I might be forgetting something really simple... but I just can't see it and I've spent too much time trying to get just a simple location...

I could maybe just use the android.location API but... It bothers me that this is so hard (supposedly being easier).

Answer

GregM picture GregM · Aug 22, 2014

The three callbacks:

public void onConnectionFailed(ConnectionResult arg0){}
public void onConnected(Bundle bundle){}
public void onConnectionSuspended(int arg0){}

must be implemented. However, I don't see onConnectionFailed being overridden. The compiler should have given an error in this case. There are two LocationListener implementations one for LocationListener and the other gms.location.LocationListener. You may want to check if you are using the gms version.

I hope Google will update their training sample code to the new client model and eliminate further confusion.