Home > database >  sensorManager becomes disabled when app is off even though I don't unregister it
sensorManager becomes disabled when app is off even though I don't unregister it

Time:01-03

I use kotlin.

I listen sensorManager and it works well onCreate.

I need to detect step even when app is off.

So I delete unregister line from onDestroy cycle.

 sensorManager.unregisterListener(this)

However on my phone device emulator, if I turn off this app, step count is not detected.

what is the problem? and How can I make this work when app is off?

class MyDiaryFragment : Fragment(), SensorEventListener {

    private var _binding: FragmentMyDiaryBinding? = null
    private val binding get() = _binding!!

    private val db = Firebase.firestore
    private val userDB = Firebase.firestore.collection("users")
    private val diaryDB = Firebase.firestore.collection("diary")
    private val userId = Firebase.auth.currentUser?.uid

    private lateinit var sensorManager: SensorManager
    private lateinit var step_sensor: Sensor

    lateinit var broadcastReceiver: BroadCastReceiver

    private var currentMonth: String = ""

    companion object {
        var todayTotalStepCount: Int? = 0
    }


    @SuppressLint("ClickableViewAccessibility")
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        _binding = FragmentMyDiaryBinding.inflate(inflater, container, false)
        val view = binding.root

        // 걸음수 권한
        if (ContextCompat.checkSelfPermission(
                requireActivity(),
                Manifest.permission.ACTIVITY_RECOGNITION,
            ) == PackageManager.PERMISSION_DENIED
        ) {
            //ask for permission
            ActivityCompat.requestPermissions(
                requireActivity(),
                arrayOf(Manifest.permission.ACTIVITY_RECOGNITION),
                100
            )
        }

        // 걸음수 셋업
        broadcastReceiver = BroadCastReceiver()
        val filter = IntentFilter()
        filter.addAction(Intent.ACTION_DATE_CHANGED)
        context?.registerReceiver(broadcastReceiver, filter)

        sensorManager = context?.getSystemService(Context.SENSOR_SERVICE) as SensorManager
        step_sensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_DETECTOR)

        if (step_sensor != null) {
            sensorManager.registerListener(this, step_sensor, SensorManager.SENSOR_DELAY_UI)
        } else {
        }

    override fun onSensorChanged(stepEvent: SensorEvent?) {
        Log.d("결과아", "sensorEvent ${stepEvent!!.values[0].toInt()}")

        var currentDate = LocalDate.now()

        todayTotalStepCount = todayTotalStepCount?.plus(stepEvent!!.values[0].toInt())
        binding.todayStepCount.text = todayTotalStepCount.toString()

        // user 내 todayStepCount
        var todayStepCountSet = hashMapOf(
            "todayStepCount" to todayTotalStepCount
        )

        userDB.document("$userId").set(todayStepCountSet, SetOptions.merge())

        var userStepCountSet = hashMapOf(
            "$currentDate" to todayTotalStepCount
        )

        var periodStepCountSet = hashMapOf(
            "$userId" to todayTotalStepCount
        )

        // user_step_count
        db.collection("user_step_count")
            .document("$userId")
            .set(userStepCountSet, SetOptions.merge())

        // period_step_count
        db.collection("period_step_count")
            .document("$currentDate")
            .set(periodStepCountSet, SetOptions.merge())

    }

    override fun onAccuracyChanged(p0: Sensor?, p1: Int) {
        Log.d("걸음수", "아직")
    }
}

CodePudding user response:

Activitys and Fragments are GUI parts. if you want your step counter to work even when app "is off", in the meaning: isn't on foreground, not visible, then you have to use some background Service, preferably ForegroundService. Keep your sensor logic in there and prepare some communication between GUI-side (e.g. Fragment) and background-side like binding or some data bus - when app is on screen then it talk with background service and presents data. When GUI isn't needed and app is "homed" or just device locked then GUI don't need to work and ask for current status, but background logic still works and is storing data for future presentation when user get back to app (GUI)

  • Related