1page.title=Changing Location Settings
2trainingnavtop=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>
148protected 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