Android Activity Recognition

DZone 's Guide to

Android Activity Recognition

· Mobile Zone ·
Free Resource

Activity Recognition gives our Android device the ability to detect a number of our physical activities like walking, riding a bicycle, driving a car or standing idle. All that can be detected by simply using an API to access Google Play Services, an increasingly crucial piece of software available to all Android versions.

As in the article on geofencing, we will download the sample app (ActivityRecognition.zip) at the Android developer’s site and start playing with it, eventually modifying parts of it to fit our purposes. We will show here only the most relevant code sections.

The first thing to note is that we need a specific permission to use Activity Recognition:

<!-- Inside manifest file -->

As with geofencing or location updates, we use the API to request Google Play Services to analyse our data and provide us with the results. The chain of method calls for requesting updates is similar to that of geofencing:

  1. Make sure that Google Play Services is available.
  2. As an Activity Recognition client, request a connection.
  3. Once connected, Location Services calls back the onConnected() method in our app.
  4. Proceed with the updates request via a Pending Intent pointing to an IntentService we have written.
  5. Google Location Services sends out its activity recognition updates as Intent objects, using the PendingIntent we provided. Get and process the updates in our IntentService’s onHandleIntent() method.

The sample app writes all the updates in a log file, and that is OK if we like that sort of thing … though a closer look at the data makes us realize that most of it is garbage. Do we really need to know that we have a 27 percent chance of being driving a vehicle and a 7 percent chance of riding a bicycle when we are in fact sitting idle at our desk? Not really. What we want is the most significant data, and in this case, that would be the most probable activity:

import com.google.android.gms.location.ActivityRecognitionResult;
import com.google.android.gms.location.DetectedActivity;

 * 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.
    protected void onHandleIntent(Intent intent) {
          // If the intent contains an update
        if (ActivityRecognitionResult.hasResult(intent)) {
            // Get the update
            ActivityRecognitionResult result =

             DetectedActivity mostProbableActivity
                    = result.getMostProbableActivity();

             // Get the confidence % (probability)
            int confidence = mostProbableActivity.getConfidence();

            // Get the type
            int activityType = mostProbableActivity.getType();
           /* types:
            * DetectedActivity.IN_VEHICLE
            * DetectedActivity.ON_BICYCLE
            * DetectedActivity.ON_FOOT
            * DetectedActivity.STILL
            * DetectedActivity.UNKNOWN
            * DetectedActivity.TILTING
            // process

Instead of writing the updates to a log file, it is simpler to just store them in memory (e.g. in a static List in a dedicated class) and display them to the user of our app. One way to do this would be by using a Fragment to display the updates on top of a Google map. As commented in previous articles, Fragments were introduced in Honeycomb but are also available to older Android versions through the Support Library.

<?xml version="1.0" encoding="utf-8"?>


<!-- activity recognition -->


Once we define our own XML layout for the ActReconFragment and give it a transparent background (left to the reader as an exercise), we will get a nice overlaid display like this:


Since we have chosen to show the most probable activity to the users of our app, we need the display to be dynamic, like a live feed. For that, we can add a local broadcast in our service:

//inside ActivityRecognitionIntentService 's onHandleIntent
Intent broadcastIntent = new Intent();

// Give it the category for all intents sent by the Intent Service
// Set the action and content for the broadcast intent

// Broadcast *locally* to other components in this app

We are using a LocalBroadcastManager (included in Android 3.0 and above, and in the support library v4 for early releases). Apart from providing our own layout to position the Activity Detection panel on top of a map, the only new code snippet we wrote is the above local broadcast. For the remainder below, we have simply re-positioned the sample app’s code in a fragment and use in-memory storage of the activity updates instead of using a log file. The receiver on that local broadcast is in our Fragment:

public class ActReconFragment extends Fragment{

 // Intent filter for incoming broadcasts from the IntentService
 IntentFilter mBroadcastFilter;

 // Instance of a local broadcast manager
 private LocalBroadcastManager mBroadcastManager;

 * Called when the corresponding Map Activity's
 * onCreate() method has completed.
public void onActivityCreated(Bundle savedInstanceState) {

  // Set the broadcast receiver intent filer
  mBroadcastManager = LocalBroadcastManager.getInstance(getActivity());

  // Create a new Intent filter for the broadcast receiver
  mBroadcastFilter = new IntentFilter(ActivityUtils.ACTION_REFRESH_STATUS_LIST);


* Broadcast receiver that receives activity update intents
* This receiver is local only. It can't read broadcast Intents from other apps.
BroadcastReceiver updateListReceiver = new BroadcastReceiver() {
   public void onReceive(Context context, Intent intent) {
     // When an Intent is received from the update listener IntentService,
     // update the display.

Live feed shots:


Once we have taken care of the display, we need to move on to other important aspects like what to do with those activity updates. The sample app gives us one example of that in the ActivityRecognitionIntentService:

   // If the current type is "moving" i.e on foot, bicycle or vehicle
  // The activity has changed from the previous activity
  // The confidence level for the current activity is >= 50%
  && (confidence >= 50)) {

  // do something useful

Simply getting the most probable activity might be OK for displaying purposes, but might not be enough for an app to act on it and do something useful. We need to make sure that the type of activity and the corresponding confidence level (i.e. probability) are adequate for our purposes. While a detected activity type of “Unknown” with a confidence level of 52% is next to useless, knowing that the user is moving in a vehicle as opposed to walking can be put to good use: increase the frequency of location updates, enlarge the map area of available points of interest, etc …

Activity Recognition has been added as an experimental feature to this Geofencing app. Check it out and feel free to post any feedback.

activity recognition ,java ,mobile ,tips and tricks ,tutorial

Published at DZone with permission of Tony Siciliani , DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}