Slides of the talk I gave at Droidcon Italy together with Daniele Bonaldo
WELLNESS& DROIDPhoto by Jeremy Thomas on Unsplash
View Slide
Daniele Bonaldo@danybony_Roberto Orgiu@_tiwiz
SLEEPEXERCISE RECORD
ACTIVITYRECOGNITION APIEXERCISE
Let’s getstarted•Track user•Compute distance•Steps measurement
Getting last user’slocation//Manifest.permission.ACCESS_FINE_LOCATIONprivate val client =LocationServices.getFusedLocationProviderClient(activity)client.lastLocation.addOnSuccessListener {location-> . ..}
Getting updateson user’s locationprivate val locationCallback =object : LocationCallback() {override fun onLocationResult(r: LocationResult) {//calculate here}}
Getting updateson user’s locationval locationRequest = LocationRequest.create().apply {priority = PRIORITY_HIGH_ACCURACYinterval = 5000}
Getting updateson user’s locationclient.requestLocationUpdates(locationRequest,locationCallback,Looper.getMainLooper())
ComputedistancesSphericalUtil.computeDistanceBetween(lastLatLng,oldLatLng)
class StepCounter(private val activity: AppCompatActivity) : SensorEventListenerEvery step counts
Every step countsprivate val sensorManager : SensorManager =activity.getSystemService(SENSOR_SERVICE)private val stepCounterSensor =sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER)private var initialSteps = -1
Every step countsfun setupStepCounter() {if (stepCounterSensor!=null) {sensorManager.registerListener(this,stepCounterSensor, SENSOR_DELAY_FASTEST)}}fun unloadStepCounter() {if (stepCounterSensor!=null) {sensorManager.unregisterListener(this)}}
Every step countsoverride fun onSensorChanged(event: SensorEvent) {event.values.firstOrNull()?.toInt()?.let { newSteps-> if (initialSteps==-1) {initialSteps = newSteps}currentSteps = newSteps - initialSteps}}override fun onAccuracyChanged(sensor: Sensor,accuracy: Int) = Unit
SLEEPSLEEP RECOGNITION API
Sleep classify eventSleep segment event
Sleep segmentevent•Start timestamp•End timestamp•Duration•Status•Successful•Not detected•Missing data
Sleep classifyevent•Confidence•Light level•Motion level•Timestamp
M T W T F S S
SetupRequirements•Android API Level > v29•Android Build Tools > v21•Google Play ServicesDependency•com.google.android.gms:play-services-location:21.0.0
ReceiverAndroid Manifestandroid:name=".receiver.SleepReceiver"android:enabled="true"android:exported="true"/>
ReceiverAndroid Manifestandroid:name=".receiver.SleepReceiver"android:enabled="true"android:exported="true"/>SleepReceiver : BroadcastReceiver()override fun onReceive(context: Context, intent: Intent) {if (SleepSegmentEvent.hasEvents(intent)) {.. .} else if (SleepClassifyEvent.hasEvents(intent)) {.. .}}
PermissionsAndroid Manifestandroid:name=“android.permission.ACTIVITY_RECOGNITION"/>
PermissionsAndroid Manifest/ >MainActivityContextCompat.checkSelfPermission(context,permission.ACTIVITY_RECOGNITION)_
PermissionsAndroid Manifest/ >MainActivityContextCompat.checkSelfPermission(context,permission.ACTIVITY_RECOGNITION)_val requestPermissionLauncher: ActivityResultLauncher =registerForActivityResult(ActivityResultContracts.RequestPermission()){ isGranted->if (!isGranted) {…} else {//ready}}requestPermissionLauncher.launch(permission.ACTIVITY_RECOGNITION)
PermissionsAndroid Manifest/ >MainActivityContextCompat.checkSelfPermission(context,permission.ACTIVITY_RECOGNITION)_val requestPermissionLauncher: ActivityResultLauncher =registerForActivityResult(ActivityResultContracts.RequestPermission()){ isGranted->if (!isGranted) {requestActivityRecognitionPermission()} else {//ready}}requestPermissionLauncher.launch(permission.ACTIVITY_RECOGNITION)private fun requestActivityRecognitionPermission() {val intent = Intent().apply {action = Settings.ACTION_APPLICATION_DETAILS_SETTINGSdata = Uri.fromParts("package", BuildConfig.APPLICATION_ID, null)flags = Intent.FLAG_ACTIVITY_NEW_TASK}startActivity(intent)}
Subscribe tosleep updatesMainActivityActivityRecognition.getClient(context).requestSleepSegmentUpdates(pendingIntent,SleepSegmentRequest.getDefaultSleepSegmentRequest())
ConfidenceMotionLightSegments
GOOGLE FIT APIRECORD
Choose optionsval fitnessOptions = FitnessOptions.builder().addDataType(DataType.TYPE_STEP_COUNT_DELTA,FitnessOptions.ACCESS_READ).addDataType(DataType.AGGREGATE_STEP_COUNT_DELTA,FitnessOptions.ACCESS_READ).build()
Requestpermissionsval account =GoogleSignIn.getAccountForExtension(activity, fitnessOptions)if (!GoogleSignIn.hasPermissions(account, fitnessOptions)) {GoogleSignIn.requestPermissions(activity,PERMISSIONS_REQUEST_CODE,account,fitnessOptions)} else {recordToGoogleFit()}
Choose optionsoverride fun onActivityResult(requestCode: Int,resultCode: Int,data: Intent?) {super.onActivityResult(requestCode, resultCode, data)when (resultCode) {Activity.RESULT_OK->when (requestCode) {PERMISSIONS_REQUEST_CODE->recordToGoogleFit()else->{...}}else->{...}}}
Create a sessionval session = Session.Builder().setName("Today's Run").setIdentifier("Unique_Identifier_Here").setDescription("Long run around home").setActivity(FitnessActivities.RUNNING).setStartTime(startTime, TimeUnit.MILLISECONDS).setEndTime(endTime, TimeUnit.MILLISECONDS).build()
Create a requestval insertRequest =SessionInsertRequest.Builder().setSession(session).build()
Insert requestFitness.getSessionsClient(this,GoogleSignIn.getAccountForExtension(this, fitnessOptions)).insertSession(insertRequest).addOnSuccessListener {...}.addOnFailureListener { e->...}
Q&APhoto by Simone Secci on Unsplash