New Activity Recognition Transition API

Javier Arroyo
ProAndroidDev
Published in
3 min readJul 23, 2018

--

Until now if we wanted to recognize a user’s current activity 🚴 🏃 🚶 🚌, such as walking, driving, or standing still we had to use ActivityRecognitionApi.

But since a time ago this API is deprecated and we have to use ActivityRecognitionClient.

In this post I will try to explain how we recognized the user’s activity before the new API was launched, and the changes you have to accomplish to use the new ActivityRecognitionClient API.

First of all, in both cases we have to add to our AndroidManifest.xml a uses-permission to read the user’s activity:

<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION"/>

Remember the activities we can read about the device status:

  • IN_VEHICLE: The device is in a vehicle, such as a car.
  • ON_BICYCLE: The device is on a bicycle
  • ON_FOOT: The device is on a user who is walking or running.
  • RUNNING: The device is on a user who is running.
  • STILL: The device is still (not moving).
  • TILTING: The device angle relative to gravity changed significantly.
  • UNKNOWN: Unable to detect the current activity.
  • WALKING: The device is on a user who is walking.

1. The deprecated way 🚫 — Google Play Services < 12.0.0

Up to now, if we wanted to get user’s activity, we had to connect to GoogleApiClient and once connected we register for activity recognition updates.

From now this is NOT the correct way to get user’s activity.

ActivityRecognition.ActivityRecognitionApi.requestActivityUpdates(mGoogleApiClient, detectionIntervalMillis, pendingIntent)

The activities are detected by periodically waking up the device and reading short bursts of sensor data. The activity detection update interval can be controlled with the detectionIntervalMillis parameter.

And we specified a PendingIntent callback (typically an IntentService) which was called with an intent when activities are detected. The intent recipient can extract the ActivityRecognitionResult using extractResult(android.content.Intent)and with this data we did whatever we need for our application.

So this is the way we did before, next I will try to explain how to get the user’s activity with the new Activity Recognition Transition API.

2. Activity Recognition Transition API ✅

Activity Recognition Transition API provides an ability for apps to subscribe to activity transitional conditions (enter, exit). For example, if our app wants to know how much a user walks, we can ask — tell me when user starts walking or finish walking.

The activities supported with the Transition API are:

Here you can get the API details.

The interested activity transitions are specified by the ActivityTransitionRequest and when such transition happens a callback intent will be generated by the provided PendingIntent. So if we want to subscribe to know if the user starts walking, we have to do something like this.

First of all we specified the activities that we want to subscribe indicating the type of activity:

.setActivityType(DetectedActivity.WALKING)

And the transition type, it could be:

  • ActivityTransition.ACTIVITY_TRANSITION_ENTER
  • ActivityTransition.ACTIVITY_TRANSITION_EXIT:
.setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_ENTER)

Once this is done we create a PendingIntent associated to a BroadcastReceiver which one will be in charge of receiveing the transitions to which we have subscribed before:

val intent = Intent(mContext,
TransitionRecognitionActivityReceiver::class.java)
mPendingIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0)val task = activityRecognitionClient
.requestActivityTransitionUpdates(request, mPendingIntent)

CAUTION: now with Activity Recognition Transition API we are not able to subscribe to get the activities: TILTING, UNKNOWN.

Bellow you can see all the code to know user’s transitions activity:

When the requested transition event occurs, app will receive a callback intent on our BroadcastReceiver; The ActivityTransitionResult can be extracted from the intent (use the extractResult(Intent) utility method), to get the list of ActivityTransitionEvents. The events are ordered in the chronological order of time.

And when we want to stop tracking transitions we have to do:

ActivityRecognition.getClient(mContext).removeActivityTransitionUpdates(mPendingIntent)
.addOnSuccessListener(OnSuccessListener<Void> {
mPendingIntent.cancel()
})
.addOnFailureListener(OnFailureListener {
e -> Log.e(TAG,
"Transitions could not be unregistered: $e")
})

Here you can see an example of how to use the new Activity Recognition Transition API 💻:

Hope you found this story useful and interesting.

Happy coding! 😃 💻

--

--