Sensor.TYPE_STEP_COUNTER vs TYPE_STEP_DETECTOR on Android
Last verified October 3, 2026 · 4 min read
Covered here:Health Connect
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, the motion sensors guide and the SensorManager reference, read 2026-10-03. Which step source a product should use across platforms is answered on the step counting API page.
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."
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_RECOGNITIONgranted, 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; with it, the Health Connect integration guide.
The iPhone counterpart, which does keep seven days of history, is CMPedometer.
Frequently asked questions
- 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.
- 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.
- 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.
- 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.
Keep reading
Elsewhere on the site
Pages that share this one’s concepts and sources, from other sections.
Next steps
Was this page useful?
Independent comparison, last reviewed October 3, 2026. Pricing, rate limits, and feature availability change often — confirm current details in each provider’s official documentation before you commit. Product and company names are trademarks of their respective owners; AIFitnessAPI is not affiliated with, endorsed by, or sponsored by any product listed here.
← All phone sensors · by AIFitnessAPI