---
title: "Sensor.TYPE_STEP_COUNTER vs TYPE_STEP_DETECTOR on Android"
canonical: "https://aifitnessapi.com/phone-sensors/android-step-counter-sensor"
cluster: "Phone Sensors"
primary_query: "Sensor.TYPE_STEP_COUNTER"
last_reviewed: "2026-10-03"
description: "Android's step counter returns steps since the last reboot with up to 10 s latency; the step detector fires once per step. Permissions, batching, pitfalls."
publisher: "AIFitnessAPI — independent, not sponsored"
cite_as: "\"Sensor.TYPE_STEP_COUNTER vs TYPE_STEP_DETECTOR on Android\", AIFitnessAPI, https://aifitnessapi.com/phone-sensors/android-step-counter-sensor"
---

# Sensor.TYPE_STEP_COUNTER vs TYPE_STEP_DETECTOR on Android

> Sensor.TYPE_STEP_COUNTER returns the number of steps taken since the last reboot while the sensor was activated, as a float that resets to zero only on a reboot, and Android defines it as an on-change sensor with up to 10 seconds of latency but more accuracy than the detector. Sensor.TYPE_STEP_DETECTOR instead fires one event with the value 1.0 for every step, as a special-trigger sensor with latency expected below 2 seconds. Both arrived in API level 19, and both require the ACTIVITY_RECOGNITION runtime permission on Android 10 (API level 29) and higher. Google also warns that the counter does not count steps unless some app keeps it registered, so unregistering stops the count.

- Canonical: https://aifitnessapi.com/phone-sensors/android-step-counter-sensor
- Last reviewed: 2026-10-03
- Publisher: AIFitnessAPI (https://aifitnessapi.com) — independent, not sponsored
- Cite as: "Sensor.TYPE_STEP_COUNTER vs TYPE_STEP_DETECTOR on Android", AIFitnessAPI, https://aifitnessapi.com/phone-sensors/android-step-counter-sensor

---

These two constants are the lowest-level way an Android phone gives you steps: no Google Play services, no Health Connect, no account. Everything here is from Google's [Sensor reference](https://developer.android.com/reference/android/hardware/Sensor), the [motion sensors guide](https://developer.android.com/develop/sensors-and-location/sensors/sensors_motion) and the [SensorManager reference](https://developer.android.com/reference/android/hardware/SensorManager), read 2026-10-03. Which step source a product should use across platforms is answered on [the step counting API page](/data/step-counting-api).

## Side by side

| | `TYPE_STEP_COUNTER` | `TYPE_STEP_DETECTOR` |
| --- | --- | --- |
| Constant value | 19 | 18 |
| Added | API level 19 | API level 19 |
| What `values[0]` holds | Steps since the last reboot while activated | Always 1.0, one event per step |
| Reporting mode | `REPORTING_MODE_ON_CHANGE` | `REPORTING_MODE_SPECIAL_TRIGGER` |
| Latency (motion guide) | "up to 10 seconds" | "expected to be below 2 seconds" |
| Event timestamp | When the last step for that event was taken | When the foot hit the ground |
| Permission | `android.permission.ACTIVITY_RECOGNITION` | `android.permission.ACTIVITY_RECOGNITION` |

Google's own split: the detector "is only for detecting every individual step as soon as it is taken, for example to perform dead reckoning. If you only need aggregate number of steps taken over a period of time, register for TYPE_STEP_COUNTER instead." The counter "is ideal for fitness tracking applications."

## The counter is a since-boot odometer

The reference text is precise: the counter "returns the number of steps taken by the user since the last reboot while activated. The value is returned as a float (with the fractional part set to zero) and is reset to zero only on a system reboot." Your first reading after install might be a five- or six-digit number. It is not today's steps. It is an odometer, and your app computes deltas.

The baseline logic is ours, not Google's: store the first value you see with its timestamp, subtract it from later values, and treat a reading lower than your stored baseline as a reboot, after which the new value is the steps since boot.

## It only counts while registered

The paragraph people skip: "If you want to continuously track the number of steps over a long period of time, do NOT unregister for this sensor, so that it keeps counting steps in the background even when the AP is in suspend mode and report the aggregate count when the AP is awake. Application needs to stay registered for this sensor because step counter does not count steps if it is not activated."

Unregistering in `onPause()` is therefore a product decision, not a battery optimisation. The steps walked while nothing was registered are not recorded anywhere you can read.

## Batching

Both sensors may be backed by hardware FIFOs. `registerListener(listener, sensor, samplingPeriodUs, maxReportLatencyUs)` "allows events to stay temporarily in the hardware FIFO (queue) before being delivered", and Google says a positive latency reduces the interrupts the application processor receives, "hence reducing power consumption". `getFifoMaxEventCount()` tells you whether a sensor batches at all: "If this value is zero it indicates that batch mode is not supported for this sensor." For the counter, the motion guide adds a battery recommendation: "you should use the JobScheduler class to retrieve the current value from the step counter sensor at a specific interval", keeping that interval "as long as possible unless your app requires real-time data".

For the detector, rate hints may be ignored: special-trigger events "are reported as described in the description of the sensor. The rate passed to registerListener might not have an impact on the rate of event delivery."

```kotlin
class StepCounterReader(context: Context) : SensorEventListener {
    private val sensorManager = context.getSystemService(Context.SENSOR_SERVICE) as SensorManager
    private val counter: Sensor? = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER)

    /** Call only after ACTIVITY_RECOGNITION is granted (Android 10+). */
    fun start(): Boolean {
        val sensor = counter ?: return false            // no step counter on this device
        return sensorManager.registerListener(
            this, sensor,
            SensorManager.SENSOR_DELAY_NORMAL,
            60_000_000                                   // maxReportLatencyUs: allow 60 s of batching
        )
    }

    override fun onSensorChanged(event: SensorEvent) {
        val sinceBoot = event.values[0].toLong()         // since last reboot, not "today"
        // persist (sinceBoot, event.timestamp) and diff against your stored baseline
    }

    override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) = Unit
}
```

## Hardware or software

Google's motion guide says the step counter and step detector "are either hardware-based or software-based", and adds that "The availability of the software-based sensors is more variable because they often rely on one or more hardware sensors to derive their data." `getDefaultSensor()` can return `null`; the sketch handles that by returning `false`.

## Pitfalls

- **Showing the raw value as today's steps.** It counts from the last reboot.
- **Unregistering to save battery.** The counter stops counting. Use batching or periodic reads instead.
- **Forgetting the runtime permission.** On Android 10 and higher both sensors need `ACTIVITY_RECOGNITION` granted, and Android 10's privacy notes say these two are "The only built-in sensors on the device that require you to declare this permission".
- **Using the detector for totals.** Missed events are missed steps. Google points totals at the counter.
- **Expecting the rate parameter to pace the detector.** Special-trigger sensors report when a step happens.
- **Assuming history.** A sensor has no past. For stored, multi-day step data without Health Connect, see the [Recording API on mobile](/phone-sensors/android-recording-api); with it, the [Health Connect integration guide](/integrate/google-health-connect).

The iPhone counterpart, which does keep seven days of history, is [CMPedometer](/phone-sensors/cmpedometer).

## FAQ

### Why does TYPE_STEP_COUNTER return a huge number on the first reading?

Because it counts from the last reboot, not from when your app started. Google's Sensor reference says the step counter returns the number of steps taken since the last reboot while activated, and is reset to zero only on a system reboot. A phone that has been on for weeks can report tens of thousands on your first event. Store that first value as a baseline and display the difference, treating any lower reading as a sign the device rebooted.

[Permalink](https://aifitnessapi.com/phone-sensors/android-step-counter-sensor#faq-1)

### Does TYPE_STEP_COUNTER keep counting after my app unregisters the listener?

Not on the strength of your registration. Google's reference says an application needs to stay registered for this sensor because the step counter does not count steps if it is not activated, and tells apps that want long-term tracking not to unregister. Another app holding a registration may keep it running, but you cannot rely on that. If battery is the concern, register with a reporting latency so the hardware batches events, rather than unregistering.

[Permalink](https://aifitnessapi.com/phone-sensors/android-step-counter-sensor#faq-2)

### Which Android permission does the step counter sensor need?

android.permission.ACTIVITY_RECOGNITION, a dangerous permission added in API level 29. Google's motion sensors guide says you must declare it to use the step counter or step detector on devices running Android 10 (API level 29) or higher, and the Sensor reference states that both sensor types require it. Because it is a runtime permission, declaring it in the manifest is not enough: request it from the user before registering the listener.

[Permalink](https://aifitnessapi.com/phone-sensors/android-step-counter-sensor#faq-3)

### How long can the Android step counter take to report a step?

Up to 10 seconds, according to Google's motion sensors guide, which says the step counter has more latency (up to 10 seconds) but more accuracy than the step detector. The step detector's latency is expected to be below 2 seconds, but it reports single steps rather than a running total. If you also register with a positive maxReportLatencyUs, events can wait in the hardware FIFO for up to that long before delivery, by design.

[Permalink](https://aifitnessapi.com/phone-sensors/android-step-counter-sensor#faq-4)
