From 65dc25da3f77a9b62e80939007f95a56feb4ae0e Mon Sep 17 00:00:00 2001 From: Sarah Maddox Date: Tue, 28 Oct 2014 16:30:24 +1100 Subject: docs: Updates lesson 1 of location API training: Get last-known location. Uses GoogleApiClient to connect to Play services. Uses the latest Fused Location Provider API. Updates the entire tutorial and code sample for clarity and correctness. Bug: 17109822 Change-Id: I759a184a72d50702030b898a5f2e240cd3bdf4be --- docs/html/training/location/index.jd | 5 +- docs/html/training/location/retrieve-current.jd | 504 +++++++----------------- docs/html/training/training_toc.cs | 2 +- 3 files changed, 144 insertions(+), 367 deletions(-) (limited to 'docs') diff --git a/docs/html/training/location/index.jd b/docs/html/training/location/index.jd index f0024e2..059a1e9 100644 --- a/docs/html/training/location/index.jd +++ b/docs/html/training/location/index.jd @@ -67,9 +67,10 @@ startpage=true

Lessons

- Retrieving the Current Location + Getting the Last Known Location
- Learn how to retrieve the user's current location. + Learn how to retrieve the last known location of an Android device, which + is usually equivalent to the user's current location.
Receiving Location Updates diff --git a/docs/html/training/location/retrieve-current.jd b/docs/html/training/location/retrieve-current.jd index f079040..5bac3fa 100644 --- a/docs/html/training/location/retrieve-current.jd +++ b/docs/html/training/location/retrieve-current.jd @@ -1,386 +1,162 @@ -page.title=Retrieving the Current Location +page.title=Getting the Last Known Location trainingnavtop=true @jd:body -
-
-

This lesson teaches you to

-
    -
  1. Specify App Permissions
  2. -
  3. Check for Google Play services
  4. -
  5. Define Location Services Callbacks
  6. -
  7. Connect the Location Client
  8. -
  9. Get the Current Location
  10. -
+
+
-

You should also read

- +

This lesson teaches you how to

+
    +
  1. Set Up Google Play Services
  2. +
  3. Specify App Permissions
  4. +
  5. Connect to Google Play Services
  6. +
  7. Get the Last Known Location
  8. +
-

Try it out

+

You should also read

+ -
- Download the sample -

LocationUpdates.zip

+

Try it out

+ +
-
-
+

Using the Google Play services location APIs, your app can request the last + known location of the user's device. In most cases, you are interested in the + user's current location, which is usually equivalent to the last known + location of the device.

+ +

Specifically, use the + fused + location provider to retrieve the device's last known location. The fused + location provider is one of the location APIs in Google Play services. It + manages the underlying location technology and provides a simple API so that + you can specify requirements at a high level, like high accuracy or low power. + It also optimizes the device's use of battery power.

+ +

This lesson shows you how to make a single request for the location of a + device using the + {@code getLastLocation()} + method in the fused location provider. + +

Set Up Google Play Services

+ +

To access the fused location provider, your app's development project must + include Google Play services. Download and install the Google Play services + component via the SDK + Manager and add the library to your project. For details, see the guide to + Setting Up Google Play + Services.

+ +

Specify App Permissions

+ +

Apps that use location services must request location permissions. Android + offers 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 determines the accuracy of the location returned by + the API. If you specify + {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION}, + the API returns a location with an accuracy approximately equivalent to a city + block.

+ +

This lesson requires only coarse location. Request this permission with the + {@code uses-permission} element in your app manifest, as shown in the + following example: -

- Location Services automatically maintains the user's current location, so all your app has to do - is retrieve it as needed. The location's accuracy is based on the location permissions you've - requested and location sensors that are currently active for the device. -

- Location Services sends the current location to your app through a location client, which is - an instance of the Location Services class -LocationClient. - All requests for location information go through this client. -

-

- Note: Before you start the lesson, be sure that your development environment - and test device are set up correctly. To learn more about this, read the - Setup section in the Google Play - services guide. -

- -

Specify App Permissions

-

- 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 controls the accuracy of the current location. If you request only coarse - location permission, Location Services obfuscates the returned 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 {@link android.Manifest.permission#ACCESS_COARSE_LOCATION - ACCESS_COARSE_LOCATION}, insert the following as a child element of the - <manifest> - element: -

-<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.google.android.gms.location.sample.basiclocationsample" >
+  
+  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
+</manifest>
 
- -

Check for Google Play Services

-

- 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 reference documentation for -ConnectionResult. - 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()}. -

-

- 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.
-        // resultCode holds the error code.
-        } else {
-            // Get the error dialog from Google Play services
-            Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog(
-                    resultCode,
-                    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");
-            }
-        }
-    }
-    ...
-}
-
-

- Snippets in the following sections call this method to verify that Google Play services is - available. -

- -

Define Location Services Callbacks

-

- To get the current location, create a location client, connect it - to Location Services, and then call its -getLastLocation() - method. The return value is the best, most recent location, based on the permissions your - app requested and the currently-enabled location sensors. -

-

- Before you create the location client, implement the interfaces that Location Services uses to - communicate with your app: -

-
-
-ConnectionCallbacks -
-
- Specifies methods that Location Services calls when a location client is connected or - disconnected. -
-
-OnConnectionFailedListener -
-
- 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. -
-
-

- The following snippet shows how to specify the interfaces and define the methods: +

Connect to Google Play Services

+ +

To connect to the API, you need to create an instance of the + Google Play services API client. For details about using the client, see + the guide to + Accessing Google + APIs.

-
-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());
-        }
-    }
-    ...
+

In your activity's {@link android.app.Activity#onCreate onCreate()} method, + create an instance of Google API Client using + {@code GoogleApiClient.Builder}. + Use the builder to add the + {@code LocationServices} + API.

+ +

The sample app defines a {@code buildGoogleApiClient()} method, called from + the activity's {@link android.app.Activity#onCreate onCreate()} method, + which includes the following code.

+ +
+protected synchronized void buildGoogleApiClient() {
+    mGoogleApiClient = new GoogleApiClient.Builder(this)
+        .addConnectionCallbacks(this)
+        .addOnConnectionFailedListener(this)
+        .addApi(LocationServices.API)
+        .build();
 }
 
- -

Connect the Location Client

-

- Now that the callback methods are in place, create the location client and connect it to - Location Services. -

-

- You should create the location client in {@link android.support.v4.app.FragmentActivity#onCreate - onCreate()}, then connect it in - {@link android.support.v4.app.FragmentActivity#onStart onStart()}, so that Location Services - maintains the current location while your activity is fully visible. Disconnect the client in - {@link android.support.v4.app.FragmentActivity#onStop onStop()}, so that when your app is not - visible, Location Services is not maintaining the current location. Following this pattern of - connection and disconnection helps save battery power. For example: -

-

- Note: The current location is only maintained while a location client is - connected to Location Service. Assuming that no other apps are connected to Location Services, - if you disconnect the client and then sometime later call -getLastLocation(), - the result may be out of date. -

+ +

Get the Last Known Location

+ +

Once you have connected to Google Play services and the location services + API, you can get the last known location of a user's device. When your app is + connected to these you can use the fused location provider's + {@code getLastLocation()} + method to retrieve the device location. The precision of the location returned + by this call is determined by the permission setting you put in your app + manifest, as described in the Specify App + Permissions section of this document.

+ +

To request the last known location, call the + {@code getLastLocation()} + method, passing it your instance of the + {@code GoogleApiClient} + object. Do this in the + {@code onConnected()} + callback provided by Google API Client, which is called when the client is + ready. The following code sample illustrates the request and a simple + handling of the response:

+
-public class MainActivity extends FragmentActivity implements
-        GooglePlayServicesClient.ConnectionCallbacks,
-        GooglePlayServicesClient.OnConnectionFailedListener {
-    ...
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        ...
-        /*
-         * Create a new location client, using the enclosing class to
-         * handle callbacks.
-         */
-        mLocationClient = new LocationClient(this, this, this);
-        ...
-    }
-    ...
-    /*
-     * Called when the Activity becomes visible.
-     */
-    @Override
-    protected void onStart() {
-        super.onStart();
-        // Connect the client.
-        mLocationClient.connect();
-    }
+public class MainActivity extends ActionBarActivity implements
+        ConnectionCallbacks, OnConnectionFailedListener {
     ...
-    /*
-     * Called when the Activity is no longer visible.
-     */
     @Override
-    protected void onStop() {
-        // Disconnecting the client invalidates it.
-        mLocationClient.disconnect();
-        super.onStop();
+    public void onConnected(Bundle connectionHint) {
+        mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
+                mGoogleApiClient);
+        if (mLastLocation != null) {
+            mLatitudeText.setText(String.valueOf(mLastLocation.getLatitude()));
+            mLongitudeText.setText(String.valueOf(mLastLocation.getLongitude()));
+        }
     }
-    ...
 }
 
- -

Get the Current Location

-

- To get the current location, call -getLastLocation(). - For example: -

-
-public class MainActivity extends FragmentActivity implements
-        GooglePlayServicesClient.ConnectionCallbacks,
-        GooglePlayServicesClient.OnConnectionFailedListener {
-    ...
-    // Global variable to hold the current location
-    Location mCurrentLocation;
-    ...
-    mCurrentLocation = mLocationClient.getLastLocation();
-    ...
-}
-
-

- The next lesson, Receiving Location Updates, shows - you how to receive periodic location updates from Location Services. -

+ +

The + {@code getLastLocation()} + method returns a + {@code Location} + object from which you can retrieve the latitude and longitude coordinates of a + geographic location. The location object returned may be null in rare cases + when the location is not available.

+ +

The next lesson, + Receiving Location Updates, shows + you how to receive periodic location updates.

diff --git a/docs/html/training/training_toc.cs b/docs/html/training/training_toc.cs index f3b2693..2489b91 100644 --- a/docs/html/training/training_toc.cs +++ b/docs/html/training/training_toc.cs @@ -694,7 +694,7 @@ include the action bar on devices running Android 2.1 or higher."