diff --git a/docs/html/training/location/receive-location-updates.jd b/docs/html/training/location/receive-location-updates.jd index e6e8c51a50787..208dc1799faf3 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 +
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 + fused + location provider.
+ +While you can get a device's location with + {@code getLastLocation()}, + as illustrated in the lesson on + Getting the Last Known Location, + 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.
+ +This lesson shows you how to request regular updates about a device's + location using the + {@code requestLocationUpdates()} + method in the fused location provider. + +
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 + {@code GoogleApiClient}, + follow the instructions in + Getting the Last Known Location, including + requesting the current location.
+ +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 + Getting the Last Known Location shows you + how to get the last known location by calling + {@code getLastLocation()}. + 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}.
+ +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:
-
- 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
-LocationClient.getLastLocation(),
- 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.
-
- 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. -
- -- 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. -
-- 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}. -
-
- For example, to add the coarse location permission to your manifest, insert the following as a
- child element of
- the
-<manifest>
- element:
-
-<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> -- -
- 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
-GooglePlayServicesUtil.isGooglePlayServicesAvailable(),
- which returns one of the
- integer result codes listed in the API reference documentation. If you encounter an error,
- call
-GooglePlayServicesUtil.getErrorDialog()
- 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()}
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.google.android.gms.location.sample.locationupdates" >
-
- Note: 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}. -
-- 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: -
-
-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.
- @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");
- }
- }
- }
- ...
-}
+ <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
+</manifest>
-- Snippets in the following sections call this method to verify that Google Play services is - available. -
- -- Before you request location updates, you must first implement the interfaces that Location - Services uses to communicate connection status to your app: -
+ +To store parameters for requests to the fused location provider, create a + {@code LocationRequest}. + The parameters determine the levels of accuracy requested. For details of all + the options available in the location request, see the + {@code LocationRequest} + class reference. This lesson sets the update interval, fastest update + interval, and priority, as described below:
+ConnectionCallbacks
- OnConnectionFailedListener
- + {@code setPriority()} + - This method sets the priority of the request, which gives the Google Play + services location services a strong hint about which location sources to use. + The following values are supported:
+- The following snippet shows how to specify the interfaces and define the methods: -
+ +Create the location request and set the parameters as shown in this + code sample:
+
-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());
- }
- }
- ...
+protected void createLocationRequest() {
+ LocationRequest mLocationRequest = new LocationRequest();
+ mLocationRequest.setInterval(10000);
+ mLocationRequest.setFastestInterval(5000);
+ mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
-- 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 - Recognizing the User's Current Activity, which - presents a similar pattern. -
-
- The callback method that Location Services invokes to send a location update to your app is
- specified in the
-LocationListener
- interface, in the method
-onLocationChanged().
- 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:
-
The priority of + {@code PRIORITY_HIGH_ACCURACY}, + combined with the + {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} + permission setting that you've defined in the app manifest, and a fast update + interval of 5000 milliseconds (5 seconds), causes the fused location + provider to return location updates that are accurate to within a few feet. + This approach is appropriate for mapping apps that display the location in + real time.
+ +Performance hint: If your app accesses the + network or does other long-running work after receiving a location update, + adjust the fastest interval to a slower value. This adjustment prevents your + app from receiving updates it can't use. Once the long-running work is done, + set the fastest interval back to a fast value.
+ +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 + {@code requestLocationUpdates()}. + Do this in the + {@code onConnected()} + callback provided by Google API Client, which is called when the client is + ready.
+ +Depending on the form of the request, the fused location provider either + invokes the + {@code LocationListener.onLocationChanged()} + callback method and passes it a {@link android.location.Location} object, or + issues a + {@code PendingIntent} + 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.
+ +This lesson shows you how to get the update using the + {@code LocationListener} + callback approach. Call + {@code requestLocationUpdates()}, + passing it your instance of the + {@code GoogleApiClient}, + the + {@code LocationRequest} + object, + and a {@code LocationListener}. + Define a {@code startLocationUpdates()} method, called from the + {@code onConnected()} + callback, as shown in the following code sample:
+
-public class MainActivity extends FragmentActivity implements
- GooglePlayServicesClient.ConnectionCallbacks,
- GooglePlayServicesClient.OnConnectionFailedListener,
- LocationListener {
+@Override
+public void onConnected(Bundle connectionHint) {
+ ...
+ if (mRequestingLocationUpdates) {
+ startLocationUpdates();
+ }
+}
+
+protected void startLocationUpdates() {
+ LocationServices.FusedLocationApi.requestLocationUpdates(
+ mGoogleApiClient, mLocationRequest, this);
+}
+
+
+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 + Save the State of the Activity. + +
The fused location provider invokes the + {@code LocationListener.onLocationChanged()} + 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 + {@code LocationListener} + 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:
+ +
+public class MainActivity extends ActionBarActivity implements
+ ConnectionCallbacks, 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();
+ mCurrentLocation = location;
+ mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
+ updateUI();
}
- ...
-}
-
-- 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. -
- -
- Location Services allows you to control the interval between updates and the location accuracy
- you want, by setting the values in a
-LocationRequest
- object and then sending this object as part of your request to start updates.
-
- First, set the following interval parameters: -
-LocationRequest.setInterval().
- 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.
- LocationRequest.setFastestInterval().
- This method sets the fastest rate in milliseconds at which your app can handle
- location updates. You need to set this rate because other apps also affect the rate
- at which updates are sent. Location Services sends out updates at the fastest rate that any
- app requested by calling
-LocationRequest.setInterval().
- If this rate is faster than your app can handle, you may encounter problems with UI flicker
- or data overflow. To prevent this, call
-LocationRequest.setFastestInterval()
- to set an upper limit to the update rate.
-
- Calling
-LocationRequest.setFastestInterval()
- also helps to save power. When you request a preferred update rate by calling
-LocationRequest.setInterval(),
- and a maximum rate by calling
-LocationRequest.setFastestInterval(),
- 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
-LocationRequest.setInterval().
-
- Next, set the accuracy parameter. In a foreground app, you need constant location updates with
- high accuracy, so use the setting
-LocationRequest.PRIORITY_HIGH_ACCURACY.
-
- The following snippet shows how to set the update interval and accuracy in - {@link android.support.v4.app.FragmentActivity#onCreate onCreate()}: -
-
-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;
- ...
- @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);
- ...
- }
- ...
-}
-
-- Note: 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. -
- -
- 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
-requestLocationUpdates().
- 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
-ConnectionCallbacks.onConnected()
-
- 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()}. -
-- 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()}: -
-
-public class MainActivity extends FragmentActivity implements
- GooglePlayServicesClient.ConnectionCallbacks,
- GooglePlayServicesClient.OnConnectionFailedListener,
- LocationListener {
- ...
- // Global variables
- ...
- LocationClient mLocationClient;
- boolean mUpdatesRequested;
- ...
- @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;
- ...
- }
- ...
- @Override
- protected void onPause() {
- // Save the current setting for updates
- mEditor.putBoolean("KEY_UPDATES_ON", mUpdatesRequested);
- mEditor.commit();
- super.onPause();
- }
- ...
- @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
- } 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
- */
- @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);
- }
- }
- ...
}
-- For more information about saving preferences, read -Saving Key-Value Sets. -
- -
- 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
-removeLocationUpdates(LocationListener).
- For example:
-
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.
+ +To stop location updates, call + {@code removeLocationUpdates()}, + passing it your instance of the + {@code GoogleApiClient} + object and a + {@code LocationListener}, + as shown in the following code sample:
+
-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
- 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();
- }
- ...
+@Override
+protected void onPause() {
+ super.onPause();
+ stopLocationUpdates();
+}
+
+protected void stopLocationUpdates() {
+ LocationServices.FusedLocationApi.removeLocationUpdates(
+ mGoogleApiClient, this);
}
-- 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. -
-- The next lesson, Displaying a Location Address, shows you how - to use the current location to display the current street address. -
+ +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:
+ +
+@Override
+public void onResume() {
+ super.onResume();
+ if (mGoogleApiClient.isConnected() && !mRequestingLocationUpdates) {
+ startLocationUpdates();
+ }
+}
+
+
+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.
+ +The following code sample shows how to use the activity's + {@code onSaveInstanceState()} + callback to save the instance state:
+ +
+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);
+}
+
+
+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:
+ +
+@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();
+ }
+}
+
+
+For more about saving instance state, see the + Android + Activity class reference.
+ +Note: 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 + Saving + Key-Value Sets.
+ +The next lesson, + Displaying a Location Address, shows + you how to display the street address for a given location.