Merge "docs: Updates the request-location-updates lesson in the location APIs training course." into lmp-docs
This commit is contained in:
@@ -1,612 +1,417 @@
|
|||||||
page.title=Receiving Location Updates
|
page.title=Receiving Location Updates
|
||||||
trainingnavtop=true
|
trainingnavtop=true
|
||||||
@jd:body
|
@jd:body
|
||||||
|
|
||||||
<div id="tb-wrapper">
|
<div id="tb-wrapper">
|
||||||
<div id="tb">
|
<div id="tb">
|
||||||
|
|
||||||
<h2>This lesson teaches you to</h2>
|
<h2>This lesson teaches you how to</h2>
|
||||||
<ol>
|
<ol>
|
||||||
<li><a href="#Permissions">Request Location Permission</a></li>
|
<li><a href="#connect">Connect to Location Services</a></li>
|
||||||
<li><a href="#PlayServices">Check for Google Play Services</a></li>
|
<li><a href="#location-request">Set Up a Location Request</a></li>
|
||||||
<li><a href="#DefineCallbacks">Define Location Services Callbacks</a></li>
|
<li><a href="#updates">Request Location Updates</a></li>
|
||||||
<li><a href="#UpdateParameters">Specify Update Parameters</a></li>
|
<li><a href="#callback">Define the Location Update Callback</a></li>
|
||||||
<li><a href="#StartUpdates">Start Location Updates</a></li>
|
<li><a href="#stop-updates">Stop Location Updates</a></li>
|
||||||
<li><a href="#StopUpdates">Stop Location Updates</a></li>
|
<li><a href="#save-state">Save the State of the Activity</a></li>
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
<h2>You should also read</h2>
|
<h2>You should also read</h2>
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<a href="{@docRoot}google/play-services/setup.html">Setup Google Play Services SDK</a>
|
<a href="{@docRoot}google/play-services/setup.html">Setting up Google Play
|
||||||
|
Services</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="retrieve-current.html">Retrieving the Current Location</a>
|
<a href="retrieve-current.html">Getting the Last Known Location</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h2>Try it out</h2>
|
<h2>Try it out</h2>
|
||||||
|
|
||||||
<div class="download-box">
|
<ul>
|
||||||
<a href="http://developer.android.com/shareables/training/LocationUpdates.zip" class="button">Download the sample</a>
|
<li>
|
||||||
<p class="filename">LocationUpdates.zip</p>
|
<a href="https://github.com/googlesamples/android-play-location/tree/master/LocationUpdates" class="external-link">LocationUpdates</a>
|
||||||
</div>
|
</li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p>
|
<p>If your app can continuously track location, it can deliver more relevant
|
||||||
If your app does navigation or tracking, you probably want to get the user's
|
information to the user. For example, if your app helps the user find their
|
||||||
location at regular intervals. While you can do this with
|
way while walking or driving, or if your app tracks the location of assets, it
|
||||||
<code><a href="{@docRoot}reference/com/google/android/gms/location/LocationClient.html#getLastLocation()">LocationClient.getLastLocation()</a></code>,
|
needs to get the location of the device at regular intervals. As well as the
|
||||||
a more direct approach is to request periodic updates from Location Services. In
|
geographical location (latitude and longitude), you may want to give the user
|
||||||
response, Location Services automatically updates your app with the best available location,
|
further information such as the bearing (horizontal direction of travel),
|
||||||
based on the currently-available location providers such as WiFi and GPS.
|
altitude, or velocity of the device. This information, and more, is available
|
||||||
</p>
|
in the {@link android.location.Location} object that your app can retrieve
|
||||||
<p>
|
from the
|
||||||
To get periodic location updates from Location Services, you send a request using a location
|
<a href="{@docRoot}reference/com/google/android/gms/location/FusedLocationProviderApi.html">fused
|
||||||
client. Depending on the form of the request, Location Services either invokes a callback
|
location provider</a>.</p>
|
||||||
method and passes in a {@link android.location.Location} object, or issues an
|
|
||||||
{@link android.content.Intent} that contains the location in its extended data. The accuracy and
|
<p>While you can get a device's location with
|
||||||
frequency of the updates are affected by the location permissions you've requested and the
|
<a href="{@docRoot}reference/com/google/android/gms/location/FusedLocationProviderApi.html#getLastLocation(com.google.android.gms.common.api.GoogleApiClient)">{@code getLastLocation()}</a>,
|
||||||
parameters you pass to Location Services with the request.
|
as illustrated in the lesson on
|
||||||
</p>
|
<a href="retrieve-current.html">Getting the Last Known Location</a>,
|
||||||
<!-- Request permission -->
|
a more direct approach is to request periodic updates from the fused location
|
||||||
<h2 id="Permissions">Specify App Permissions</h2>
|
provider. In response, the API updates your app periodically with the best
|
||||||
<p>
|
available location, based on the currently-available location providers such
|
||||||
Apps that use Location Services must request location permissions. Android has two location
|
as WiFi and GPS (Global Positioning System). The accuracy of the location is
|
||||||
permissions, {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION}
|
determined by the providers, the location permissions you've requested, and
|
||||||
and {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION}. The
|
the options you set in the location request.</p>
|
||||||
permission you choose affects the accuracy of the location updates you receive.
|
|
||||||
For example, If you request only coarse location permission, Location Services obfuscates the
|
<p>This lesson shows you how to request regular updates about a device's
|
||||||
updated location to an accuracy that's roughly equivalent to a city block.
|
location using the
|
||||||
</p>
|
<a href="{@docRoot}reference/com/google/android/gms/location/FusedLocationProviderApi.html#requestLocationUpdates(com.google.android.gms.common.api.GoogleApiClient, com.google.android.gms.location.LocationRequest, com.google.android.gms.location.LocationListener)">{@code requestLocationUpdates()}</a>
|
||||||
<p>
|
method in the fused location provider.
|
||||||
Requesting {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} implies
|
|
||||||
a request for {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION}.
|
<h2 id="connect">Connect to Location Services</h2>
|
||||||
</p>
|
|
||||||
<p>
|
<p>Location services for apps are provided through Google Play services and the
|
||||||
For example, to add the coarse location permission to your manifest, insert the following as a
|
fused location provider. In order to use these services, you connect your app
|
||||||
child element of
|
using the Google API Client and then request location updates. For details on
|
||||||
the
|
connecting with the
|
||||||
<code><a href="{@docRoot}guide/topics/manifest/manifest-element.html"><manifest></a></code>
|
<a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.html">{@code GoogleApiClient}</a>,
|
||||||
element:
|
follow the instructions in
|
||||||
</p>
|
<a href="retrieve-current.html">Getting the Last Known Location</a>, including
|
||||||
<pre>
|
requesting the current location.</p>
|
||||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
|
|
||||||
</pre>
|
<p>The last known location of the device provides a handy base from which to
|
||||||
<!-- Check for Google Play services -->
|
start, ensuring that the app has a known location before starting the
|
||||||
<h2 id="PlayServices">Check for Google Play Services</h2>
|
periodic location updates. The lesson on
|
||||||
<p>
|
<a href="retrieve-current.html">Getting the Last Known Location</a> shows you
|
||||||
Location Services is part of the Google Play services APK. Since it's hard to anticipate the
|
how to get the last known location by calling
|
||||||
state of the user's device, you should always check that the APK is installed before you attempt
|
<a href="{@docRoot}reference/com/google/android/gms/location/FusedLocationProviderApi.html#getLastLocation(com.google.android.gms.common.api.GoogleApiClient)">{@code getLastLocation()}</a>.
|
||||||
to connect to Location Services. To check that the APK is installed, call
|
The snippets in the following sections assume that your app has already
|
||||||
<code><a href="{@docRoot}reference/com/google/android/gms/common/GooglePlayServicesUtil.html#isGooglePlayServicesAvailable(android.content.Context)">GooglePlayServicesUtil.isGooglePlayServicesAvailable()</a></code>,
|
retrieved the last known location and stored it as a
|
||||||
which returns one of the
|
{@link android.location.Location} object in the global variable
|
||||||
integer result codes listed in the API reference documentation. If you encounter an error,
|
{@code mCurrentLocation}.</p>
|
||||||
call
|
|
||||||
<code><a href="{@docRoot}reference/com/google/android/gms/common/GooglePlayServicesUtil.html#getErrorDialog(int, android.app.Activity, int)">GooglePlayServicesUtil.getErrorDialog()</a></code>
|
<p>Apps that use location services must request location permissions. In this
|
||||||
to retrieve localized dialog that prompts users to take the correct action, then display
|
lesson you require fine location detection, so that your app can get as
|
||||||
the dialog in a {@link android.support.v4.app.DialogFragment}. The dialog may allow the
|
precise a location as possible from the available location providers. Request
|
||||||
user to correct the problem, in which case Google Play services may send a result back to your
|
this permission with the
|
||||||
activity. To handle this result, override the method
|
{@code uses-permission} element in your app manifest, as shown in the
|
||||||
{@link android.support.v4.app.FragmentActivity#onActivityResult onActivityResult()}
|
following example:</p>
|
||||||
|
|
||||||
</p>
|
|
||||||
<p class="note">
|
|
||||||
<strong>Note:</strong> To make your app compatible with
|
|
||||||
platform version 1.6 and later, the activity that displays the
|
|
||||||
{@link android.support.v4.app.DialogFragment} must subclass
|
|
||||||
{@link android.support.v4.app.FragmentActivity} instead of {@link android.app.Activity}. Using
|
|
||||||
{@link android.support.v4.app.FragmentActivity} also allows you to call
|
|
||||||
{@link android.support.v4.app.FragmentActivity#getSupportFragmentManager
|
|
||||||
getSupportFragmentManager()} to display the {@link android.support.v4.app.DialogFragment}.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Since you usually need to check for Google Play services in more than one place in your code,
|
|
||||||
define a method that encapsulates the check, then call the method before each connection
|
|
||||||
attempt. The following snippet contains all of the code required to check for Google
|
|
||||||
Play services:
|
|
||||||
</p>
|
|
||||||
<pre>
|
<pre>
|
||||||
public class MainActivity extends FragmentActivity {
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
...
|
package="com.google.android.gms.location.sample.locationupdates" >
|
||||||
// Global constants
|
|
||||||
/*
|
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
|
||||||
* Define a request code to send to Google Play services
|
</manifest>
|
||||||
* This code is returned in Activity.onActivityResult
|
|
||||||
*/
|
|
||||||
private final static int
|
|
||||||
CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;
|
|
||||||
...
|
|
||||||
// Define a DialogFragment that displays the error dialog
|
|
||||||
public static class ErrorDialogFragment extends DialogFragment {
|
|
||||||
// Global field to contain the error dialog
|
|
||||||
private Dialog mDialog;
|
|
||||||
// Default constructor. Sets the dialog field to null
|
|
||||||
public ErrorDialogFragment() {
|
|
||||||
super();
|
|
||||||
mDialog = null;
|
|
||||||
}
|
|
||||||
// Set the dialog to display
|
|
||||||
public void setDialog(Dialog dialog) {
|
|
||||||
mDialog = dialog;
|
|
||||||
}
|
|
||||||
// Return a Dialog to the DialogFragment.
|
|
||||||
@Override
|
|
||||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
|
||||||
return mDialog;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
...
|
|
||||||
/*
|
|
||||||
* Handle results returned to the FragmentActivity
|
|
||||||
* by Google Play services
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected void onActivityResult(
|
|
||||||
int requestCode, int resultCode, Intent data) {
|
|
||||||
// Decide what to do based on the original request code
|
|
||||||
switch (requestCode) {
|
|
||||||
...
|
|
||||||
case CONNECTION_FAILURE_RESOLUTION_REQUEST :
|
|
||||||
/*
|
|
||||||
* If the result code is Activity.RESULT_OK, try
|
|
||||||
* to connect again
|
|
||||||
*/
|
|
||||||
switch (resultCode) {
|
|
||||||
case Activity.RESULT_OK :
|
|
||||||
/*
|
|
||||||
* Try the request again
|
|
||||||
*/
|
|
||||||
...
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
...
|
|
||||||
}
|
|
||||||
...
|
|
||||||
}
|
|
||||||
...
|
|
||||||
private boolean servicesConnected() {
|
|
||||||
// Check that Google Play services is available
|
|
||||||
int resultCode =
|
|
||||||
GooglePlayServicesUtil.
|
|
||||||
isGooglePlayServicesAvailable(this);
|
|
||||||
// If Google Play services is available
|
|
||||||
if (ConnectionResult.SUCCESS == resultCode) {
|
|
||||||
// In debug mode, log the status
|
|
||||||
Log.d("Location Updates",
|
|
||||||
"Google Play services is available.");
|
|
||||||
// Continue
|
|
||||||
return true;
|
|
||||||
// Google Play services was not available for some reason
|
|
||||||
} else {
|
|
||||||
// Get the error code
|
|
||||||
int errorCode = connectionResult.getErrorCode();
|
|
||||||
// Get the error dialog from Google Play services
|
|
||||||
Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog(
|
|
||||||
errorCode,
|
|
||||||
this,
|
|
||||||
CONNECTION_FAILURE_RESOLUTION_REQUEST);
|
|
||||||
// If Google Play services can provide an error dialog
|
|
||||||
if (errorDialog != null) {
|
|
||||||
// Create a new DialogFragment for the error dialog
|
|
||||||
ErrorDialogFragment errorFragment =
|
|
||||||
new ErrorDialogFragment();
|
|
||||||
// Set the dialog in the DialogFragment
|
|
||||||
errorFragment.setDialog(errorDialog);
|
|
||||||
// Show the error dialog in the DialogFragment
|
|
||||||
errorFragment.show(
|
|
||||||
getSupportFragmentManager(),
|
|
||||||
"Location Updates");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
...
|
|
||||||
}
|
|
||||||
</pre>
|
</pre>
|
||||||
<p>
|
|
||||||
Snippets in the following sections call this method to verify that Google Play services is
|
<h2 id="location-request">Set Up a Location Request</h2>
|
||||||
available.
|
|
||||||
</p>
|
<p>To store parameters for requests to the fused location provider, create a
|
||||||
<!--
|
<a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html">{@code LocationRequest}</a>.
|
||||||
Define Location Services Callbacks
|
The parameters determine the levels of accuracy requested. For details of all
|
||||||
-->
|
the options available in the location request, see the
|
||||||
<h2 id="DefineCallbacks">Define Location Services Callbacks</h2>
|
<a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html">{@code LocationRequest}</a>
|
||||||
<p>
|
class reference. This lesson sets the update interval, fastest update
|
||||||
Before you request location updates, you must first implement the interfaces that Location
|
interval, and priority, as described below:</p>
|
||||||
Services uses to communicate connection status to your app:
|
|
||||||
</p>
|
|
||||||
<dl>
|
|
||||||
<dt>
|
|
||||||
<code><a href="{@docRoot}reference/com/google/android/gms/common/GooglePlayServicesClient.ConnectionCallbacks.html">ConnectionCallbacks</a></code>
|
|
||||||
</dt>
|
|
||||||
<dd>
|
|
||||||
Specifies methods that Location Services calls when a location client is connected or
|
|
||||||
disconnected.
|
|
||||||
</dd>
|
|
||||||
<dt>
|
|
||||||
<code><a href="{@docRoot}reference/com/google/android/gms/common/GooglePlayServicesClient.OnConnectionFailedListener.html">OnConnectionFailedListener</a></code>
|
|
||||||
</dt>
|
|
||||||
<dd>
|
|
||||||
Specifies a method that Location Services calls if an error occurs while attempting to
|
|
||||||
connect the location client. This method uses the previously-defined {@code showErrorDialog}
|
|
||||||
method to display an error dialog that attempts to fix the problem using Google Play
|
|
||||||
services.
|
|
||||||
</dd>
|
|
||||||
</dl>
|
|
||||||
<p>
|
|
||||||
The following snippet shows how to specify the interfaces and define the methods:
|
|
||||||
</p>
|
|
||||||
<pre>
|
|
||||||
public class MainActivity extends FragmentActivity implements
|
|
||||||
GooglePlayServicesClient.ConnectionCallbacks,
|
|
||||||
GooglePlayServicesClient.OnConnectionFailedListener {
|
|
||||||
...
|
|
||||||
/*
|
|
||||||
* Called by Location Services when the request to connect the
|
|
||||||
* client finishes successfully. At this point, you can
|
|
||||||
* request the current location or start periodic updates
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void onConnected(Bundle dataBundle) {
|
|
||||||
// Display the connection status
|
|
||||||
Toast.makeText(this, "Connected", Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
...
|
|
||||||
/*
|
|
||||||
* Called by Location Services if the connection to the
|
|
||||||
* location client drops because of an error.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void onDisconnected() {
|
|
||||||
// Display the connection status
|
|
||||||
Toast.makeText(this, "Disconnected. Please re-connect.",
|
|
||||||
Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
...
|
|
||||||
/*
|
|
||||||
* Called by Location Services if the attempt to
|
|
||||||
* Location Services fails.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void onConnectionFailed(ConnectionResult connectionResult) {
|
|
||||||
/*
|
|
||||||
* Google Play services can resolve some errors it detects.
|
|
||||||
* If the error has a resolution, try sending an Intent to
|
|
||||||
* start a Google Play services activity that can resolve
|
|
||||||
* error.
|
|
||||||
*/
|
|
||||||
if (connectionResult.hasResolution()) {
|
|
||||||
try {
|
|
||||||
// Start an Activity that tries to resolve the error
|
|
||||||
connectionResult.startResolutionForResult(
|
|
||||||
this,
|
|
||||||
CONNECTION_FAILURE_RESOLUTION_REQUEST);
|
|
||||||
/*
|
|
||||||
* Thrown if Google Play services canceled the original
|
|
||||||
* PendingIntent
|
|
||||||
*/
|
|
||||||
} catch (IntentSender.SendIntentException e) {
|
|
||||||
// Log the error
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/*
|
|
||||||
* If no resolution is available, display a dialog to the
|
|
||||||
* user with the error.
|
|
||||||
*/
|
|
||||||
showErrorDialog(connectionResult.getErrorCode());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
...
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
<h3>Define the location update callback</h3>
|
|
||||||
<p>
|
|
||||||
Location Services sends location updates to your app either as an {@link android.content.Intent}
|
|
||||||
or as an argument passed to a callback method you define. This lesson shows you how to get the
|
|
||||||
update using a callback method, because that pattern works best for most use cases. If you want
|
|
||||||
to receive updates in the form of an {@link android.content.Intent}, read the lesson
|
|
||||||
<a href="activity-recognition.html">Recognizing the User's Current Activity</a>, which
|
|
||||||
presents a similar pattern.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
The callback method that Location Services invokes to send a location update to your app is
|
|
||||||
specified in the
|
|
||||||
<code><a href="{@docRoot}reference/com/google/android/gms/location/LocationListener.html">LocationListener</a></code>
|
|
||||||
interface, in the method
|
|
||||||
<code><a href="{@docRoot}reference/com/google/android/gms/location/LocationListener.html#onLocationChanged(android.location.Location)">onLocationChanged()</a></code>.
|
|
||||||
The incoming argument is a {@link android.location.Location} object containing the location's
|
|
||||||
latitude and longitude. The following snippet shows how to specify the interface and define
|
|
||||||
the method:
|
|
||||||
</p>
|
|
||||||
<pre>
|
|
||||||
public class MainActivity extends FragmentActivity implements
|
|
||||||
GooglePlayServicesClient.ConnectionCallbacks,
|
|
||||||
GooglePlayServicesClient.OnConnectionFailedListener,
|
|
||||||
LocationListener {
|
|
||||||
...
|
|
||||||
// Define the callback method that receives location updates
|
|
||||||
@Override
|
|
||||||
public void onLocationChanged(Location location) {
|
|
||||||
// Report to the UI that the location was updated
|
|
||||||
String msg = "Updated Location: " +
|
|
||||||
Double.toString(location.getLatitude()) + "," +
|
|
||||||
Double.toString(location.getLongitude());
|
|
||||||
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
...
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
<p>
|
|
||||||
Now that you have the callbacks prepared, you can set up the request for location updates.
|
|
||||||
The first step is to specify the parameters that control the updates.
|
|
||||||
</p>
|
|
||||||
<!-- Specify update parameters -->
|
|
||||||
<h2 id="UpdateParameters">Specify Update Parameters</h2>
|
|
||||||
<p>
|
|
||||||
Location Services allows you to control the interval between updates and the location accuracy
|
|
||||||
you want, by setting the values in a
|
|
||||||
<code><a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html">LocationRequest</a></code>
|
|
||||||
object and then sending this object as part of your request to start updates.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
First, set the following interval parameters:
|
|
||||||
</p>
|
|
||||||
<dl>
|
<dl>
|
||||||
<dt>
|
<dt>
|
||||||
Update interval
|
Update interval
|
||||||
</dt>
|
</dt>
|
||||||
<dd>
|
<dd>
|
||||||
Set by
|
<a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html#setInterval(long)">{@code setInterval()}</a>
|
||||||
<code><a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html#setInterval(long)">LocationRequest.setInterval()</a></code>.
|
- This method sets the rate in milliseconds at which your app prefers to
|
||||||
This method sets the rate in milliseconds at which your app prefers to receive location
|
receive location updates. Note that the location updates may be faster than
|
||||||
updates. If no other apps are receiving updates from Location Services, your app will
|
this rate if another app is receiving updates at a faster rate, or slower
|
||||||
receive updates at this rate.
|
than this rate, or there may be no updates at all (if the device has no
|
||||||
|
connectivity, for example).
|
||||||
</dd>
|
</dd>
|
||||||
<dt>
|
<dt>
|
||||||
Fastest update interval
|
Fastest update interval
|
||||||
</dt>
|
</dt>
|
||||||
<dd>
|
<dd>
|
||||||
Set by
|
<a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html#setFastestInterval(long)">{@code setFastestInterval()}</a>
|
||||||
<code><a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html#setFastestInterval(long)">LocationRequest.setFastestInterval()</a></code>.
|
- This method sets the <strong>fastest</strong> rate in milliseconds at which
|
||||||
This method sets the <b>fastest</b> rate in milliseconds at which your app can handle
|
your app can handle location updates. You need to set this rate because
|
||||||
location updates. You need to set this rate because other apps also affect the rate
|
other apps also affect the rate at which updates are sent. The Google Play
|
||||||
at which updates are sent. Location Services sends out updates at the fastest rate that any
|
services location APIs send out updates at the fastest rate that any app
|
||||||
app requested by calling
|
has requested with
|
||||||
<code><a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html#setInterval(long)">LocationRequest.setInterval()</a></code>.
|
<a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html#setInterval(long)">{@code setInterval()}</a>.
|
||||||
If this rate is faster than your app can handle, you may encounter problems with UI flicker
|
If this rate is faster
|
||||||
or data overflow. To prevent this, call
|
than your app can handle, you may encounter problems with UI flicker or data
|
||||||
<code><a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html#setFastestInterval(long)">LocationRequest.setFastestInterval()</a></code>
|
overflow. To prevent this, call
|
||||||
|
<a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html#setFastestInterval(long)">{@code setFastestInterval()}</a>
|
||||||
to set an upper limit to the update rate.
|
to set an upper limit to the update rate.
|
||||||
|
</dd>
|
||||||
|
<dt>Priority</dt>
|
||||||
|
<dd>
|
||||||
<p>
|
<p>
|
||||||
Calling
|
<a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html#setPriority(int)">{@code setPriority()}</a>
|
||||||
<code><a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html#setFastestInterval(long)">LocationRequest.setFastestInterval()</a></code>
|
- This method sets the priority of the request, which gives the Google Play
|
||||||
also helps to save power. When you request a preferred update rate by calling
|
services location services a strong hint about which location sources to use.
|
||||||
<code><a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html#setInterval(long)">LocationRequest.setInterval()</a></code>,
|
The following values are supported:</p>
|
||||||
and a maximum rate by calling
|
<ul>
|
||||||
<code><a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html#setFastestInterval(long)">LocationRequest.setFastestInterval()</a></code>,
|
<li>
|
||||||
then your app gets the same update rate as the fastest rate in the system. If other
|
<a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html#PRIORITY_BALANCED_POWER_ACCURACY">{@code PRIORITY_BALANCED_POWER_ACCURACY}</a>
|
||||||
apps have requested a faster rate, you get the benefit of a faster rate. If no other
|
- Use this setting to request location precision to within a city
|
||||||
apps have a faster rate request outstanding, your app receives updates at the rate you specified
|
block, which is an accuracy of approximately 100 meters. This is
|
||||||
with
|
considered a coarse level of accuracy, and is likely to consume less
|
||||||
<code><a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html#setInterval(long)">LocationRequest.setInterval()</a></code>.
|
power. With this setting, the location services are likely to use WiFi
|
||||||
</p>
|
and cell tower positioning. Note, however, that the choice of location
|
||||||
|
provider depends on many other factors, such as which sources are
|
||||||
|
available.</li>
|
||||||
|
<li>
|
||||||
|
<a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html#PRIORITY_HIGH_ACCURACY">{@code PRIORITY_HIGH_ACCURACY}</a>
|
||||||
|
- Use this setting to request the most precise location possible. With
|
||||||
|
this setting, the location services are more likely to use GPS
|
||||||
|
(Global Positioning System) to determine the location.</li>
|
||||||
|
<li><a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html#PRIORITY_LOW_POWER">{@code PRIORITY_LOW_POWER}</a>
|
||||||
|
- Use this setting to request city-level precision, which is
|
||||||
|
an accuracy of approximately 10 kilometers. This is considered a
|
||||||
|
coarse level of accuracy, and is likely to consume less power.</li>
|
||||||
|
<li><a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html#PRIORITY_NO_POWER">{@code PRIORITY_NO_POWER}</a>
|
||||||
|
- Use this setting if you need negligible impact on power consumption,
|
||||||
|
but want to receive location updates when available. With this
|
||||||
|
setting, your app does not trigger any location updates, but
|
||||||
|
receives locations triggered by other apps.</li>
|
||||||
|
</ul>
|
||||||
</dd>
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
<p>
|
|
||||||
Next, set the accuracy parameter. In a foreground app, you need constant location updates with
|
<p>Create the location request and set the parameters as shown in this
|
||||||
high accuracy, so use the setting
|
code sample:</p>
|
||||||
<code><a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html#PRIORITY_HIGH_ACCURACY">LocationRequest.PRIORITY_HIGH_ACCURACY</a></code>.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
The following snippet shows how to set the update interval and accuracy in
|
|
||||||
{@link android.support.v4.app.FragmentActivity#onCreate onCreate()}:
|
|
||||||
</p>
|
|
||||||
<pre>
|
<pre>
|
||||||
public class MainActivity extends FragmentActivity implements
|
protected void createLocationRequest() {
|
||||||
GooglePlayServicesClient.ConnectionCallbacks,
|
LocationRequest mLocationRequest = new LocationRequest();
|
||||||
GooglePlayServicesClient.OnConnectionFailedListener,
|
mLocationRequest.setInterval(10000);
|
||||||
LocationListener {
|
mLocationRequest.setFastestInterval(5000);
|
||||||
...
|
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
|
||||||
// Global constants
|
|
||||||
...
|
|
||||||
// Milliseconds per second
|
|
||||||
private static final int MILLISECONDS_PER_SECOND = 1000;
|
|
||||||
// Update frequency in seconds
|
|
||||||
public static final int UPDATE_INTERVAL_IN_SECONDS = 5;
|
|
||||||
// Update frequency in milliseconds
|
|
||||||
private static final long UPDATE_INTERVAL =
|
|
||||||
MILLISECONDS_PER_SECOND * UPDATE_INTERVAL_IN_SECONDS;
|
|
||||||
// The fastest update frequency, in seconds
|
|
||||||
private static final int FASTEST_INTERVAL_IN_SECONDS = 1;
|
|
||||||
// A fast frequency ceiling in milliseconds
|
|
||||||
private static final long FASTEST_INTERVAL =
|
|
||||||
MILLISECONDS_PER_SECOND * FASTEST_INTERVAL_IN_SECONDS;
|
|
||||||
...
|
|
||||||
// Define an object that holds accuracy and frequency parameters
|
|
||||||
LocationRequest mLocationRequest;
|
|
||||||
...
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
// Create the LocationRequest object
|
|
||||||
mLocationRequest = LocationRequest.create();
|
|
||||||
// Use high accuracy
|
|
||||||
mLocationRequest.setPriority(
|
|
||||||
LocationRequest.PRIORITY_HIGH_ACCURACY);
|
|
||||||
// Set the update interval to 5 seconds
|
|
||||||
mLocationRequest.setInterval(UPDATE_INTERVAL);
|
|
||||||
// Set the fastest update interval to 1 second
|
|
||||||
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
|
|
||||||
...
|
|
||||||
}
|
|
||||||
...
|
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
<p class="note">
|
|
||||||
<strong>Note:</strong> If your app accesses the network or does other long-running work after
|
<p>The priority of
|
||||||
receiving a location update, adjust the fastest interval to a slower value. This prevents your
|
<a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html#PRIORITY_HIGH_ACCURACY">{@code PRIORITY_HIGH_ACCURACY}</a>,
|
||||||
app from receiving updates it can't use. Once the long-running work is done, set the fastest
|
combined with the
|
||||||
interval back to a fast value.
|
{@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION}
|
||||||
</p>
|
permission setting that you've defined in the app manifest, and a fast update
|
||||||
<!-- Start Location Updates -->
|
interval of 5000 milliseconds (5 seconds), causes the fused location
|
||||||
<h2 id="StartUpdates">Start Location Updates</h2>
|
provider to return location updates that are accurate to within a few feet.
|
||||||
<p>
|
This approach is appropriate for mapping apps that display the location in
|
||||||
To send the request for location updates, create a location client in
|
real time.</p>
|
||||||
{@link android.support.v4.app.FragmentActivity#onCreate onCreate()}, then connect it and make
|
|
||||||
the request by calling
|
<p class="note"><strong>Performance hint:</strong> If your app accesses the
|
||||||
<code><a href="{@docRoot}reference/com/google/android/gms/location/LocationClient.html#requestLocationUpdates(com.google.android.gms.location.LocationRequest, com.google.android.gms.location.LocationListener)">requestLocationUpdates()</a></code>.
|
network or does other long-running work after receiving a location update,
|
||||||
Since your client must be connected for your app to receive updates, you should
|
adjust the fastest interval to a slower value. This adjustment prevents your
|
||||||
connect the client in
|
app from receiving updates it can't use. Once the long-running work is done,
|
||||||
{@link android.support.v4.app.FragmentActivity#onStart onStart()}. This ensures that you always
|
set the fastest interval back to a fast value.</p>
|
||||||
have a valid, connected client while your app is visible. Since you need a connection before you
|
|
||||||
can request updates, make the update request in
|
<h2 id="updates">Request Location Updates</h2>
|
||||||
<code><a href="{@docRoot}reference/com/google/android/gms/common/GooglePlayServicesClient.ConnectionCallbacks.html#onConnected(android.os.Bundle)">ConnectionCallbacks.onConnected()</a></code>
|
|
||||||
</p>
|
<p>Now that you've set up a location request containing your app's requirements
|
||||||
<p>
|
for the location updates, you can start the regular updates by calling
|
||||||
Remember that the user may want to turn off location updates for various reasons. You should
|
<a href="{@docRoot}reference/com/google/android/gms/location/FusedLocationProviderApi.html#requestLocationUpdates(com.google.android.gms.common.api.GoogleApiClient, com.google.android.gms.location.LocationRequest, com.google.android.gms.location.LocationListener)">{@code requestLocationUpdates()}</a>.
|
||||||
provide a way for the user to do this, and you should ensure that you don't start updates in
|
Do this in the
|
||||||
{@link android.support.v4.app.FragmentActivity#onStart onStart()} if updates were previously
|
<a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.ConnectionCallbacks.html#onConnected(android.os.Bundle)">{@code onConnected()}</a>
|
||||||
turned off. To track the user's preference, store it in your app's
|
callback provided by Google API Client, which is called when the client is
|
||||||
{@link android.content.SharedPreferences} in
|
ready.</p>
|
||||||
{@link android.support.v4.app.FragmentActivity#onPause onPause()} and retrieve it in
|
|
||||||
{@link android.support.v4.app.FragmentActivity#onResume onResume()}.
|
<p>Depending on the form of the request, the fused location provider either
|
||||||
</p>
|
invokes the
|
||||||
<p>
|
<a href="{@docRoot}reference/com/google/android/gms/location/LocationListener.html">{@code LocationListener.onLocationChanged()}</a>
|
||||||
The following snippet shows how to set up the client in
|
callback method and passes it a {@link android.location.Location} object, or
|
||||||
{@link android.support.v4.app.FragmentActivity#onCreate onCreate()}, and how to connect it
|
issues a
|
||||||
and request updates in {@link android.support.v4.app.FragmentActivity#onStart onStart()}:
|
<a href="{@docRoot}reference/android/app/PendingIntent.html">{@code PendingIntent}</a>
|
||||||
</p>
|
that contains the location in its extended data. The accuracy and frequency of
|
||||||
|
the updates are affected by the location permissions you've requested and the
|
||||||
|
options you set in the location request object.</p>
|
||||||
|
|
||||||
|
<p>This lesson shows you how to get the update using the
|
||||||
|
<a href="{@docRoot}reference/com/google/android/gms/location/LocationListener.html">{@code LocationListener}</a>
|
||||||
|
callback approach. Call
|
||||||
|
<a href="{@docRoot}reference/com/google/android/gms/location/FusedLocationProviderApi.html#requestLocationUpdates(com.google.android.gms.common.api.GoogleApiClient, com.google.android.gms.location.LocationRequest, com.google.android.gms.location.LocationListener)">{@code requestLocationUpdates()}</a>,
|
||||||
|
passing it your instance of the
|
||||||
|
<a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.html">{@code GoogleApiClient}</a>,
|
||||||
|
the
|
||||||
|
<a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html">{@code LocationRequest}</a>
|
||||||
|
object,
|
||||||
|
and a <a href="{@docRoot}reference/com/google/android/gms/location/LocationListener.html">{@code LocationListener}</a>.
|
||||||
|
Define a {@code startLocationUpdates()} method, called from the
|
||||||
|
<a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.ConnectionCallbacks.html#onConnected(android.os.Bundle)">{@code onConnected()}</a>
|
||||||
|
callback, as shown in the following code sample:</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
public class MainActivity extends FragmentActivity implements
|
@Override
|
||||||
GooglePlayServicesClient.ConnectionCallbacks,
|
public void onConnected(Bundle connectionHint) {
|
||||||
GooglePlayServicesClient.OnConnectionFailedListener,
|
|
||||||
LocationListener {
|
|
||||||
...
|
...
|
||||||
// Global variables
|
if (mRequestingLocationUpdates) {
|
||||||
...
|
startLocationUpdates();
|
||||||
LocationClient mLocationClient;
|
}
|
||||||
boolean mUpdatesRequested;
|
}
|
||||||
|
|
||||||
|
protected void startLocationUpdates() {
|
||||||
|
LocationServices.FusedLocationApi.requestLocationUpdates(
|
||||||
|
mGoogleApiClient, mLocationRequest, this);
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>Notice that the above code snippet refers to a boolean flag,
|
||||||
|
{@code mRequestingLocationUpdates}, used to track whether the user has
|
||||||
|
turned location updates on or off. For more about retaining the value of this
|
||||||
|
flag across instances of the activity, see
|
||||||
|
<a href="#save-state">Save the State of the Activity</a>.
|
||||||
|
|
||||||
|
<h2 id="callback">Define the Location Update Callback</h2>
|
||||||
|
|
||||||
|
<p>The fused location provider invokes the
|
||||||
|
<a href="{@docRoot}reference/com/google/android/gms/location/LocationListener.html#onLocationChanged(android.location.Location)">{@code LocationListener.onLocationChanged()}</a>
|
||||||
|
callback method. The incoming argument is a {@link android.location.Location}
|
||||||
|
object containing the location's latitude and longitude. The following snippet
|
||||||
|
shows how to implement the
|
||||||
|
<a href="{@docRoot}reference/com/google/android/gms/location/LocationListener.html">{@code LocationListener}</a>
|
||||||
|
interface and define the method, then get the timestamp of the location update
|
||||||
|
and display the latitude, longitude and timestamp on your app's user
|
||||||
|
interface:</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
public class MainActivity extends ActionBarActivity implements
|
||||||
|
ConnectionCallbacks, OnConnectionFailedListener, LocationListener {
|
||||||
...
|
...
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
public void onLocationChanged(Location location) {
|
||||||
...
|
mCurrentLocation = location;
|
||||||
// Open the shared preferences
|
mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
|
||||||
mPrefs = getSharedPreferences("SharedPreferences",
|
updateUI();
|
||||||
Context.MODE_PRIVATE);
|
|
||||||
// Get a SharedPreferences editor
|
|
||||||
mEditor = mPrefs.edit();
|
|
||||||
/*
|
|
||||||
* Create a new location client, using the enclosing class to
|
|
||||||
* handle callbacks.
|
|
||||||
*/
|
|
||||||
mLocationClient = new LocationClient(this, this, this);
|
|
||||||
// Start with updates turned off
|
|
||||||
mUpdatesRequested = false;
|
|
||||||
...
|
|
||||||
}
|
}
|
||||||
...
|
|
||||||
|
private void updateUI() {
|
||||||
|
mLatitudeTextView.setText(String.valueOf(mCurrentLocation.getLatitude()));
|
||||||
|
mLongitudeTextView.setText(String.valueOf(mCurrentLocation.getLongitude()));
|
||||||
|
mLastUpdateTimeTextView.setText(mLastUpdateTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<h2 id="stop-updates">Stop Location Updates</h2>
|
||||||
|
|
||||||
|
<p>Consider whether you want to stop the location updates when the activity is
|
||||||
|
no longer in focus, such as when the user switches to another app or to a
|
||||||
|
different activity in the same app. This can be handy to reduce power
|
||||||
|
consumption, provided the app doesn't need to collect information even when
|
||||||
|
it's running in the background. This section shows how you can stop the
|
||||||
|
updates in the activity's
|
||||||
|
{@link android.app.Activity#onPause onPause()} method.</p>
|
||||||
|
|
||||||
|
<p>To stop location updates, call
|
||||||
|
<a href="{@docRoot}reference/com/google/android/gms/location/FusedLocationProviderApi.html#removeLocationUpdates(com.google.android.gms.common.api.GoogleApiClient, com.google.android.gms.location.LocationListener)">{@code removeLocationUpdates()}</a>,
|
||||||
|
passing it your instance of the
|
||||||
|
<a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.html">{@code GoogleApiClient}</a>
|
||||||
|
object and a
|
||||||
|
<a href="{@docRoot}reference/com/google/android/gms/location/LocationListener.html">{@code LocationListener}</a>,
|
||||||
|
as shown in the following code sample:</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
@Override
|
@Override
|
||||||
protected void onPause() {
|
protected void onPause() {
|
||||||
// Save the current setting for updates
|
|
||||||
mEditor.putBoolean("KEY_UPDATES_ON", mUpdatesRequested);
|
|
||||||
mEditor.commit();
|
|
||||||
super.onPause();
|
super.onPause();
|
||||||
|
stopLocationUpdates();
|
||||||
}
|
}
|
||||||
...
|
|
||||||
@Override
|
|
||||||
protected void onStart() {
|
|
||||||
...
|
|
||||||
mLocationClient.connect();
|
|
||||||
}
|
|
||||||
...
|
|
||||||
@Override
|
|
||||||
protected void onResume() {
|
|
||||||
/*
|
|
||||||
* Get any previous setting for location updates
|
|
||||||
* Gets "false" if an error occurs
|
|
||||||
*/
|
|
||||||
if (mPrefs.contains("KEY_UPDATES_ON")) {
|
|
||||||
mUpdatesRequested =
|
|
||||||
mPrefs.getBoolean("KEY_UPDATES_ON", false);
|
|
||||||
|
|
||||||
// Otherwise, turn off location updates
|
protected void stopLocationUpdates() {
|
||||||
} else {
|
LocationServices.FusedLocationApi.removeLocationUpdates(
|
||||||
mEditor.putBoolean("KEY_UPDATES_ON", false);
|
mGoogleApiClient, this);
|
||||||
mEditor.commit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
...
|
|
||||||
/*
|
|
||||||
* Called by Location Services when the request to connect the
|
|
||||||
* client finishes successfully. At this point, you can
|
|
||||||
* request the current location or start periodic updates
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void onConnected(Bundle dataBundle) {
|
|
||||||
// Display the connection status
|
|
||||||
Toast.makeText(this, "Connected", Toast.LENGTH_SHORT).show();
|
|
||||||
// If already requested, start periodic updates
|
|
||||||
if (mUpdatesRequested) {
|
|
||||||
mLocationClient.requestLocationUpdates(mLocationRequest, this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
...
|
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
<p>
|
|
||||||
For more information about saving preferences, read
|
<p>Use a boolean, {@code mRequestingLocationUpdates}, to track
|
||||||
<a href="{@docRoot}training/basics/data-storage/shared-preferences.html">Saving Key-Value Sets</a>.
|
whether location updates are currently turned on. In the activity's
|
||||||
</p>
|
{@link android.app.Activity#onResume onResume()} method, check
|
||||||
<!--
|
whether location updates are currently active, and activate them if not:</p>
|
||||||
Stop Location Updates
|
|
||||||
-->
|
|
||||||
<h2 id="StopUpdates">Stop Location Updates</h2>
|
|
||||||
<p>
|
|
||||||
To stop location updates, save the state of the update flag in
|
|
||||||
{@link android.support.v4.app.FragmentActivity#onPause onPause()}, and stop updates in
|
|
||||||
{@link android.support.v4.app.FragmentActivity#onStop onStop()} by calling
|
|
||||||
<code><a href="{@docRoot}reference/com/google/android/gms/location/LocationClient.html#removeLocationUpdates(com.google.android.gms.location.LocationListener)">removeLocationUpdates(LocationListener)</a></code>.
|
|
||||||
For example:
|
|
||||||
</p>
|
|
||||||
<pre>
|
<pre>
|
||||||
public class MainActivity extends FragmentActivity implements
|
|
||||||
GooglePlayServicesClient.ConnectionCallbacks,
|
|
||||||
GooglePlayServicesClient.OnConnectionFailedListener,
|
|
||||||
LocationListener {
|
|
||||||
...
|
|
||||||
/*
|
|
||||||
* Called when the Activity is no longer visible at all.
|
|
||||||
* Stop updates and disconnect.
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStop() {
|
public void onResume() {
|
||||||
// If the client is connected
|
super.onResume();
|
||||||
if (mLocationClient.isConnected()) {
|
if (mGoogleApiClient.isConnected() && !mRequestingLocationUpdates) {
|
||||||
/*
|
startLocationUpdates();
|
||||||
* Remove location updates for a listener.
|
|
||||||
* The current Activity is the listener, so
|
|
||||||
* the argument is "this".
|
|
||||||
*/
|
|
||||||
removeLocationUpdates(this);
|
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
* After disconnect() is called, the client is
|
|
||||||
* considered "dead".
|
|
||||||
*/
|
|
||||||
mLocationClient.disconnect();
|
|
||||||
super.onStop();
|
|
||||||
}
|
|
||||||
...
|
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
<p>
|
|
||||||
You now have the basic structure of an app that requests and receives periodic location updates.
|
<h2 id="save-state">Save the State of the Activity</h2>
|
||||||
You can combine the features described in this lesson with the geofencing, activity recognition,
|
|
||||||
or reverse geocoding features described in other lessons in this class.
|
<p>A change to the device's configuration, such as a change in screen
|
||||||
</p>
|
orientation or language, can cause the current activity to be destroyed. Your
|
||||||
<p>
|
app must therefore store any information it needs to recreate the activity.
|
||||||
The next lesson, <a href="display-address.html">Displaying a Location Address</a>, shows you how
|
One way to do this is via an instance state stored in a
|
||||||
to use the current location to display the current street address.
|
{@link android.os.Bundle} object.</p>
|
||||||
</p>
|
|
||||||
|
<p>The following code sample shows how to use the activity's
|
||||||
|
<a href="{@docRoot}reference/android/app/Activity.html#onSaveInstanceState(android.os.Bundle)">{@code onSaveInstanceState()}</a>
|
||||||
|
callback to save the instance state:</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
public void onSaveInstanceState(Bundle savedInstanceState) {
|
||||||
|
savedInstanceState.putBoolean(REQUESTING_LOCATION_UPDATES_KEY,
|
||||||
|
mRequestingLocationUpdates);
|
||||||
|
savedInstanceState.putParcelable(LOCATION_KEY, mCurrentLocation);
|
||||||
|
savedInstanceState.putString(LAST_UPDATED_TIME_STRING_KEY, mLastUpdateTime);
|
||||||
|
super.onSaveInstanceState(savedInstanceState);
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>Define an {@code updateValuesFromBundle()} method to restore
|
||||||
|
the saved values from the previous instance of the activity, if they're
|
||||||
|
available. Call the method from the activity's
|
||||||
|
{@link android.app.Activity#onCreate onCreate()} method, as shown in the
|
||||||
|
following code sample:</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
...
|
||||||
|
updateValuesFromBundle(savedInstanceState);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateValuesFromBundle(Bundle savedInstanceState) {
|
||||||
|
if (savedInstanceState != null) {
|
||||||
|
// Update the value of mRequestingLocationUpdates from the Bundle, and
|
||||||
|
// make sure that the Start Updates and Stop Updates buttons are
|
||||||
|
// correctly enabled or disabled.
|
||||||
|
if (savedInstanceState.keySet().contains(REQUESTING_LOCATION_UPDATES_KEY)) {
|
||||||
|
mRequestingLocationUpdates = savedInstanceState.getBoolean(
|
||||||
|
REQUESTING_LOCATION_UPDATES_KEY);
|
||||||
|
setButtonsEnabledState();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the value of mCurrentLocation from the Bundle and update the
|
||||||
|
// UI to show the correct latitude and longitude.
|
||||||
|
if (savedInstanceState.keySet().contains(LOCATION_KEY)) {
|
||||||
|
// Since LOCATION_KEY was found in the Bundle, we can be sure that
|
||||||
|
// mCurrentLocationis not null.
|
||||||
|
mCurrentLocation = savedInstanceState.getParcelable(LOCATION_KEY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the value of mLastUpdateTime from the Bundle and update the UI.
|
||||||
|
if (savedInstanceState.keySet().contains(LAST_UPDATED_TIME_STRING_KEY)) {
|
||||||
|
mLastUpdateTime = savedInstanceState.getString(
|
||||||
|
LAST_UPDATED_TIME_STRING_KEY);
|
||||||
|
}
|
||||||
|
updateUI();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>For more about saving instance state, see the
|
||||||
|
<a href="{@docRoot}reference/android/app/Activity.html#ConfigurationChanges">Android
|
||||||
|
Activity</a> class reference.</p>
|
||||||
|
|
||||||
|
<p class="note"><strong>Note:</strong> For a more persistent storage, you can
|
||||||
|
store the user's preferences in your app's
|
||||||
|
{@link android.content.SharedPreferences}. Set the shared preference in
|
||||||
|
your activity's {@link android.app.Activity#onPause onPause()} method, and
|
||||||
|
retrieve the preference in {@link android.app.Activity#onResume onResume()}.
|
||||||
|
For more information about saving preferences, read
|
||||||
|
<a href="{@docRoot}training/basics/data-storage/shared-preferences.html">Saving
|
||||||
|
Key-Value Sets</a>.</p>
|
||||||
|
|
||||||
|
<p>The next lesson,
|
||||||
|
<a href="display-address.html">Displaying a Location Address</a>, shows
|
||||||
|
you how to display the street address for a given location.</p>
|
||||||
|
|||||||
Reference in New Issue
Block a user