-
Notifications
You must be signed in to change notification settings - Fork 6.3k
Retrieving Location with LocationServices API
The Fused Location API is a higher-level Google Play Services API that wraps the underlying location sensors like GPS. You can accomplish tasks like:
- Register for location connection events
- Connect to the location sensor
- Register for updates or accuracy changes
- Get last location
Fused location requires the use of the Google Play SDK. You must include the library in your app/build.gradle
file:
dependencies {
compile 'com.google.android.gms:play-services-location:9.8.0'
}
You can use this site to find the latest version to use, or you can refer to the official SDK setup instructions.
In addition, if you are using Genymotion emulator, you must install a Google Play Services APK file too.
Add the following permissions to the AndroidManifest.xml
:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
This provides the ability to access location information at coarse and fine granularities. You can remove ACCESS_FINE_LOCATION
this will still work with less precision.
Note: The permissions model has changed starting in Marshmallow. If your targetSdkVersion
>= 23
and you are running on a Marshmallow (or later) device, you may need to enable runtime permissions. You can also read more about the runtime permissions changes here.
Inside an Activity, put the following to connect and start receiving location updates:
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
private long UPDATE_INTERVAL = 10 * 1000; /* 10 secs */
private long FASTEST_INTERVAL = 2000; /* 2 sec */
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Create the location client to start receiving updates
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).build();
}
protected void onStart() {
super.onStart();
// Connect the client.
mGoogleApiClient.connect();
}
protected void onStop() {
// Disconnecting the client invalidates it.
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
// only stop if it's connected, otherwise we crash
if (mGoogleApiClient != null) {
mGoogleApiClient.disconnect();
}
super.onStop();
}
public void onConnected(Bundle dataBundle) {
// Get last known recent location.
Location mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
// Note that this can be NULL if last location isn't already known.
if (mCurrentLocation != null) {
// Print current location if not null
Log.d("DEBUG", "current location: " + mCurrentLocation.toString());
LatLng latLng = new LatLng(mCurrentLocation.getLatitude(), mCurrentLocation.getLongitude());
}
// Begin polling for new location updates.
startLocationUpdates();
}
@Override
public void onConnectionSuspended(int i) {
if (i == CAUSE_SERVICE_DISCONNECTED) {
Toast.makeText(this, "Disconnected. Please re-connect.", Toast.LENGTH_SHORT).show();
} else if (i == CAUSE_NETWORK_LOST) {
Toast.makeText(this, "Network lost. Please re-connect.", Toast.LENGTH_SHORT).show();
}
}
// Trigger new location updates at interval
protected void startLocationUpdates() {
// Create the location request
mLocationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(UPDATE_INTERVAL)
.setFastestInterval(FASTEST_INTERVAL);
// Request location updates
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,
mLocationRequest, this);
}
and then register for location updates with onLocationChanged
:
public void onLocationChanged(Location location) {
// New location has now been determined
String msg = "Updated Location: " +
Double.toString(location.getLatitude()) + "," +
Double.toString(location.getLongitude());
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
// You can now create a LatLng Object for use with maps
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
}
For more information on the Fused Location API, refer to this Google guide.
For using maps check out the Cliffnotes for Maps or the Android Maps Tutorial. See a working source code example.
Location updates should always be done using the GoogleApiClient
leveraging the LocationServices.API
as shown above. Do not use the older Location APIs which are much less reliable. Even when using the correct FusedLocationApi
, there are a lot of things that can go wrong. Consider the following potential issues:
-
Did you add the necessary permissions? Make sure your app has
INTERNET
andACCESS_COARSE_LOCATION
permissions to ensure that location can be accessed as illustrated in the guide above. -
Are you getting
null
when callingLocationServices.FusedLocationApi.getLastLocation
? This is normal since this method only returns if there is already a location recently retrieved by another application. If this returns null, this means you need start receiving location updates withLocationServices.FusedLocationApi.requestLocationUpdates
before receiving the location as shown above. - Are you trying to get location on the genymotion emulator? Ensure you've enabled GPS and configured a lat/lng properly. Try restarting the emulator if needed and re-enabling GPS or trying a device (or the official emulator) instead to rule out genymotion specific issues.
- Are you failed to add Google Play Services Location dependencies when using Firebase? Firebase dependencies version is usually not up to date with recent Google Play Services, thus showing a conflict error when Gradle trying to get dependencies. To solve this, simply match Google Play Services Location version with your Firebase version.
You can also review the following troubleshooting resources:
With this, you should have location updates working as expected.
Created by CodePath with much help from the community. Contributed content licensed under cc-wiki with attribution required. You are free to remix and reuse, as long as you attribute and use a similar license.
Finding these guides helpful?
We need help from the broader community to improve these guides, add new topics and keep the topics up-to-date. See our contribution guidelines here and our topic issues list for great ways to help out.
Check these same guides through our standalone viewer for a better browsing experience and an improved search. Follow us on twitter @codepath for access to more useful Android development resources.