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:
Activity
s and Fragment
s 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)