1

The intent of the code I created is that whenever the data from the Pedometer changes, the data is passed in real-time via the onSensorChanged() function.

However, even though data is being collected through the foreground during the off-screen period, onSensorChanaged does not work at all until it is on-screen.

However, for the on body sensor utilizing the same function, data is being collected properly every time it is worn and unworn regardless of off-screen / on-screen.

I realize that Pedometer doesn't have a function like flush(), but is there any way to initiating onSensorChanged work off-screen?

OnSensorChanged() is not triggering for the Step detect sensor

My symptoms match the link above, but none of the answers to that problem helped me get the pedometer values in real time.


import android.content.Context
import android.hardware.Sensor
import android.hardware.SensorEvent
import android.hardware.SensorEventListener
import android.hardware.SensorManager
import android.util.Log
import com.health.multisensors.util.JsonFileWriter
import org.json.JSONObject
class PedometerModule(private val context: Context) : SensorEventListener {
 private val TAG = "PedometerModule"
 private var sensorManager: SensorManager? = null
 private var stepCounter: Sensor? = null
 private var stepDetector: Sensor? = null
 private var initialSteps: Float? = null
 fun startTracking() {
 Log.i(TAG, "Starting Pedometer tracking...")
 sensorManager = context.getSystemService(Context.SENSOR_SERVICE) as SensorManager
 stepCounter = sensorManager?.getDefaultSensor(Sensor.TYPE_STEP_COUNTER)
 stepDetector = sensorManager?.getDefaultSensor(Sensor.TYPE_STEP_DETECTOR)
 if (stepCounter == null) {
 Log.w(TAG, "Step Counter sensor not available.")
 } else {
 sensorManager?.registerListener(this, stepCounter, SensorManager.SENSOR_DELAY_NORMAL)
 }
 if (stepDetector == null) {
 Log.w(TAG, "Step Detector sensor not available.")
 } else {
 sensorManager?.registerListener(this, stepDetector, SensorManager.SENSOR_DELAY_FASTEST)
 }
 }
 fun stopTracking() {
 sensorManager?.unregisterListener(this)
 Log.i(TAG, "Stopped Pedometer tracking.")
 }
 **override fun onSensorChanged(event: SensorEvent?) {
 if (event == null) return
 val timestamp = System.currentTimeMillis()
 when (event.sensor.type) {
 Sensor.TYPE_STEP_COUNTER -> {
 val steps = event.values[0]
 if (initialSteps == null) initialSteps = steps
 val stepCount = steps - (initialSteps ?: 0f)
 Log.d(TAG, "StepCounter: $stepCount at $timestamp")
 val json = JSONObject().apply {
 put("sensor", "pedometer")
 put("timestamp", timestamp)
 put("total_steps", steps.toInt())
 put("relative_steps", stepCount.toInt())
 }
 JsonFileWriter.writeJson(context, json)
 }
 Sensor.TYPE_STEP_DETECTOR -> {
 Log.d(TAG, "StepDetector: step detected at $timestamp")
 val json = JSONObject().apply {
 put("sensor", "step_detector")
 put("timestamp", timestamp)
 put("step", 1)
 }
 JsonFileWriter.writeJson(context, json)
 }
 }
 }**
 override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {
 // Not used
 }
}

The manifest includes the foreground and several permission settings as shown below, and the uses-feature also includes stepcount and stepdetector.

 <uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION" />
 <uses-permission android:name="android.permission.BODY_SENSORS_BACKGROUND" />
 <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
 <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
 <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
 <uses-permission android:name="android.permission.BODY_SENSORS" />
 <uses-permission android:name="android.permission.WAKE_LOCK" />
 <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
 <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
 <uses-permission android:name="android.permission.FOREGROUND_SERVICE_HEALTH" />
 <uses-permission android:name="android.permission.BIND_HEALTH_SERVICE" />
 <uses-permission android:name="android.permission.BIND_HEALTH_TRACKING_SERVICE" />```
I've also tried periodically turning the sensor itself off and on, but none of this has been able to fetch stepcount in real-time.
asked May 26, 2025 at 4:48
2
  • Have you tried with the platform Activity Recognition permission instead of the gms permission? developer.android.com/develop/sensors-and-location/sensors/… "android.permission.ACTIVITY_RECOGNITION" Commented May 27, 2025 at 15:41
  • you can use google health passivelistener to get some stepcounter updates even with screen off. but it will only send you data from time to time. if you are interested in a certain goal (like reaching 10000 steps) you can even set passive goals there. but i'm not sure if this is really fast then or if it notifies you 20 minutes after you reached that goal. Commented Nov 5, 2025 at 9:28

0

Know someone who can answer? Share a link to this question via email, Twitter, or Facebook.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.