page.title=Changing Location Settings trainingnavtop=true @jd:body

This lesson teaches you how to

  1. Connect to Location Services
  2. Set Up a Location Request
  3. Get Current Location Settings
  4. Prompt the User to Change Location Settings

You should also read

If your app needs to request location or receive permission updates, the device needs to enable the appropriate system settings, such as GPS or Wi-Fi scanning. Rather than directly enabling services such as the device's GPS, your app specifies the required level of accuracy/power consumption and desired update interval, and the device automatically makes the appropriate changes to system settings. These settings are defined by the {@code LocationRequest} data object.

This lesson shows you how to use the Settings API to check which settings are enabled, and present the Location Settings dialog for the user to update their settings with a single tap.

Connect to Location Services

In order to use the location services provided by Google Play Services and the fused location provider, connect your app using the Google API Client, then check the current location settings and prompt the user to enable the required settings if needed. For details on connecting with the Google API client, see Getting the Last Known Location.

Apps that use location services must request location permissions. For this lesson, coarse location detection is sufficient. Request this permission with the uses-permission element in your app manifest, as shown in the following example:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.google.android.gms.location.sample.locationupdates" >

  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
</manifest>

If the device is running Android 6.0 or higher, and your app's target SDK is 23 or higher, the app has to list the permissions in the manifest and request those permissions at run time. For more information, see Requesting Permissions at Run Time.

Set Up a Location Request

To store parameters for requests to the fused location provider, create a {@code LocationRequest}. The parameters determine the level of accuracy for location requests. For details of all available location request options, see the {@code LocationRequest} class reference. This lesson sets the update interval, fastest update interval, and priority, as described below:

Update interval
{@code setInterval()} - This method sets the rate in milliseconds at which your app prefers to receive location updates. Note that the location updates may be faster than this rate if another app is receiving updates at a faster rate, or slower than this rate, or there may be no updates at all (if the device has no connectivity, for example).
Fastest update interval
{@code setFastestInterval()} - This method sets the fastest rate in milliseconds at which your app can handle location updates. You need to set this rate because other apps also affect the rate at which updates are sent. The Google Play services location APIs send out updates at the fastest rate that any app has requested with {@code setInterval()}. If this rate is faster than your app can handle, you may encounter problems with UI flicker or data overflow. To prevent this, call {@code setFastestInterval()} to set an upper limit to the update rate.
Priority

{@code setPriority()} - This method sets the priority of the request, which gives the Google Play services location services a strong hint about which location sources to use. The following values are supported:

Create the location request and set the parameters as shown in this code sample:

protected void createLocationRequest() {
    LocationRequest mLocationRequest = new LocationRequest();
    mLocationRequest.setInterval(10000);
    mLocationRequest.setFastestInterval(5000);
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}

The priority of {@code PRIORITY_HIGH_ACCURACY}, combined with the {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission setting that you've defined in the app manifest, and a fast update interval of 5000 milliseconds (5 seconds), causes the fused location provider to return location updates that are accurate to within a few feet. This approach is appropriate for mapping apps that display the location in real time.

Performance hint: If your app accesses the network or does other long-running work after receiving a location update, adjust the fastest interval to a slower value. This adjustment prevents your app from receiving updates it can't use. Once the long-running work is done, set the fastest interval back to a fast value.

Get Current Location Settings

Once you have connected to Google Play services and the location services API, you can get the current location settings of a user's device. To do this, create a LocationSettingsRequest.Builder, and add one or more location requests. The following code snippet shows how to add the location request that was created in the previous step:

LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
     .addLocationRequest(mLocationRequest);

Next check whether the current location settings are satisfied:

PendingResult<LocationSettingsResult> result =
         LocationServices.SettingsApi.checkLocationSettings(mGoogleClient,
                 builder.build());

When the PendingResult returns, your app can check the location settings by looking at the status code from the LocationSettingsResult object. To get even more details about the the current state of the relevant location settings, your app can call the {@code LocationSettingsResult} object's getLocationSettingsStates() method.

Prompt the User to Change Location Settings

To determine whether the location settings are appropriate for the location request, check the status code from the {@code LocationSettingsResult} object. A status code of RESOLUTION_REQUIRED indicates that the settings must be changed. To prompt the user for permission to modify the location settings, call {@code startResolutionForResult(Activity, int)}. This method brings up a dialog asking for the user's permission to modify location settings. The following code snippet shows how to check the location settings, and how to call {@code startResolutionForResult(Activity, int)}.

result.setResultCallback(new ResultCallback<LocationSettingsResult>()) {
     @Override
     public void onResult(LocationSettingsResult result) {
         final Status status = result.getStatus();
         final LocationSettingsStates = result.getLocationSettingsStates();
         switch (status.getStatusCode()) {
             case LocationSettingsStatusCodes.SUCCESS:
                 // All location settings are satisfied. The client can
                 // initialize location requests here.
                 ...
                 break;
             case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                 // Location settings are not satisfied, but this can be fixed
                 // by showing the user a dialog.
                 try {
                     // Show the dialog by calling startResolutionForResult(),
                     // and check the result in onActivityResult().
                     status.startResolutionForResult(
                         OuterClass.this,
                         REQUEST_CHECK_SETTINGS);
                 } catch (SendIntentException e) {
                     // Ignore the error.
                 }
                 break;
             case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                 // Location settings are not satisfied. However, we have no way
                 // to fix the settings so we won't show the dialog.
                 ...
                 break;
         }
     }
 });

The next lesson, Receiving Location Updates, shows you how to receive periodic location updates.