Home | History | Annotate | Download | only in location
      1 page.title=Changing Location Settings
      2 trainingnavtop=true
      3 @jd:body
      4 
      5 <div id="tb-wrapper">
      6   <div id="tb">
      7 
      8   <h2>This lesson teaches you how to</h2>
      9   <ol>
     10     <li><a href="#connect">Connect to Location Services</a></li>
     11     <li><a href="#location-request">Set Up a Location Request</a></li>
     12     <li><a href="#get-settings">Get Current Location Settings</a></li>
     13     <li><a href="#prompt">Prompt the User to Change Location Settings</a></li>
     14   </ol>
     15 
     16   <h2>You should also read</h2>
     17   <ul>
     18     <li>
     19       <a href="https://developers.google.com/android/guides/setup"
     20       class="external-link">Setting up Google Play Services</a>
     21     </li>
     22     <li>
     23       <a href="retrieve-current.html">Getting the Last Known Location</a>
     24     </li>
     25    </ul>
     26   </div>
     27 </div>
     28 
     29 <p>If your app needs to request location or receive permission updates, the
     30   device needs to enable the appropriate system settings, such as GPS or Wi-Fi
     31   scanning. Rather than directly enabling services such as the device's GPS,
     32   your app specifies the required level of accuracy/power consumption and
     33   desired update interval, and the device automatically makes the appropriate
     34   changes to system settings. These settings are defined by the
     35   <a href="https://developers.google.com/android/reference/com/google/android/gms/location/LocationRequest"
     36   class="external-link">{@code LocationRequest}</a>
     37   data object. </p>
     38 
     39 <p>This lesson shows you how to use the
     40   <a href="https://developers.google.com/android/reference/com/google/android/gms/location/SettingsApi">Settings API</a>
     41   to check which settings are enabled, and present the Location Settings
     42   dialog for the user to update their settings with a single tap.</p>
     43 
     44 <h2 id="connect">Connect to Location Services</h2>
     45 
     46 <p>In order to use the location services provided by Google Play Services and
     47   the fused location provider, connect your app using the
     48   <a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient">Google API Client</a>,
     49   then check the current location settings and prompt the user to enable the
     50   required settings if needed. For details on connecting with the
     51   Google API client, see <a href="retrieve-current.html">Getting the Last Known Location</a>.</p>
     52 
     53 <p>Apps that use location services must request location permissions. For this
     54   lesson, coarse location detection is sufficient. Request this permission
     55   with the <code>uses-permission</code> element in your app manifest, as shown
     56   in the following example:</p>
     57 
     58 <pre><code>&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
     59   package="com.google.android.gms.location.sample.locationupdates" &gt;
     60 
     61   &lt;uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/&gt;
     62 &lt;/manifest&gt;
     63 </code></pre>
     64 
     65 <p>If the device is running Android 6.0 or higher, and your app's target
     66   SDK is 23 or higher, the app has to list the permissions in the manifest
     67   <em>and</em> request those permissions at run time. For more information, see
     68 <a href="{@docRoot}training/permissions/requesting.html">Requesting Permissions at Run Time</a>.</p>
     69 
     70 <h2 id="location-request">Set Up a Location Request</h2>
     71 
     72 <p>To store parameters for requests to the fused location provider, create a
     73   <a href="https://developers.google.com/android/reference/com/google/android/gms/location/LocationRequest.html">{@code LocationRequest}</a>.
     74   The parameters determine the level of accuracy for location requests. For
     75   details of all available location request options, see the
     76   <a href="https://developers.google.com/android/reference/com/google/android/gms/location/LocationRequest.html">{@code LocationRequest}</a>
     77   class reference. This lesson sets the update interval, fastest update
     78   interval, and priority, as described below:</p>
     79 
     80 <dl>
     81   <dt>
     82     Update interval
     83   </dt>
     84   <dd>
     85     <a href="https://developers.google.com/android/reference/com/google/android/gms/location/LocationRequest.html#setInterval(long)">{@code setInterval()}</a>
     86     - This method sets the rate in milliseconds at which your app prefers to
     87     receive location updates. Note that the location updates may be faster than
     88     this rate if another app is receiving updates at a faster rate, or slower
     89     than this rate, or there may be no updates at all (if the device has no
     90     connectivity, for example).
     91   </dd>
     92   <dt>
     93     Fastest update interval
     94   </dt>
     95   <dd>
     96     <a href="https://developers.google.com/android/reference/com/google/android/gms/location/LocationRequest.html#setFastestInterval(long)">{@code setFastestInterval()}</a>
     97     - This method sets the <strong>fastest</strong> rate in milliseconds at which
     98     your app can handle location updates. You need to set this rate because
     99     other apps also affect the rate at which updates are sent. The Google Play
    100     services location APIs send out updates at the fastest rate that any app
    101     has requested with
    102     <a href="https://developers.google.com/android/reference/com/google/android/gms/location/LocationRequest.html#setInterval(long)">{@code setInterval()}</a>.
    103     If this rate is faster
    104     than your app can handle, you may encounter problems with UI flicker or data
    105     overflow. To prevent this, call
    106     <a href="https://developers.google.com/android/reference/com/google/android/gms/location/LocationRequest.html#setFastestInterval(long)">{@code setFastestInterval()}</a>
    107     to set an upper limit to the update rate.
    108   </dd>
    109   <dt>Priority</dt>
    110   <dd>
    111     <p>
    112       <a href="https://developers.google.com/android/reference/com/google/android/gms/location/LocationRequest.html#setPriority(int)">{@code setPriority()}</a>
    113       - This method sets the priority of the request, which gives the Google Play
    114       services location services a strong hint about which location sources to use.
    115       The following values are supported:</p>
    116       <ul>
    117         <li>
    118           <a href="https://developers.google.com/android/reference/com/google/android/gms/location/LocationRequest.html#PRIORITY_BALANCED_POWER_ACCURACY">{@code PRIORITY_BALANCED_POWER_ACCURACY}</a>
    119           - Use this setting to request location precision to within a city
    120           block, which is an accuracy of approximately 100 meters. This is
    121           considered a coarse level of accuracy, and is likely to consume less
    122           power. With this setting, the location services are likely to use WiFi
    123           and cell tower positioning. Note, however, that the choice of location
    124           provider depends on many other factors, such as which sources are
    125           available.</li>
    126         <li>
    127           <a href="https://developers.google.com/android/reference/com/google/android/gms/location/LocationRequest.html#PRIORITY_HIGH_ACCURACY">{@code PRIORITY_HIGH_ACCURACY}</a>
    128           - Use this setting to request the most precise location possible. With
    129           this setting, the location services are more likely to use GPS
    130           to determine the location.</li>
    131         <li><a href="https://developers.google.com/android/reference/com/google/android/gms/location/LocationRequest.html#PRIORITY_LOW_POWER">{@code PRIORITY_LOW_POWER}</a>
    132           - Use this setting to request city-level precision, which is
    133           an accuracy of approximately 10 kilometers. This is considered a
    134           coarse level of accuracy, and is likely to consume less power.</li>
    135         <li><a href="https://developers.google.com/android/reference/com/google/android/gms/location/LocationRequest.html#PRIORITY_NO_POWER">{@code PRIORITY_NO_POWER}</a>
    136           - Use this setting if you need negligible impact on power consumption,
    137           but want to receive location updates when available. With this
    138           setting, your app does not trigger any location updates, but
    139           receives locations triggered by other apps.</li>
    140       </ul>
    141   </dd>
    142 </dl>
    143 
    144 <p>Create the location request and set the parameters as shown in this
    145   code sample:</p>
    146 
    147 <pre>
    148 protected void createLocationRequest() {
    149     LocationRequest mLocationRequest = new LocationRequest();
    150     mLocationRequest.setInterval(10000);
    151     mLocationRequest.setFastestInterval(5000);
    152     mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    153 }
    154 </pre>
    155 
    156 <p>The priority of
    157   <a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html#PRIORITY_HIGH_ACCURACY">{@code PRIORITY_HIGH_ACCURACY}</a>,
    158   combined with the
    159   {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION}
    160   permission setting that you've defined in the app manifest, and a fast update
    161   interval of 5000 milliseconds (5 seconds), causes the fused location
    162   provider to return location updates that are accurate to within a few feet.
    163   This approach is appropriate for mapping apps that display the location in
    164   real time.</p>
    165 
    166 <p class="note"><strong>Performance hint:</strong> If your app accesses the
    167   network or does other long-running work after receiving a location update,
    168   adjust the fastest interval to a slower value. This adjustment prevents your
    169   app from receiving updates it can't use. Once the long-running work is done,
    170   set the fastest interval back to a fast value.</p>
    171 
    172 <h2 id="get-settings">Get Current Location Settings</h2>
    173 
    174 <p>Once you have connected to Google Play services and the location services
    175     API, you can get the current location settings of a user's device. To do
    176     this, create a
    177     <a href="{@docRoot}reference/com/google/android/gms/location/LocationSettingsRequest.Builder"><code>LocationSettingsRequest.Builder</code></a>,
    178     and add one or more location requests. The following code snippet shows how
    179     to add the location request that was created in the previous step:</p>
    180 
    181 <pre>LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
    182      .addLocationRequest(mLocationRequest);
    183 </pre>
    184 
    185 <p>Next check whether the current location settings are satisfied:</p>
    186 
    187 <pre>PendingResult&lt;LocationSettingsResult&gt; result =
    188          LocationServices.SettingsApi.checkLocationSettings(mGoogleClient,
    189                  builder.build());</pre>
    190 
    191 <p>When the <a href="{@docRoot}reference/com/google/android/gms/common/api/PendingResult"><code>PendingResult</code></a>
    192   returns, your app can check the location settings by looking at the status
    193   code from the <a href="{@docRoot}reference/com/google/android/gms/location/LocationSettingsResult"><code>LocationSettingsResult</code></a>
    194   object. To get even more details about the the current state of the relevant
    195   location settings, your app can call the
    196   <a href="{@docRoot}reference/com/google/android/gms/location/LocationSettingsResult">{@code LocationSettingsResult}</a>
    197   object's
    198   <a href="{@docRoot}reference/com/google/android/gms/location/LocationSettingsResult#getLocationSettingsStates"><code>getLocationSettingsStates()</code></a>
    199   method.</p>
    200 
    201 <h2 id="prompt">Prompt the User to Change Location Settings</h2>
    202 
    203 <p>To determine whether the location settings are appropriate for the location
    204   request, check the status code from the
    205   <a href="{@docRoot}reference/com/google/android/gms/location/LocationSettingsResult">{@code LocationSettingsResult}</a>
    206   object. A status code of <code>RESOLUTION_REQUIRED</code> indicates that the
    207   settings must be changed. To prompt the user for permission to modify the
    208   location settings, call
    209   <a href="{@docRoot}reference/com/google/android/gms/common/api/Status#startResolutionForResult(android.app.Activity, int)">
    210             {@code startResolutionForResult(Activity, int)}</a>.
    211   This method brings up a dialog asking for the user's permission to modify
    212   location settings. The following code snippet shows how to check the location
    213   settings, and how to call {@code startResolutionForResult(Activity, int)}.
    214 </p>
    215 
    216 <pre>result.setResultCallback(new ResultCallback&lt;LocationSettingsResult&gt;()) {
    217      &#64;Override
    218      public void onResult(LocationSettingsResult result) {
    219          final Status status = result.getStatus();
    220          final LocationSettingsStates = result.getLocationSettingsStates();
    221          switch (status.getStatusCode()) {
    222              case LocationSettingsStatusCodes.SUCCESS:
    223                  // All location settings are satisfied. The client can
    224                  // initialize location requests here.
    225                  ...
    226                  break;
    227              case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
    228                  // Location settings are not satisfied, but this can be fixed
    229                  // by showing the user a dialog.
    230                  try {
    231                      // Show the dialog by calling startResolutionForResult(),
    232                      // and check the result in onActivityResult().
    233                      status.startResolutionForResult(
    234                          OuterClass.this,
    235                          REQUEST_CHECK_SETTINGS);
    236                  } catch (SendIntentException e) {
    237                      // Ignore the error.
    238                  }
    239                  break;
    240              case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
    241                  // Location settings are not satisfied. However, we have no way
    242                  // to fix the settings so we won't show the dialog.
    243                  ...
    244                  break;
    245          }
    246      }
    247  });</pre>
    248 
    249   <p>The next lesson,
    250     <a href="receive-location-updates.html">Receiving Location Updates</a>, shows
    251     you how to receive periodic location updates.</p>
    252