page.title=Recognizing the User's Current Activity

trainingnavtop=true
@jd:body

<div id="tb-wrapper">
<div id="tb">
<h2>This lesson teaches you to</h2>
<ol>
    <li><a href="#RequestUpdates">Request Activity Recognition Updates</a></li>
    <li><a href="#HandleUpdates">Handle Activity Updates</a>
    <li><a href="#RemoveUpdates">Stop Activity Recognition Updates</a>
</ol>
<h2>You should also read</h2>
<ul>
    <li>
        <a href="{@docRoot}google/play-services/setup.html">Setup Google Play Services SDK</a>
    </li>
    <li>
        <a href="receive-location-updates.html">Receiving Location Updates</a>
    </li>
</ul>
<h2>Try it out</h2>

<div class="download-box">
  <a href="http://developer.android.com/shareables/training/ActivityRecognition.zip" class="button">Download the sample</a>
  <p class="filename">ActivityRecognition.zip</p>
</div>

</div>
</div>

<p>
    Activity recognition tries to detect the user's current physical activity, such as walking,
    driving, or standing still. Requests for updates go through an activity recognition client,
    which, while different from the location client used by location or geofencing, follows a
    similar pattern. Based on the update interval you choose, Location Services sends out
    activity information containing one or more possible activities and the confidence level for
    each one. This lesson shows you how to request activity recognition updates from Location 
    Services.
</p>
<h2 id="RequestUpdates">Request Activity Recognition Updates</h2>
<p>
    Requesting activity recognition updates from Location Services is similar to requesting
    periodic location updates. You send the request through a client, and Location Services sends
    updates back to your app by means of a {@link android.app.PendingIntent}. However, you need to
    request a special permission before you request activity updates, and you use a different type
    of client to make requests. The following sections show how to request the permission,
    connect the client, and request updates.
</p>
<h3>Request permission to receive updates</h3>
<p>
    An app that wants to get activity recognition updates must have the permission
    {@code com.google.android.gms.permission.ACTIVITY_RECOGNITION}. To request this permission for
    your app, add the following XML element to your manifest as a child element of the
<code><a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></code>
    element:
</p>
<pre>
&lt;uses-permission
    android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION"/&gt;
</pre>
<p>
    Activity recognition does not require the permissions
    {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} or
    {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION}.
</p>
<!-- Check for Google Play services -->
<h3>Check for Google Play Services</h3>
<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()}

</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("Activity Recognition",
                    "Google Play services is available.");
            // Continue
            return true;
        // Google Play services was not available for some reason
        } 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(),
                        "Activity Recognition");
            }
            return false;
        }
    }
    ...
}
</pre>
<p>
    Snippets in the following sections call this method to verify that Google Play services is
    available.
</p>
<h3>Send the activity update request</h3>
<p>
    Send the update request from an {@link android.app.Activity} or
    {@link android.support.v4.app.Fragment} that implements the callback methods required by
    Location Services. Making the request is an asynchronous process that starts when you request
    a connection to an activity recognition client. When the client is connected, Location Services
    invokes your implementation of
<code><a href="{@docRoot}reference/com/google/android/gms/common/GooglePlayServicesClient.ConnectionCallbacks.html#onConnected(android.os.Bundle)">onConnected()</a></code>.
    In this method, you can send the update request to Location Services; this request is
    synchronous. Once you've made the request, you can disconnect the client.
</p>
<p>
    This process is described in the following snippets.
</p>
<h4 id="DefineActivity">Define the Activity or Fragment</h4>
<p>
    Define an {@link android.support.v4.app.FragmentActivity} or
    {@link android.support.v4.app.Fragment} that implements the following interfaces:
</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 the 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 client.
    </dd>
</dl>
<p>
    For example:
</p>
<pre>
public class MainActivity extends FragmentActivity implements
        ConnectionCallbacks, OnConnectionFailedListener {
    ...
}
</pre>
<p>
    Next, define global variables and constants.  Define constants for the update interval,
    add a variable for the activity recognition client, and another for the
    {@link android.app.PendingIntent} that Location Services uses to send updates to your app:
</p>
<pre>
public class MainActivity extends FragmentActivity implements
        ConnectionCallbacks, OnConnectionFailedListener {
    ...
    // Constants that define the activity detection interval
    public static final int MILLISECONDS_PER_SECOND = 1000;
    public static final int DETECTION_INTERVAL_SECONDS = 20;
    public static final int DETECTION_INTERVAL_MILLISECONDS =
            MILLISECONDS_PER_SECOND * DETECTION_INTERVAL_SECONDS;
    ...
    /*
     * Store the PendingIntent used to send activity recognition events
     * back to the app
     */
    private PendingIntent mActivityRecognitionPendingIntent;
    // Store the current activity recognition client
    private ActivityRecognitionClient mActivityRecognitionClient;
    ...
}
</pre>
<p>
    In {@link android.app.Activity#onCreate onCreate()}, instantiate the activity recognition
    client and the {@link android.app.PendingIntent}:
</p>
<pre>
public class MainActivity extends FragmentActivity implements
        ConnectionCallbacks, OnConnectionFailedListener {
    ...
    &#64;Override
    onCreate(Bundle savedInstanceState) {
        ...
        /*
         * Instantiate a new activity recognition client. Since the
         * parent Activity implements the connection listener and
         * connection failure listener, the constructor uses "this"
         * to specify the values of those parameters.
         */
        mActivityRecognitionClient =
                new ActivityRecognitionClient(mContext, this, this);
        /*
         * Create the PendingIntent that Location Services uses
         * to send activity recognition updates back to this app.
         */
        Intent intent = new Intent(
                mContext, ActivityRecognitionIntentService.class);
        /*
         * Return a PendingIntent that starts the IntentService.
         */
        mActivityRecognitionPendingIntent =
                PendingIntent.getService(mContext, 0, intent,
                PendingIntent.FLAG_UPDATE_CURRENT);
        ...
    }
    ...
}
</pre>
<h4>Start the request process</h4>
<p>
    Define a method that requests activity recognition updates. In the method, request a
    connection to Location Services. You can call this method from anywhere in your activity; its
    purpose is to start the chain of method calls for requesting updates.
</p>
<p>
    To guard against race conditions that might arise if your app tries to start another request
    before the first one finishes, define a boolean flag that tracks the state of the current
    request. Set the flag to {@code true} when you start a request, and then set it to
    {@code false} when the request completes.
</p>
<p>
    The following snippet shows how to start a request for updates:
</p>
<pre>
public class MainActivity extends FragmentActivity implements
        ConnectionCallbacks, OnConnectionFailedListener {
    ...
    // Global constants
    ...
    // Flag that indicates if a request is underway.
    private boolean mInProgress;
    ...
    &#64;Override
    onCreate(Bundle savedInstanceState) {
        ...
        // Start with the request flag set to false
        mInProgress = false;
        ...
    }
    ...
    /**
     * Request activity recognition updates based on the current
     * detection interval.
     *
     */
     public void startUpdates() {
        // Check for Google Play services

        if (!servicesConnected()) {
            return;
        }
        // If a request is not already underway
        if (!mInProgress) {
            // Indicate that a request is in progress
            mInProgress = true;
            // Request a connection to Location Services
            mActivityRecognitionClient.connect();
        //
        } else {
            /*
             * A request is already underway. You can handle
             * this situation by disconnecting the client,
             * re-setting the flag, and then re-trying the
             * request.
             */
        }
    }
    ...
}
</pre>
<p>
    Implement
<code><a href="{@docRoot}reference/com/google/android/gms/common/GooglePlayServicesClient.ConnectionCallbacks.html#onConnected(android.os.Bundle)">onConnected()</a></code>.
    In this method, request activity recognition updates from Location Services. When Location
    Services finishes connecting to the client and calls
<code><a href="{@docRoot}reference/com/google/android/gms/common/GooglePlayServicesClient.ConnectionCallbacks.html#onConnected(android.os.Bundle)">onConnected()</a></code>,
    the update request is called immediately:
</p>
<pre>
public class MainActivity extends FragmentActivity implements
        ConnectionCallbacks, OnConnectionFailedListener {
    ...
    /*
     * Called by Location Services once the location client is connected.
     *
     * Continue by requesting activity updates.
     */
    &#64;Override
    public void onConnected(Bundle dataBundle) {
        /*
         * Request activity recognition updates using the preset
         * detection interval and PendingIntent. This call is
         * synchronous.
         */
        mActivityRecognitionClient.requestActivityUpdates(
                DETECTION_INTERVAL_MILLISECONDS,
                mActivityRecognitionPendingIntent);
        /*
         * Since the preceding call is synchronous, turn off the
         * in progress flag and disconnect the client
         */
        mInProgress = false;
        mActivityRecognitionClient.disconnect();
    }
    ...
}
</pre>
<h3>Handle disconnections</h3>
<p>
    In some cases, Location Services may disconnect from the activity recognition client before
    you call
<code><a href="{@docRoot}reference/com/google/android/gms/location/ActivityRecognitionClient.html#disconnect()">disconnect()</a></code>.
    To handle this situation, implement <code>
<a href="{@docRoot}reference/com/google/android/gms/common/GooglePlayServicesClient.ConnectionCallbacks.html#onDisconnected()">onDisconnected()</a></code>.
    In this method, set the request flag to indicate that a request is not in progress, and
    delete the client:
</p>
<pre>
public class MainActivity extends FragmentActivity implements
        ConnectionCallbacks, OnConnectionFailedListener {
    ...
    /*
     * Called by Location Services once the activity recognition
     * client is disconnected.
     */
    &#64;Override
    public void onDisconnected() {
        // Turn off the request flag
        mInProgress = false;
        // Delete the client
        mActivityRecognitionClient = null;
    }
    ...
}
</pre>
<!-- Handle connection errors -->
<h3>Handle connection errors</h3>
<p>
    Besides handling the normal callbacks from Location Services, you have to provide a callback
    method that Location Services calls if a connection error occurs. This callback method
    can re-use the {@link android.support.v4.app.DialogFragment} class that you defined to
    handle the check for Google Play services. It can also re-use the override you defined
    for {@link android.support.v4.app.FragmentActivity#onActivityResult onActivityResult()} that
    receives any Google Play services results that occur when the user interacts with the
    error dialog. The following snippet shows you a sample implementation of the callback method:
</p>
<pre>
public class MainActivity extends FragmentActivity implements
        ConnectionCallbacks, OnConnectionFailedListener {
    ...
    // Implementation of OnConnectionFailedListener.onConnectionFailed
    &#64;Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        // Turn off the request flag
        mInProgress = false;
        /*
         * If the error has a resolution, start a Google Play services
         * activity to resolve it.
         */
        if (connectionResult.hasResolution()) {
            try {
                connectionResult.startResolutionForResult(
                        this,
                        CONNECTION_FAILURE_RESOLUTION_REQUEST);
            } catch (SendIntentException e) {
                // Log the error
                e.printStackTrace();
            }
        // If no resolution is available, display an error dialog
        } 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(),
                        "Activity Recognition");
            }
        }
        ...
    }
    ...
}
</pre>
<!-- Create Intent Service -->
<h2 id="HandleUpdates">Handle Activity Updates</h2>
<p>
    To handle the {@link android.content.Intent} that Location Services sends for each update
    interval, define an {@link android.app.IntentService} and its required method
    {@link android.app.IntentService#onHandleIntent onHandleIntent()}. Location Services
    sends out activity recognition updates as {@link android.content.Intent} objects, using the
    the {@link android.app.PendingIntent} you provided when you called
<code><a href="{@docRoot}reference/com/google/android/gms/location/ActivityRecognitionClient.html#requestActivityUpdates(long, android.app.PendingIntent)">requestActivityUpdates()</a></code>.
    Since you provided an explicit intent for the {@link android.app.PendingIntent}, the only
    component that receives the intent is the {@link android.app.IntentService} you're defining.
</p>
<p>
    The following snippets demonstrate how to examine the data in an activity recognition
    update.
</p>
<h3>Define an IntentService</h3>
<p>
    Start by defining the class and the required method
    {@link android.app.IntentService#onHandleIntent onHandleIntent()}:
</p>
<pre>
/**
 * Service that receives ActivityRecognition updates. It receives
 * updates in the background, even if the main Activity is not visible.
 */
public class ActivityRecognitionIntentService extends IntentService {
    ...
    /**
     * Called when a new activity detection update is available.
     */
    &#64;Override
    protected void onHandleIntent(Intent intent) {
        ...
    }
    ...
}
</pre>
<p>
    Next, examine the data in the intent. From the update, you can get a list of possible activities
    and the probability of each one. The following snippet shows how to get the most probable
    activity, the confidence level for the activity (the probability that this is the actual
    activity), and its type:
</p>
<pre>
public class ActivityRecognitionIntentService extends IntentService {
    ...
    &#64;Override
    protected void onHandleIntent(Intent intent) {
        ...
        // If the incoming intent contains an update
        if (ActivityRecognitionResult.hasResult(intent)) {
            // Get the update
            ActivityRecognitionResult result =
                    ActivityRecognitionResult.extractResult(intent);
            // Get the most probable activity
            DetectedActivity mostProbableActivity =
                    result.getMostProbableActivity();
            /*
             * Get the probability that this activity is the
             * the user's actual activity
             */
            int confidence = mostProbableActivity.getConfidence();
            /*
             * Get an integer describing the type of activity
             */
            int activityType = mostProbableActivity.getType();
            String activityName = getNameFromType(activityType);
            /*
             * At this point, you have retrieved all the information
             * for the current update. You can display this
             * information to the user in a notification, or
             * send it to an Activity or Service in a broadcast
             * Intent.
             */
            ...
        } else {
            /*
             * This implementation ignores intents that don't contain
             * an activity update. If you wish, you can report them as
             * errors.
             */
        }
        ...
    }
    ...
}
</pre>
<p>
    The method {@code getNameFromType()} converts activity types into descriptive
    strings. In a production app, you should retrieve the strings from resources instead of
    using fixed values:
</p>
<pre>
public class ActivityRecognitionIntentService extends IntentService {
    ...
    /**
     * Map detected activity types to strings
     *&#64;param activityType The detected activity type
     *&#64;return A user-readable name for the type
     */
    private String getNameFromType(int activityType) {
        switch(activityType) {
            case DetectedActivity.IN_VEHICLE:
                return "in_vehicle";
            case DetectedActivity.ON_BICYCLE:
                return "on_bicycle";
            case DetectedActivity.ON_FOOT:
                return "on_foot";
            case DetectedActivity.STILL:
                return "still";
            case DetectedActivity.UNKNOWN:
                return "unknown";
            case DetectedActivity.TILTING:
                return "tilting";
        }
        return "unknown";
    }
    ...
}
</pre>
<!-- Define IntentService -->
<h3>Specify the IntentService in the manifest</h3>
<p>
    To identify the {@link android.app.IntentService} to the system, add a
    <code><a href="{@docRoot}guide/topics/manifest/service-element.html">&lt;service&gt;</a></code>
    element to the app manifest. For example:
</p>
<pre>
&lt;service
    android:name="com.example.android.location.ActivityRecognitionIntentService"
    android:label="&#64;string/app_name"
    android:exported="false"&gt;
&lt;/service&gt;
</pre>
<p>
    Notice that you don't have to specify intent filters for the service, because it only receives
    explicit intents. How the incoming activity update intents are created is described in the
    section <a id="DefineActivity">Define the Activity or Fragment</a>.
</p>
<h2 id="RemoveUpdates">Stop Activity Recognition Updates</h2>
<p>
    To stop activity recognition updates, use the same pattern you used to request updates,
    but call <code>
<a href="{@docRoot}reference/com/google/android/gms/location/ActivityRecognitionClient.html#removeActivityUpdates(android.app.PendingIntent)">removeActivityUpdates()</a></code>
    instead of <code><a href="{@docRoot}reference/com/google/android/gms/location/ActivityRecognitionClient.html#requestActivityUpdates(long, android.app.PendingIntent)">requestActivityUpdates()</a></code>.
</p>
<p>
<p>
    Since removing updates uses some of the methods you use to add updates, start by defining
    request types for the two operations:
</p>
<pre>
public class MainActivity extends FragmentActivity implements
        ConnectionCallbacks, OnConnectionFailedListener {
    ...
    public enum REQUEST_TYPE {START, STOP}
    private REQUEST_TYPE mRequestType;
    ...
}
</pre>
<p>
    Modify the code that starts activity recognition so that it uses the {@code START}
    request type:
</p>
<pre>
public class MainActivity extends FragmentActivity implements
        ConnectionCallbacks, OnConnectionFailedListener {
    ...
    public void startUpdates() {
        // Set the request type to START
        mRequestType = REQUEST_TYPE.START;
        /*
         * Test for Google Play services after setting the request type.
         * If Google Play services isn't present, the proper request type
         * can be restarted.
         */
        if (!servicesConnected()) {
            return;
        }
        ...
    }
    ...
    public void onConnected(Bundle dataBundle) {
        switch (mRequestType) {
            case START :
                /*
                 * Request activity recognition updates using the
                 * preset detection interval and PendingIntent.
                 * This call is synchronous.
                 */
                mActivityRecognitionClient.requestActivityUpdates(
                        DETECTION_INTERVAL_MILLISECONDS,
                        mActivityRecognitionPendingIntent);
                break;
                ...
                /*
                 * An enum was added to the definition of REQUEST_TYPE,
                 * but it doesn't match a known case. Throw an exception.
                 */
                default :
                throw new Exception("Unknown request type in onConnected().");
                break;
        }
        ...
    }
    ...
}
</pre>
<h3>Start the process</h3>
<p>
    Define a method that requests a stop to activity recognition updates. In the method,
    set the request type and then request a connection to Location Services. You can call this
    method from anywhere in your activity; its purpose is to start the chain of method calls that
    stop activity updates:
</p>
<pre>
public class MainActivity extends FragmentActivity implements
        ConnectionCallbacks, OnConnectionFailedListener {
    ...
    /**
     * Turn off activity recognition updates
     *
     */
    public void stopUpdates() {
        // Set the request type to STOP
        mRequestType = REQUEST_TYPE.STOP;
        /*
         * Test for Google Play services after setting the request type.
         * If Google Play services isn't present, the request can be
         * restarted.
         */
        if (!servicesConnected()) {
            return;
        }
        // If a request is not already underway
        if (!mInProgress) {
            // Indicate that a request is in progress
            mInProgress = true;
            // Request a connection to Location Services
            mActivityRecognitionClient.connect();
        //
        } else {
            /*
             * A request is already underway. You can handle
             * this situation by disconnecting the client,
             * re-setting the flag, and then re-trying the
             * request.
             */
        }
        ...
    }
    ...
}
</pre>
<p>
    In
<code><a href="{@docRoot}reference/com/google/android/gms/common/GooglePlayServicesClient.ConnectionCallbacks.html#onConnected(android.os.Bundle)">onConnected()</a></code>,
    if the request type is STOP, call
<code><a href="{@docRoot}reference/com/google/android/gms/location/ActivityRecognitionClient.html#removeActivityUpdates(android.app.PendingIntent)">removeActivityUpdates()</a></code>.
    Pass the {@link android.app.PendingIntent} you used to start updates as the parameter to
<code><a href="{@docRoot}reference/com/google/android/gms/location/ActivityRecognitionClient.html#removeActivityUpdates(android.app.PendingIntent)">removeActivityUpdates()</a></code>:
</p>
<pre>
public class MainActivity extends FragmentActivity implements
        ConnectionCallbacks, OnConnectionFailedListener {
    ...
    public void onConnected(Bundle dataBundle) {
        switch (mRequestType) {
            ...
            case STOP :
            mActivityRecognitionClient.removeActivityUpdates(
                    mActivityRecognitionPendingIntent);
            break;
            ...
        }
        ...
    }
    ...
}
</pre>
<p>
    You do not have to modify your implementation of
<code><a href="{@docRoot}reference/com/google/android/gms/common/GooglePlayServicesClient.ConnectionCallbacks.html#onDisconnected()">onDisconnected()</a></code>
    or
<code><a href="{@docRoot}reference/com/google/android/gms/common/GooglePlayServicesClient.OnConnectionFailedListener.html#onConnectionFailed(com.google.android.gms.common.ConnectionResult)">onConnectionFailed()</a></code>,
    because these methods do not depend on the request type.
</p>
<p>
    You now have the basic structure of an app that implements activity recognition. You can combine
    activity recognition with other location-aware features, such as periodic location updates or
    geofencing, which are described in other lessons in this class.
</p>
