I'd like to simply retrieve device location in my Android project and in order to do so I use the play-services approach:
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder( MainSearchActivity.this )
.addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
@Override
public void onConnected( Bundle bundle ){
Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if( location == null ){
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, new LocationListener() {
@Override
public void onLocationChanged(Location location) {
lastLocation = location;
}
});
}
}
@Override
public void onConnectionSuspended( int i ){
}
})
.addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
@Override
public void onConnectionFailed( ConnectionResult connectionResult ){
if( connectionResult.hasResolution() ){
try {
// Start an Activity that tries to resolve the error
connectionResult.startResolutionForResult(MainSearchActivity.this, CONNECTION_FAILURE_RESOLUTION_REQUEST);
}catch( IntentSender.SendIntentException e ){
e.printStackTrace();
}
}else{
Utils.logger("Location services connection failed with code " + connectionResult.getErrorCode(), Utils.LOG_DEBUG );
}
}
})
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
}
public Location retrieveLastLocation(){
Location loc = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if( loc == null)
{
}
return loc; //TODO: What if loc is null?
}
but the loc variable is ALWAYS null. It's as such on different phones, every single time. Also lastLocation, that I try to assign in the onLocationChanged, never changes. Always null.
These are the permission I set for the app
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="com.vogella.android.locationapi.maps.permission.MAPS_RECEIVE" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
I just don't get it: why can't the LocationServices retrieve a position? I have all geolocation settings enabled on all three the deviced i tested upon :-/
Thank you for any help
First, create a
LocationRequest
object:Then, make sure the user has granted permission to use location. If so, get the location from
requestLocationUpdates
as follows:Be sure to remove the updates if you only need one location without constant monitoring. This way, you will never get a null
Location
.For more information, go to http://blog.teamtreehouse.com/beginners-guide-location-android.
I am using the below code to get location as per the latest documentation of android https://developer.android.com/training/location/retrieve-current https://developer.android.com/training/location/receive-location-updates
If getLastLocation() is always returning null, try this hack. I have used it to solve my problem. Implement LocationListener (import com.google.android.gms.location.LocationListener) in your activity.
onStart or onResume (i preferred onResume)
Now, in your onLocationChanged method check whether the googleApiClient is connected or not. If its connected, disconnect it, and connect again.
And finally, in your onConntected() method
We are repeatedly trying to connect to googleApiClient, even if its already connected, so that we can get the lastLocation data. This will depend on the LocationRequest intervals. You can get the location data in onLocationChanged too, and perform your task from there.
The fused
Location Provider
will only maintain background location if at least one client is connected to it. Now just turning on the location service will not guarantee to store the last known location.Once the first client connects, it will immediately try to get a location. If your activity is the first client to connect and
getLastLocation()
is invoked right away inonConnected()
, that might not be enough time for the first location to arrive..I suggest you to launch the Maps app first, so that there is at least some confirmed location, and then test your app.
If you are using Android Marshmallow (API 23) or newer version of Android, you can face same problem because permission is not granted. You should either explicitly request permission at run time for location or, if it's a test project you can grant location permission from app settings on your phone.
I think there is a small miss which is not visible to me in the code shown.
The
mGoogleApiClient
is built but seems not connected.You can verify this by callingmGoogleApiClient.isConnected()
.You can just override the onStart method and call connect there. Or you can override
onResume()
in case you want to access the location whenever ur activity is visible.