---
title: "The Activity Recognition Transition API and the ACTIVITY_RECOGNITION permission"
canonical: "https://aifitnessapi.com/phone-sensors/android-activity-recognition-transition-api"
cluster: "Phone Sensors"
primary_query: "Activity Recognition Transition API"
last_reviewed: "2026-10-03"
description: "Subscribing to walking, running, cycling, driving and still transitions on Android, the two ACTIVITY_RECOGNITION permissions, and silent failures."
publisher: "AIFitnessAPI — independent, not sponsored"
cite_as: "\"The Activity Recognition Transition API and the ACTIVITY_RECOGNITION permission\", AIFitnessAPI, https://aifitnessapi.com/phone-sensors/android-activity-recognition-transition-api"
---

# The Activity Recognition Transition API and the ACTIVITY_RECOGNITION permission

> The Activity Recognition Transition API, part of Google Play services location, notifies your app when the user enters or exits one of five activities: IN_VEHICLE, ON_BICYCLE, RUNNING, STILL or WALKING. You build ActivityTransition objects with ACTIVITY_TRANSITION_ENTER or ACTIVITY_TRANSITION_EXIT, register them with requestActivityTransitionUpdates() and a PendingIntent, and read an ActivityTransitionResult from the Intent you receive. Google's setup page asks for play-services-location 12.0.0 or higher and the com.google.android.gms.permission.ACTIVITY_RECOGNITION permission, while Android 10's privacy changes add the android.permission.ACTIVITY_RECOGNITION runtime permission and say the Activity Recognition API doesn't provide results unless the user has granted it.

- Canonical: https://aifitnessapi.com/phone-sensors/android-activity-recognition-transition-api
- Last reviewed: 2026-10-03
- Publisher: AIFitnessAPI (https://aifitnessapi.com) — independent, not sponsored
- Cite as: "The Activity Recognition Transition API and the ACTIVITY_RECOGNITION permission", AIFitnessAPI, https://aifitnessapi.com/phone-sensors/android-activity-recognition-transition-api

---

A walking app that starts a session when someone starts walking, or a commute tracker that stops when they get in a car, wants transitions rather than a stream. This page uses Google's [transitions guide](https://developer.android.com/develop/sensors-and-location/location/transitions) and [Android 10 privacy changes](https://developer.android.com/about/versions/10/privacy/changes), read 2026-10-03. The `ActivityTransition` and `ActivityRecognitionClient` reference pages live on developers.google.com, which our research environment could not reach, so nothing here depends on them.

## What you can subscribe to

Google lists the supported activities as `DetectedActivity` constants: `IN_VEHICLE`, `ON_BICYCLE`, `RUNNING`, `STILL` and `WALKING`. Each subscription pairs one of them with `ACTIVITY_TRANSITION_ENTER` or `ACTIVITY_TRANSITION_EXIT`. Google's description of the design: "Your app subscribes to a transition in activities of interest and the API notifies your app only when needed."

## Two permissions with the same name

This is the confusing part, and the two Google pages describe it from different ends.

| Permission | Where Google documents it | What it does |
| --- | --- | --- |
| `com.google.android.gms.permission.ACTIVITY_RECOGNITION` | Transitions guide, "Set up your project" | Declared in the manifest as the guide's setup step |
| `android.permission.ACTIVITY_RECOGNITION` | Android 10 privacy changes; `Manifest.permission` (API level 29, dangerous) | Runtime permission "for apps that need to detect the user's step count or classify the user's physical activity" |

The Android 10 page connects them: "Some libraries within Google Play services, such as the Activity Recognition API and the Google Fit API, don't provide results unless the user has granted your app this permission." For older targets there is an auto-grant: if your app targets Android 9 (API level 28) or lower, the system grants the platform permission "as needed" when the manifest includes the Play services permission and does not include the platform one. The transitions guide itself mentions only the Play services permission. On a current target, declare the platform permission and request it at runtime; that is the one the results depend on.

## Register

```kotlin
val transitions = listOf(
    ActivityTransition.Builder()
        .setActivityType(DetectedActivity.WALKING)
        .setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_ENTER)
        .build(),
    ActivityTransition.Builder()
        .setActivityType(DetectedActivity.WALKING)
        .setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_EXIT)
        .build(),
)
val request = ActivityTransitionRequest(transitions)

// Android 12+ requires FLAG_MUTABLE or FLAG_IMMUTABLE to be set explicitly here.
// Google's transitions guide does not say which one this API needs.
val pendingIntent = PendingIntent.getBroadcast(context, 0, Intent(context, TransitionReceiver::class.java), mutabilityFlag)

ActivityRecognition.getClient(context)
    .requestActivityTransitionUpdates(request, pendingIntent)
    .addOnFailureListener { e -> /* most often: runtime permission not granted */ }
```

On the mutability flag: the `PendingIntent` reference says that from Android 12 "it will be required to explicitly specify the mutability of PendingIntents on creation with either FLAG_IMMUTABLE or FLAG_MUTABLE", recommends `FLAG_IMMUTABLE`, and reserves `FLAG_MUTABLE` for cases where "some functionality relies on modifying the underlying intent". The transitions guide is silent on which applies. Our judgement: results arrive by being extracted from the Intent you supplied, so test a delivered transition with whichever flag you choose before shipping.

## Receive

```kotlin
class TransitionReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        if (ActivityTransitionResult.hasResult(intent)) {
            val result = ActivityTransitionResult.extractResult(intent) ?: return
            for (event in result.transitionEvents) {
                // chronological, per Google's guide
            }
        }
    }
}
```

Google says the events "are ordered in chronological order" and gives the example that subscribing to enter and exit for `IN_VEHICLE` yields one event "when the user starts driving, and another one when the user transitions to any other activity." On timing, the whole of Google's statement is: "The latency of event detection might vary by device."

## Deregister

`removeActivityTransitionUpdates(pendingIntent)` stops delivery; Google's sample cancels the `PendingIntent` in the success listener.

## Pitfalls

- **Declaring only the Play services permission on a modern target.** The Android 10 page says results are withheld until the user grants `android.permission.ACTIVITY_RECOGNITION`.
- **Expecting a fixed latency.** Google publishes none and says it varies by device.
- **Leaving the PendingIntent mutability to chance.** It is mandatory from Android 12, and the guide does not choose for you.
- **Ending a session the instant STILL arrives.** A walker at a crossing is still. Debounce exits before ending a session; this is judgement, not Google guidance.
- **Expecting confidence values.** The transitions guide describes enter and exit events only. iOS exposes a confidence on each update; see [CMMotionActivityManager](/phone-sensors/cmmotionactivitymanager).

For counting steps rather than classifying activity, see the [step counter sensor](/phone-sensors/android-step-counter-sensor). For running a session in the background once a transition starts it, see [foregroundServiceType="health"](/phone-sensors/foreground-service-type-health).

## FAQ

### Which activities can the Activity Recognition Transition API detect?

Five, according to Google's transitions guide: IN_VEHICLE, ON_BICYCLE, RUNNING, STILL and WALKING, all expressed as DetectedActivity constants. For each you can subscribe to ACTIVITY_TRANSITION_ENTER, ACTIVITY_TRANSITION_EXIT or both. The guide does not list other activity types as supported for transitions, so a subscription to anything else should be treated as unsupported unless Google's reference documentation says otherwise.

[Permalink](https://aifitnessapi.com/phone-sensors/android-activity-recognition-transition-api#faq-1)

### Do I need both ACTIVITY_RECOGNITION permissions for the Transition API?

On a current target, the one that matters is android.permission.ACTIVITY_RECOGNITION, granted at runtime. Google's Android 10 privacy page says the Activity Recognition API doesn't provide results unless the user has granted that permission. The transitions guide's setup step names com.google.android.gms.permission.ACTIVITY_RECOGNITION; Android 10's page explains that apps targeting Android 9 or lower that declare only that Play services permission are auto-granted the platform permission as needed.

[Permalink](https://aifitnessapi.com/phone-sensors/android-activity-recognition-transition-api#faq-2)

### Why does requestActivityTransitionUpdates succeed but no transitions ever arrive?

The documented cause to check first is the runtime permission: Google's Android 10 privacy page says Play services activity recognition doesn't provide results unless the user has granted android.permission.ACTIVITY_RECOGNITION. Next, the PendingIntent: from Android 12 its mutability must be set explicitly, and the transitions guide doesn't say which flag the API needs, so test delivery with your choice. Finally, Google says only that detection latency might vary by device, so wait for a real transition before concluding it is broken.

[Permalink](https://aifitnessapi.com/phone-sensors/android-activity-recognition-transition-api#faq-3)

### How do I stop activity transition updates on Android?

Call removeActivityTransitionUpdates() on the ActivityRecognitionClient, passing the same PendingIntent you registered with. Google's transitions guide shows the call returning a Task and cancels the PendingIntent in the success listener, logging the error in the failure listener. Stopping updates when a feature is switched off also keeps your app's behaviour aligned with what the user agreed to when they granted the permission.

[Permalink](https://aifitnessapi.com/phone-sensors/android-activity-recognition-transition-api#faq-4)
