Activity Recognition API Tutorial for Android: Getting Started
Learn to track your activities in your Android app by creating a fitness app that uses the Activity Recognition API. By Andrej Vukelic.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Activity Recognition API Tutorial for Android: Getting Started
20 mins
Tracking Activities in the Background
Apps that track your activity should work in the background so you can still use other apps on your mobile device. In this section, you’ll learn how to use the Sampling API and run it in the background service.
Remember how you requested transition updates from the ActivityRecognitionClient
? Requesting activity sampling updates is almost the same process.
Find DetectedActivityService.kt
. Then replace TODO 15
with:
val task = ActivityRecognitionClient(this).requestActivityUpdates(ACTIVITY_UPDATES_INTERVAL,
DetectedActivityReceiver.getPendingIntent(this))
task.run {
addOnSuccessListener {
Log.d("ActivityUpdate", getString(R.string.activity_update_request_success))
}
addOnFailureListener {
Log.d("ActivityUpdate", getString(R.string.activity_update_request_failed))
}
}
In the above code, you can see the process is pretty much the same as requesting transition updates. You create a task and apply success and failure listeners to that task. The difference is that now you call requestActivityUpdates
which takes detectionInterval
and the activity’s pending intent as parameters and updates the receiver’s PendingIntent
.
Now, ActivityRecognitionClient
will send periodic updates to your app.
Next, add code to stop the updates in case a user closes the app. Find TODO 16
and replace it with:
val task = ActivityRecognitionClient(this).removeActivityUpdates(
DetectedActivityReceiver.getPendingIntent(this))
task.run {
addOnSuccessListener {
Log.d("ActivityUpdate", getString(R.string.activity_update_remove_success))
}
addOnFailureListener {
Log.d("ActivityUpdate", getString(R.string.activity_update_remove_failed))
}
}
This code removes all activity updates specified for PendingIntent
. It also helps you control battery consumption.
Now, you’ll register the service and broadcast receiver in AndroidManifes.xml
.
Open AndroidManifes.xml
. Find TODO 17
and replace it with:
<service android:name=".detectedactivity.DetectedActivityService" />
<receiver android:name=".detectedactivity.DetectedActivityReceiver"/>
This code lets your service and receiver work in the background.
Now, switch to DetectedActivityReceiver.kt
. Here, you’ll handle messages received from the ActivityRecognitionClient
.
First, find TODO 18
and uncomment handleDetectedActivities
and showNotification
. Next, add the imports:
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import com.google.android.gms.location.DetectedActivity
import com.raywenderlich.android.petbuddy.MainActivity
import com.raywenderlich.android.petbuddy.R
import com.raywenderlich.android.petbuddy.SUPPORTED_ACTIVITY_KEY
import com.raywenderlich.android.petbuddy.SupportedActivity
Now, you’ll handle the Intent
received from the ActivityRecognitionClient
with the same steps you used for transition updates. Find TODO 19
, and replace it with:
// 1
if (ActivityRecognitionResult.hasResult(intent)) {
// 2
val result = ActivityRecognitionResult.extractResult(intent)
// 3
result?.let { handleDetectedActivities(it.probableActivities, context) }
}
Here, the logic:
- Checks if the received intent contains a wanted result.
- Then, extracts
ActivityRecognitionResult
from the intent. - If the result is not null, it handles probable activities.
probableActivites
is a sorted list of activities based on confidence grades. Since your pet likes to walk and run, you don’t want to track any other activities. Okay, you’ll take standing still into consideration, too.
In DetectedActivityReceiver.kt
, find TODO 20
. Replace it with:
detectedActivities
.filter {
it.type == DetectedActivity.STILL ||
it.type == DetectedActivity.WALKING ||
it.type == DetectedActivity.RUNNING
}
.filter { it.confidence > RELIABLE_CONFIDENCE }
.run {
if (isNotEmpty()) {
showNotification(this[0], context)
}
}
First, you filter activities you’re interested in. Then, you filter activities with a confidence grade over 75% because you’re only interested in the most probable activity.
Voila! The notification is here.
When you requested permission, you logged a message on permission granted. In the MainActivity.kt
, find TODO 21
. In the else
branch above it, add:
startService(Intent(this, DetectedActivityService::class.java))
requestActivityTransitionUpdates()
When a user taps Start on a fresh install of the app, the permission dialog shows. When a user allows the permission, it’ll start tracking activity.
Great job! You’re ready to use the Sampling API.
Build and run. Go outside, start tracking and pay attention to the status bar. You’ll see a notification like this:
Congratulations! You created your first activity tracker app. Take your dog for a walk and enjoy nature.
Where to Go From Here?
In this tutorial, you learned why and how to use the Activity Recognition API. You used the Activity Recognition Client to detect the start and end of an activity and how to keep track of activity transitions. You also learned about confidence grades and tracking activities in the background.
You can download the complete project by clicking Download Materials at the top or bottom of this tutorial.
If you want to know more about this topic, check out the official documentation for building apps with Android Recognition Client.
There’s one API left in the Android Recognition Client. Take a look at the official documentation for Sleep API.