# RnSensorStepListener.kt

package com.sensor.step

import android.hardware.Sensor
import android.hardware.SensorEvent
import android.hardware.SensorEventListener
import android.hardware.SensorManager
import android.util.Log
import com.facebook.react.bridge.Arguments
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactContext
import com.facebook.react.bridge.WritableMap
import com.facebook.react.modules.core.DeviceEventManagerModule

class RnSensorStepListener(private val reactContext: ReactApplicationContext) : SensorEventListener {

    private var sensorManager: SensorManager = reactContext.getSystemService(ReactApplicationContext.SENSOR_SERVICE) as SensorManager
    private var stepCounterSensor: Sensor? = null
    private var sensorType: Int = Sensor.TYPE_STEP_COUNTER
    private var lastUpdate: Long = 0
    private var delay: Int = 0

    enum class SensorType(val type: String) {
        COUNTER("COUNTER"),
        DETECTOR("DETECTOR");

        companion object {
            fun fromString(value: String): SensorType? = values().find { it.type == value }
        }
    }

    fun start(delay: Int, sensorType: SensorType) {
        this.delay = delay
        this.sensorType = if (sensorType == SensorType.COUNTER) Sensor.TYPE_STEP_COUNTER else Sensor.TYPE_STEP_DETECTOR
        stepCounterSensor = sensorManager.getDefaultSensor(this.sensorType)
        stepCounterSensor?.let {
            sensorManager.registerListener(this, it, SensorManager.SENSOR_DELAY_FASTEST)
        }
    }

    fun stop() {
        sensorManager.unregisterListener(this)
    }

    private fun sendEvent(eventName: String, params: WritableMap?) {
        try {
            reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
                .emit(eventName, params)
        } catch (e: RuntimeException) {
            Log.e("ERROR", "Trying to invoke JS before CatalystInstance has been set!", e)
        }
    }

    override fun onSensorChanged(event: SensorEvent?) {
        event?.let {
            if (it.sensor.type == sensorType) {
                val curTime = System.currentTimeMillis()
                if (curTime - lastUpdate > delay) {
                    val map: WritableMap = Arguments.createMap()
                    map.putDouble("steps", it.values[0].toDouble())
                    sendEvent("StepCounter", map)
                    lastUpdate = curTime
                }
            }
        }
    }

    override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {
        // Not used
    }
}
# RnSensorStepModule.kt

package com.sensor.step

import android.Manifest
import android.app.Activity
import android.content.pm.PackageManager
import android.os.Build
import androidx.annotation.RequiresApi
import com.facebook.react.bridge.Promise
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactContextBaseJavaModule
import com.facebook.react.bridge.ReactMethod
import com.sensor.step.RnSensorStepListener.SensorType

class RnSensorStepModule(private val reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {

    private var sensorStepListener: RnSensorStepListener? = null

    @RequiresApi(Build.VERSION_CODES.M)
    @ReactMethod
    fun requestSensorPermission() {
        val activity: Activity? = currentActivity
        val permissions = arrayOf(Manifest.permission.ACTIVITY_RECOGNITION)
        activity?.requestPermissions(permissions, 0)
    }

    @RequiresApi(Build.VERSION_CODES.M)
    @ReactMethod
    fun checkSensorPermission(promise: Promise) {
        val permissionGranted = reactContext.checkSelfPermission(Manifest.permission.ACTIVITY_RECOGNITION) == PackageManager.PERMISSION_GRANTED
        promise.resolve(permissionGranted)
    }

    @ReactMethod
    fun start(delay: Int, sensorType: String) {
        if (sensorStepListener == null) {
            sensorStepListener = RnSensorStepListener(reactContext)
        }
        val type = SensorType.fromString(sensorType) ?: SensorType.COUNTER
        sensorStepListener?.start(delay, type)
    }

    @ReactMethod
    fun stop() {
        sensorStepListener?.stop()
    }

     @ReactMethod
    fun addListener(eventName: String) {
        // NativeEventEmitter와의 호환을 위한 더미 메서드
    }

    @ReactMethod
    fun removeListeners(count: Int) {
        // NativeEventEmitter와의 호환을 위한 더미 메서드
    }

    override fun getName(): String {
        return "RnSensorStep"
    }
}
# RnSensorStepPackage.kt

package com.sensor.step

import com.facebook.react.ReactPackage
import com.facebook.react.bridge.NativeModule
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.uimanager.ViewManager

class RnSensorStepPackage : ReactPackage {
    override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
        return listOf(RnSensorStepModule(reactContext))
    }

    override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
        return emptyList()
    }
}