Darotudeen
Darotudeen

Reputation: 2518

How to get step count with GoogleFit Api Sensor Manager

I am trying to geth step count and heart rpm from the Google Fit Api. I am aware that the getHistoryClient and getSensorClient are deprecated.

Please how can I replace this methods with the Sensor Manager. I do not seem to undersatnd the documentation.

class MainActivity : AppCompatActivity(), SensorEventListener {
    private val listOfPermissionNotGranted = mutableListOf<String>()
    lateinit var permissionsLauncher: ActivityResultLauncher<Array<String>>
    lateinit var signInLauncher: ActivityResultLauncher<Intent>
    private val sensorManager: SensorManager by lazy { getSystemService(SENSOR_SERVICE) as SensorManager }
    private val accelerometer by lazy { sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) }
    lateinit var googleApiClient: GoogleSignInClient

    @RequiresApi(Build.VERSION_CODES.Q)
    @OptIn(ExperimentalTime::class)
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)


        signInLauncher = registerForActivityResult(StartActivityForResult()) { result ->
            if (result.resultCode == RESULT_OK) {
                val task = GoogleSignIn.getSignedInAccountFromIntent(result.data)
                if (task.isSuccessful) {
                    Toast.makeText(this, "Signed in", Toast.LENGTH_LONG).show()
                    Log.d("MainUser", "${task.result}")
                    val fitnessOptions = FitnessOptions.builder()
                        .addDataType(DataType.TYPE_STEP_COUNT_DELTA, FitnessOptions.ACCESS_READ)
                        .addDataType(
                            DataType.AGGREGATE_STEP_COUNT_DELTA,
                            FitnessOptions.ACCESS_READ
                        )
                        .build()
                    Fitness.getHistoryClient(this, GoogleSignIn.getAccountForExtension(this, fitnessOptions))
                        .readDailyTotal(DataType.TYPE_STEP_COUNT_DELTA)
                        .addOnSuccessListener { result ->
                            val totalSteps =
                                result.dataPoints.firstOrNull()?.getValue(Field.FIELD_STEPS)?.asInt() ?: 0
                            // Do something with totalSteps
                            Log.i("Main", "total $totalSteps")
                        }
                        .addOnFailureListener { e ->
                            Log.i("Main", "There was a problem getting steps.", e)
                        }
//                    val googleSignInAccount =
//                        GoogleSignIn.getAccountForExtension(this, fitnessOptions)
                }
            }
        }
        permissionsLauncher = registerForActivityResult(RequestMultiplePermissions()) { permissionMap ->
            val permitted = permissionMap.all { it.value }
            if (permitted) {
                val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                    .requestScopes(Fitness.SCOPE_ACTIVITY_READ)
                    .build()

                googleApiClient = GoogleSignIn.getClient(this, gso)
                val signInIntent = googleApiClient.signInIntent
                signInLauncher.launch(signInIntent)
            }

        }


        permissionsLauncher.launch(
            arrayOf(
                Manifest.permission.BODY_SENSORS,
                Manifest.permission.ACCESS_FINE_LOCATION,
                Manifest.permission.ACTIVITY_RECOGNITION
            )
        )
        listOfPermissionNotGranted.forEach { permission ->
            Toast.makeText(this, "$permission is not granted", Toast.LENGTH_LONG).show()
        }


    }

    override fun onResume() {
        super.onResume()
        sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL)
    }

    override fun onPause() {
        super.onPause()
        sensorManager.unregisterListener(this)
    }

    override fun onSensorChanged(event: SensorEvent?) {
        if (event?.sensor?.type == Sensor.TYPE_STEP_DETECTOR) {
            Log.d("MainSensorStep detected", "${event.values[0]}")
            Toast.makeText(this, "Step is detected ${event.values[0]}", Toast.LENGTH_LONG).show()
        } else if (event?.sensor?.type == Sensor.TYPE_STEP_COUNTER) {
            Log.d("MainSensorStep counting", "${event.values[0]}")
            Toast.makeText(this, "Step is counting ${event.values[0]}", Toast.LENGTH_LONG).show()
        }

    }

    override fun onAccuracyChanged(sensor: Sensor?, p1: Int) {
        Log.d("MainSensor", "$sensor")
    }
}

Upvotes: 0

Views: 431

Answers (1)

BearDroid
BearDroid

Reputation: 583

You might want to go over this answer in a separate, but related SO post, and get a better understanding of the different approaches.

If you need to collate processed steps information from the User, then Google Fit is the better approach. You can see how you get the same step count as what's on the google fit app using the cited example code in their official docs: https://developers.google.com/fit/scenarios/read-daily-step-total#android

I see that you're also using the Android API for Fit, you might want to explore Android Health Connect too as the Android API for Fit will be deprecated soon.

Upvotes: 0

Related Questions