am 4811f9b8: am ecf0ac29: am ca23a587: Merge "docs: Updates the request-location-updates lesson in the location APIs training course." into lmp-docs

* commit '4811f9b84766adc17efb730160e15785d74875a3':
  docs: Updates the request-location-updates lesson in the location APIs training course.
diff --git a/docs/html/training/location/receive-location-updates.jd b/docs/html/training/location/receive-location-updates.jd
index e6e8c51..208dc17 100644
--- a/docs/html/training/location/receive-location-updates.jd
+++ b/docs/html/training/location/receive-location-updates.jd
@@ -1,612 +1,417 @@
 page.title=Receiving Location Updates
 trainingnavtop=true
 @jd:body
+
 <div id="tb-wrapper">
-<div id="tb">
+  <div id="tb">
 
-<h2>This lesson teaches you to</h2>
-<ol>
-    <li><a href="#Permissions">Request Location Permission</a></li>
-    <li><a href="#PlayServices">Check for Google Play Services</a></li>
-    <li><a href="#DefineCallbacks">Define Location Services Callbacks</a></li>
-    <li><a href="#UpdateParameters">Specify Update Parameters</a></li>
-    <li><a href="#StartUpdates">Start Location Updates</a></li>
-    <li><a href="#StopUpdates">Stop Location Updates</a></li>
-</ol>
+  <h2>This lesson teaches you how to</h2>
+  <ol>
+    <li><a href="#connect">Connect to Location Services</a></li>
+    <li><a href="#location-request">Set Up a Location Request</a></li>
+    <li><a href="#updates">Request Location Updates</a></li>
+    <li><a href="#callback">Define the Location Update Callback</a></li>
+    <li><a href="#stop-updates">Stop Location Updates</a></li>
+    <li><a href="#save-state">Save the State of the Activity</a></li>
+  </ol>
 
-<h2>You should also read</h2>
-<ul>
+  <h2>You should also read</h2>
+  <ul>
     <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>
-        <a href="retrieve-current.html">Retrieving the Current Location</a>
+      <a href="retrieve-current.html">Getting the Last Known Location</a>
     </li>
- </ul>
+   </ul>
 
-<h2>Try it out</h2>
+  <h2>Try it out</h2>
 
-<div class="download-box">
-  <a href="http://developer.android.com/shareables/training/LocationUpdates.zip" class="button">Download the sample</a>
-  <p class="filename">LocationUpdates.zip</p>
+    <ul>
+      <li>
+        <a href="https://github.com/googlesamples/android-play-location/tree/master/LocationUpdates" class="external-link">LocationUpdates</a>
+      </li>
+    </ul>
+  </div>
 </div>
 
-</div>
-</div>
+<p>If your app can continuously track location, it can deliver more relevant
+  information to the user. For example, if your app helps the user find their
+  way while walking or driving, or if your app tracks the location of assets, it
+  needs to get the location of the device at regular intervals. As well as the
+  geographical location (latitude and longitude), you may want to give the user
+  further information such as the bearing (horizontal direction of travel),
+  altitude, or velocity of the device. This information, and more, is available
+  in the {@link android.location.Location} object that your app can retrieve
+  from the
+  <a href="{@docRoot}reference/com/google/android/gms/location/FusedLocationProviderApi.html">fused
+  location provider</a>.</p>
 
-<p>
-    If your app does navigation or tracking, you probably want to get the user's
-    location at regular intervals. While you can do this with
-<code><a href="{@docRoot}reference/com/google/android/gms/location/LocationClient.html#getLastLocation()">LocationClient.getLastLocation()</a></code>,
-    a more direct approach is to request periodic updates from Location Services. In
-    response, Location Services automatically updates your app with the best available location,
-    based on the currently-available location providers such as WiFi and GPS.
-</p>
-<p>
-    To get periodic location updates from Location Services, you send a request using a location
-    client. Depending on the form of the request, Location Services either invokes a callback
-    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
-    frequency of the updates are affected by the location permissions you've requested and the
-    parameters you pass to Location Services with the request.
-</p>
-<!-- Request permission -->
-<h2 id="Permissions">Specify App Permissions</h2>
-<p>
-    Apps that use Location Services must request location permissions. Android has two location
-    permissions, {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION}
-    and {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION}. The
-    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
-    updated location to an accuracy that's roughly equivalent to a city block.
-</p>
-<p>
-    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}.
-</p>
-<p>
-    For example, to add the coarse location permission to your manifest, insert the following as a
-    child element of
-    the
-<code><a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></code>
-    element:
-</p>
+<p>While you can get a device's location with
+  <a href="{@docRoot}reference/com/google/android/gms/location/FusedLocationProviderApi.html#getLastLocation(com.google.android.gms.common.api.GoogleApiClient)">{@code getLastLocation()}</a>,
+  as illustrated in the lesson on
+  <a href="retrieve-current.html">Getting the Last Known Location</a>,
+  a more direct approach is to request periodic updates from the fused location
+  provider. In response, the API updates your app periodically with the best
+  available location, based on the currently-available location providers such
+  as WiFi and GPS (Global Positioning System). The accuracy of the location is
+  determined by the providers, the location permissions you've requested, and
+  the options you set in the location request.</p>
+
+<p>This lesson shows you how to request regular updates about a device's
+  location using the
+  <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>
+  method in the fused location provider.
+
+<h2 id="connect">Connect to Location Services</h2>
+
+<p>Location services for apps are provided through Google Play services and the
+  fused location provider. In order to use these services, you connect your app
+  using the Google API Client and then request location updates. For details on
+  connecting with the
+  <a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.html">{@code GoogleApiClient}</a>,
+  follow the instructions in
+  <a href="retrieve-current.html">Getting the Last Known Location</a>, including
+  requesting the current location.</p>
+
+<p>The last known location of the device provides a handy base from which to
+  start, ensuring that the app has a known location before starting the
+  periodic location updates. The lesson on
+  <a href="retrieve-current.html">Getting the Last Known Location</a> shows you
+  how to get the last known location by calling
+  <a href="{@docRoot}reference/com/google/android/gms/location/FusedLocationProviderApi.html#getLastLocation(com.google.android.gms.common.api.GoogleApiClient)">{@code getLastLocation()}</a>.
+  The snippets in the following sections assume that your app has already
+  retrieved the last known location and stored it as a
+  {@link android.location.Location} object in the global variable
+  {@code mCurrentLocation}.</p>
+
+<p>Apps that use location services must request location permissions. In this
+  lesson you require fine location detection, so that your app can get as
+  precise a location as possible from the available location providers. Request
+  this permission with the
+  {@code uses-permission} element in your app manifest, as shown in the
+  following example:</p>
+
 <pre>
-&lt;uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/&gt;
-</pre>
-<!-- Check for Google Play services -->
-<h2 id="PlayServices">Check for Google Play Services</h2>
-<p>
-    Location Services is part of the Google Play services APK. Since it's hard to anticipate the
-    state of the user's device, you should always check that the APK is installed before you attempt
-    to connect to Location Services. To check that the APK is installed, call
-<code><a href="{@docRoot}reference/com/google/android/gms/common/GooglePlayServicesUtil.html#isGooglePlayServicesAvailable(android.content.Context)">GooglePlayServicesUtil.isGooglePlayServicesAvailable()</a></code>,
-    which returns one of the
-    integer result codes listed in the API reference documentation. If you encounter an error,
-    call
-<code><a href="{@docRoot}reference/com/google/android/gms/common/GooglePlayServicesUtil.html#getErrorDialog(int, android.app.Activity, int)">GooglePlayServicesUtil.getErrorDialog()</a></code>
-    to retrieve localized dialog that prompts users to take the correct action, then display
-    the dialog in a {@link android.support.v4.app.DialogFragment}. The dialog may allow the
-    user to correct the problem, in which case Google Play services may send a result back to your
-    activity. To handle this result, override the method
-    {@link android.support.v4.app.FragmentActivity#onActivityResult onActivityResult()}
+&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.google.android.gms.location.sample.locationupdates" &gt;
 
-</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>
-public class MainActivity extends FragmentActivity {
-    ...
-    // Global constants
-    /*
-     * Define a request code to send to Google Play services
-     * 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.
-        &#64;Override
-        public Dialog onCreateDialog(Bundle savedInstanceState) {
-            return mDialog;
-        }
-    }
-    ...
-    /*
-     * Handle results returned to the FragmentActivity
-     * by Google Play services
-     */
-    &#64;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");
-            }
-        }
-    }
-    ...
-}
+  &lt;uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/&gt;
+&lt;/manifest&gt;
 </pre>
-<p>
-    Snippets in the following sections call this method to verify that Google Play services is
-    available.
-</p>
-<!--
-    Define Location Services Callbacks
- -->
-<h2 id="DefineCallbacks">Define Location Services Callbacks</h2>
-<p>
-    Before you request location updates, you must first implement the interfaces that Location
-    Services uses to communicate connection status to your app:
-</p>
+
+<h2 id="location-request">Set Up a Location Request</h2>
+
+<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>.
+  The parameters determine the levels of accuracy requested. For details of all
+  the options available in the location request, see the
+  <a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html">{@code LocationRequest}</a>
+  class reference. This lesson sets the update interval, fastest update
+  interval, and priority, as described below:</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>
+  <dt>
+    Update interval
+  </dt>
+  <dd>
+    <a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html#setInterval(long)">{@code setInterval()}</a>
+    - 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).
+  </dd>
+  <dt>
+    Fastest update interval
+  </dt>
+  <dd>
+    <a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html#setFastestInterval(long)">{@code setFastestInterval()}</a>
+    - This method sets the <strong>fastest</strong> 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
+    <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 or data
+    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.
+  </dd>
+  <dt>Priority</dt>
+  <dd>
+    <p>
+      <a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html#setPriority(int)">{@code setPriority()}</a>
+      - 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:</p>
+      <ul>
+        <li>
+          <a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html#PRIORITY_BALANCED_POWER_ACCURACY">{@code PRIORITY_BALANCED_POWER_ACCURACY}</a>
+          - Use this setting to request location precision to within a city
+          block, which is an accuracy of approximately 100 meters. This is
+          considered a coarse level of accuracy, and is likely to consume less
+          power. With this setting, the location services are likely to use WiFi
+          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>
 </dl>
-<p>
-    The following snippet shows how to specify the interfaces and define the methods:
-</p>
+
+<p>Create the location request and set the parameters as shown in this
+  code sample:</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
-     */
-    &#64;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.
-     */
-    &#64;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.
-     */
-    &#64;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());
-        }
-    }
-    ...
+protected void createLocationRequest() {
+    LocationRequest mLocationRequest = new LocationRequest();
+    mLocationRequest.setInterval(10000);
+    mLocationRequest.setFastestInterval(5000);
+    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
 }
 </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>
+
+<p>The priority of
+  <a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html#PRIORITY_HIGH_ACCURACY">{@code PRIORITY_HIGH_ACCURACY}</a>,
+  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.</p>
+
+<p class="note"><strong>Performance hint:</strong> 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.</p>
+
+<h2 id="updates">Request Location Updates</h2>
+
+<p>Now that you've set up a location request containing your app's requirements
+  for the location updates, you can start the regular updates by calling
+  <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>.
+  Do this in the
+  <a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.ConnectionCallbacks.html#onConnected(android.os.Bundle)">{@code onConnected()}</a>
+  callback provided by Google API Client, which is called when the client is
+  ready.</p>
+
+<p>Depending on the form of the request, the fused location provider either
+  invokes the
+  <a href="{@docRoot}reference/com/google/android/gms/location/LocationListener.html">{@code LocationListener.onLocationChanged()}</a>
+  callback method and passes it a {@link android.location.Location} object, or
+  issues a
+  <a href="{@docRoot}reference/android/app/PendingIntent.html">{@code PendingIntent}</a>
+  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>
-public class MainActivity extends FragmentActivity implements
-        GooglePlayServicesClient.ConnectionCallbacks,
-        GooglePlayServicesClient.OnConnectionFailedListener,
-        LocationListener {
+&#64;Override
+public void onConnected(Bundle connectionHint) {
     ...
-    // Define the callback method that receives location updates
+    if (mRequestingLocationUpdates) {
+        startLocationUpdates();
+    }
+}
+
+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 {
+    ...
     &#64;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();
+        mCurrentLocation = location;
+        mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
+        updateUI();
     }
-    ...
-}
-</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>
-    <dt>
-        Update interval
-    </dt>
-    <dd>
-        Set by
-<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 receive location
-        updates. If no other apps are receiving updates from Location Services, your app will
-        receive updates at this rate.
-    </dd>
-    <dt>
-        Fastest update interval
-    </dt>
-    <dd>
-        Set by
-<code><a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html#setFastestInterval(long)">LocationRequest.setFastestInterval()</a></code>.
-        This method sets the <b>fastest</b> 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. Location Services sends out updates at the fastest rate that any
-        app requested by calling
-<code><a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html#setInterval(long)">LocationRequest.setInterval()</a></code>.
-        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><a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html#setFastestInterval(long)">LocationRequest.setFastestInterval()</a></code>
-        to set an upper limit to the update rate.
-        <p>
-            Calling
-<code><a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html#setFastestInterval(long)">LocationRequest.setFastestInterval()</a></code>
-            also helps to save power. When you request a preferred update rate by calling
-<code><a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html#setInterval(long)">LocationRequest.setInterval()</a></code>,
-            and a maximum rate by calling
-<code><a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html#setFastestInterval(long)">LocationRequest.setFastestInterval()</a></code>,
-            then your app gets the same update rate as the fastest rate in the system. If other
-            apps have requested a faster rate, you get the benefit of a faster rate. If no other
-            apps have a faster rate request outstanding, your app receives updates at the rate you specified
-        with
-<code><a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html#setInterval(long)">LocationRequest.setInterval()</a></code>.
-        </p>
-    </dd>
-</dl>
-<p>
-    Next, set the accuracy parameter. In a foreground app, you need constant location updates with
-    high accuracy, so use the setting
-<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>
-public class MainActivity extends FragmentActivity implements
-        GooglePlayServicesClient.ConnectionCallbacks,
-        GooglePlayServicesClient.OnConnectionFailedListener,
-        LocationListener {
-    ...
-    // 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;
-    ...
-    &#64;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>
-<p class="note">
-   <strong>Note:</strong> 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 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.
-</p>
-<!-- Start Location Updates -->
-<h2 id="StartUpdates">Start Location Updates</h2>
-<p>
-    To send the request for location updates, create a location client in
-    {@link android.support.v4.app.FragmentActivity#onCreate onCreate()}, then connect it and make
-    the request by calling
-<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>.
-    Since your client must be connected for your app to receive updates, you should
-    connect the client in
-    {@link android.support.v4.app.FragmentActivity#onStart onStart()}. This ensures that you always
-    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
-<code><a href="{@docRoot}reference/com/google/android/gms/common/GooglePlayServicesClient.ConnectionCallbacks.html#onConnected(android.os.Bundle)">ConnectionCallbacks.onConnected()</a></code>
-</p>
-<p>
-    Remember that the user may want to turn off location updates for various reasons. You should
-    provide a way for the user to do this, and you should ensure that you don't start updates in
-    {@link android.support.v4.app.FragmentActivity#onStart onStart()} if updates were previously
-    turned off. To track the user's preference, store it in your app's
-    {@link android.content.SharedPreferences} in
-    {@link android.support.v4.app.FragmentActivity#onPause onPause()} and retrieve it in
-    {@link android.support.v4.app.FragmentActivity#onResume onResume()}.
-</p>
-<p>
-    The following snippet shows how to set up the client in
-    {@link android.support.v4.app.FragmentActivity#onCreate onCreate()}, and how to connect it
-    and request updates in {@link android.support.v4.app.FragmentActivity#onStart onStart()}:
-</p>
-<pre>
-public class MainActivity extends FragmentActivity implements
-        GooglePlayServicesClient.ConnectionCallbacks,
-        GooglePlayServicesClient.OnConnectionFailedListener,
-        LocationListener {
-    ...
-    // Global variables
-    ...
-    LocationClient mLocationClient;
-    boolean mUpdatesRequested;
-    ...
-    &#64;Override
-    protected void onCreate(Bundle savedInstanceState) {
-        ...
-        // Open the shared preferences
-        mPrefs = getSharedPreferences("SharedPreferences",
-                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;
-        ...
-    }
-    ...
-    &#64;Override
-    protected void onPause() {
-        // Save the current setting for updates
-        mEditor.putBoolean("KEY_UPDATES_ON", mUpdatesRequested);
-        mEditor.commit();
-        super.onPause();
-    }
-    ...
-    &#64;Override
-    protected void onStart() {
-        ...
-        mLocationClient.connect();
-    }
-    ...
-    &#64;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
-        } else {
-            mEditor.putBoolean("KEY_UPDATES_ON", false);
-            mEditor.commit();
-        }
+    private void updateUI() {
+        mLatitudeTextView.setText(String.valueOf(mCurrentLocation.getLatitude()));
+        mLongitudeTextView.setText(String.valueOf(mCurrentLocation.getLongitude()));
+        mLastUpdateTimeTextView.setText(mLastUpdateTime);
     }
-    ...
-    /*
-     * 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
-     */
-    &#64;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>
-<p>
-    For more information about saving preferences, read
-<a href="{@docRoot}training/basics/data-storage/shared-preferences.html">Saving Key-Value Sets</a>.
-</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>
+
+<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>
-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.
-     */
-    &#64;Override
-    protected void onStop() {
-        // If the client is connected
-        if (mLocationClient.isConnected()) {
-            /*
-             * 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();
-    }
-    ...
+&#64;Override
+protected void onPause() {
+    super.onPause();
+    stopLocationUpdates();
+}
+
+protected void stopLocationUpdates() {
+    LocationServices.FusedLocationApi.removeLocationUpdates(
+            mGoogleApiClient, this);
 }
 </pre>
-<p>
-    You now have the basic structure of an app that requests and receives periodic location updates.
-    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>
-<p>
-    The next lesson, <a href="display-address.html">Displaying a Location Address</a>, shows you how
-    to use the current location to display the current street address.
-</p>
+
+<p>Use a boolean, {@code mRequestingLocationUpdates}, to track
+  whether location updates are currently turned on. In the activity's
+  {@link android.app.Activity#onResume onResume()} method, check
+  whether location updates are currently active, and activate them if not:</p>
+
+<pre>
+&#64;Override
+public void onResume() {
+    super.onResume();
+    if (mGoogleApiClient.isConnected() && !mRequestingLocationUpdates) {
+        startLocationUpdates();
+    }
+}
+</pre>
+
+<h2 id="save-state">Save the State of the Activity</h2>
+
+<p>A change to the device's configuration, such as a change in screen
+  orientation or language, can cause the current activity to be destroyed. Your
+  app must therefore store any information it needs to recreate the activity.
+  One way to do this is via an instance state stored in a
+  {@link android.os.Bundle} object.</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>
+&#64;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>