Skip to content
Open
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package com.example.healthconnect
import android.annotation.SuppressLint
import android.content.Context
import android.util.Log
import androidx.core.app.ActivityCompat.requestPermissions
import androidx.health.connect.client.HealthConnectClient
import androidx.health.connect.client.HealthConnectFeatures
import androidx.health.connect.client.feature.ExperimentalFeatureAvailabilityApi
Expand All @@ -38,8 +39,23 @@ import java.time.ZoneOffset
import androidx.health.connect.client.HealthConnectFeatures.Companion.FEATURE_MINDFULNESS_SESSION
import androidx.health.connect.client.changes.DeletionChange
import androidx.health.connect.client.changes.UpsertionChange
import androidx.health.connect.client.permission.HealthPermission
import androidx.health.connect.client.records.BloodPressureRecord
import androidx.health.connect.client.records.BodyTemperatureRecord
import androidx.health.connect.client.records.ExerciseCompletionGoal
import androidx.health.connect.client.records.ExercisePerformanceTarget
import androidx.health.connect.client.records.ExerciseSegment
import androidx.health.connect.client.records.NutritionRecord
import androidx.health.connect.client.records.OxygenSaturationRecord
import androidx.health.connect.client.records.PlannedExerciseBlock
import androidx.health.connect.client.records.PlannedExerciseSessionRecord
import androidx.health.connect.client.records.PlannedExerciseStep
import androidx.health.connect.client.records.Record
import androidx.health.connect.client.records.RespiratoryRateRecord
import androidx.health.connect.client.records.SkinTemperatureRecord
import androidx.health.connect.client.records.SleepSessionRecord
import androidx.health.connect.client.records.SpeedRecord
import androidx.health.connect.client.records.TotalCaloriesBurnedRecord
import androidx.health.connect.client.records.WeightRecord
import androidx.health.connect.client.records.metadata.DataOrigin
import androidx.health.connect.client.request.AggregateGroupByDurationRequest
Expand All @@ -55,10 +71,12 @@ import java.time.Duration
import com.google.android.gms.fitness.data.LocalDataSet
import com.google.android.gms.fitness.data.LocalDataType
import com.google.android.gms.fitness.request.LocalDataReadRequest
import java.time.LocalDate
import java.time.LocalDateTime
import java.time.Period
import java.time.ZoneId
import java.time.temporal.ChronoUnit
import java.util.UUID
import java.util.concurrent.TimeUnit
import kotlin.random.Random

Expand Down Expand Up @@ -254,6 +272,247 @@ class HealthConnectManager(
}
}

suspend fun createSetOfPermissionSleep(
Comment thread
shounbi marked this conversation as resolved.
Outdated
healthConnectClient: HealthConnectClient,
record: StepsRecord
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Parameters not needed

): Set<String> {
Comment thread
shounbi marked this conversation as resolved.
Outdated
// [START android_healthconnect_create_set_of_permissions_sleep]
val permissions =
setOf(
HealthPermission.getReadPermission(SleepSessionRecord::class),
HealthPermission.getWritePermission(SleepSessionRecord::class),
HealthPermission.getReadPermission(HeartRateRecord::class),
HealthPermission.getWritePermission(HeartRateRecord::class),
HealthPermission.getReadPermission(OxygenSaturationRecord::class),
HealthPermission.getWritePermission(OxygenSaturationRecord::class),
HealthPermission.getReadPermission(RespiratoryRateRecord::class),
HealthPermission.getWritePermission(RespiratoryRateRecord::class)
)
// [END android_healthconnect_create_set_of_permissions_sleep]
return permissions
}

suspend fun createSetOfPermissionVitals(
Comment thread
shounbi marked this conversation as resolved.
Outdated
healthConnectClient: HealthConnectClient,
record: StepsRecord
Comment on lines +295 to +296
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Parameters not needed

): Set<String> {
// [START android_healthconnect_create_set_of_permissions_vitals]
val permissions =
setOf(
HealthPermission.getReadPermission(BloodPressureRecord::class),
HealthPermission.getWritePermission(BloodPressureRecord::class),
HealthPermission.getReadPermission(HeartRateRecord::class),
HealthPermission.getWritePermission(HeartRateRecord::class),
HealthPermission.getReadPermission(BodyTemperatureRecord::class),
HealthPermission.getWritePermission(BodyTemperatureRecord::class)
)
// [END android_healthconnect_create_set_of_permissions_vitals]
return permissions
}

suspend fun createSetOfPermissionWorkout(
Comment thread
shounbi marked this conversation as resolved.
Outdated
healthConnectClient: HealthConnectClient,
record: StepsRecord
Comment thread
shounbi marked this conversation as resolved.
Outdated
): Set<String> {
// [START android_healthconnect_create_set_of_permissions_workout]
val permissions =
setOf(
HealthPermission.getReadPermission(ExerciseSessionRecord::class),
HealthPermission.getWritePermission(ExerciseSessionRecord::class),
HealthPermission.getReadPermission(HeartRateRecord::class),
HealthPermission.getWritePermission(HeartRateRecord::class),
HealthPermission.getReadPermission(SpeedRecord::class),
HealthPermission.getWritePermission(SpeedRecord::class),
HealthPermission.getReadPermission(DistanceRecord::class),
HealthPermission.getWritePermission(DistanceRecord::class),
HealthPermission.getReadPermission(TotalCaloriesBurnedRecord::class),
HealthPermission.getWritePermission(TotalCaloriesBurnedRecord::class),
HealthPermission.getReadPermission(StepsRecord::class),
HealthPermission.getWritePermission(StepsRecord::class)
)
// [END android_healthconnect_create_set_of_permissions_workout]

val granted = healthConnectClient.permissionController.getGrantedPermissions()
// [START android_healthconnect_check_permission_granted]
if (!granted.containsAll(permissions)) {
// Check if required permissions are not granted, and return
}
Comment thread
shounbi marked this conversation as resolved.
// Permissions already granted; proceed with inserting or reading data
// [START android_healthconnect_check_permission_granted]
return permissions
}

suspend fun createSetOfPermissionGetStarted(
Comment thread
shounbi marked this conversation as resolved.
Outdated
healthConnectClient: HealthConnectClient,
record: StepsRecord
Comment thread
shounbi marked this conversation as resolved.
Outdated
): Set<String> {
// [START android_healthconnect_create_set_of_permissions_user]
val permissions =
setOf(
HealthPermission.getReadPermission(HeartRateRecord::class),
HealthPermission.getWritePermission(HeartRateRecord::class),
HealthPermission.getReadPermission(StepsRecord::class),
HealthPermission.getWritePermission(StepsRecord::class)
)
// [END android_healthconnect_create_set_of_permissions_user]
return permissions
}

suspend fun createPermissionStep(
Comment thread
shounbi marked this conversation as resolved.
Outdated
healthConnectClient: HealthConnectClient,
record: StepsRecord
Comment thread
shounbi marked this conversation as resolved.
Outdated
): Set<String> {
// [START android_healthconnect_create_set_of_permissions_step]
val permissions =
setOf(
HealthPermission.getReadPermission(StepsRecord::class),
HealthPermission.getWritePermission(StepsRecord::class)
)
// [END android_healthconnect_create_set_of_permissions_step]
return permissions
}

suspend fun createPermissionHeartRate(): Set<String> {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
suspend fun createPermissionHeartRate(): Set<String> {
fun createPermissionHeartRate(): Set<String> {

// [START android_healthconnect_create_set_of_permissions_heart_rate]
val permissions =
setOf(
HealthPermission.getReadPermission(HeartRateRecord::class),
HealthPermission.getWritePermission(HeartRateRecord::class)
)
// [END android_healthconnect_create_set_of_permissions_heart_rate]
return permissions
}

suspend fun createPermissionSleepSession(): Set<String> {
// [START android_healthconnect_create_set_of_permissions_sleep_session]
val permissions =
setOf(
HealthPermission.getReadPermission(SleepSessionRecord::class),
HealthPermission.getWritePermission(SleepSessionRecord::class)
)
// [END android_healthconnect_create_set_of_permissions_sleep_session]
return permissions
}

suspend fun createPermissionExcerciseSession(): Set<String> {
Comment thread
shounbi marked this conversation as resolved.
Outdated
// [START android_healthconnect_create_set_of_permissions_excercise_session]
val permissions =
setOf(
HealthPermission.getReadPermission(ExerciseSessionRecord::class),
HealthPermission.getWritePermission(ExerciseSessionRecord::class)
)
// [END android_healthconnect_create_set_of_permissions_excercise_session]
return permissions
}

suspend fun createPermissionMindfulness(): Set<String> {
// [START android_healthconnect_create_set_of_permissions_mindfulness]
val permissions =
setOf(
HealthPermission.getReadPermission(MindfulnessSessionRecord::class),
HealthPermission.getWritePermission(MindfulnessSessionRecord::class)
)
// [END android_healthconnect_create_set_of_permissions_mindfulness]
return permissions
}

suspend fun createPermissionTrainingPlan(): Set<String> {
// [START android_healthconnect_create_set_of_permissions_training_plan]
val permissions =
setOf(
HealthPermission.getReadPermission(HeartRateRecord::class),
HealthPermission.getWritePermission(HeartRateRecord::class),
HealthPermission.getReadPermission(PlannedExerciseSessionRecord::class),
HealthPermission.getWritePermission(PlannedExerciseSessionRecord::class),
HealthPermission.getReadPermission(ExerciseSessionRecord::class),
HealthPermission.getWritePermission(ExerciseSessionRecord::class)
)
// [END android_healthconnect_create_set_of_permissions_training_plan]
return permissions
}


suspend fun createPermissionSkinTemperature(): Set<String> {
// [START android_healthconnect_create_set_of_permissions_skin_temperature]
val permissions =
setOf(
HealthPermission.getReadPermission(SkinTemperatureRecord::class),
HealthPermission.getWritePermission(SkinTemperatureRecord::class)
)
// [END android_healthconnect_create_set_of_permissions_skin_temperature]
return permissions
}

suspend fun checkPermissionPlannedExceriseSession() {
Comment thread
shounbi marked this conversation as resolved.
Outdated
// [START android_healthconnect_check_permission_planned_excerise_session]
// Verify the user has granted all necessary permissions for this task
val grantedPermissions =
healthConnectClient.permissionController.getGrantedPermissions()
if (!grantedPermissions.contains(
HealthPermission.getWritePermission(PlannedExerciseSessionRecord::class))) {
// The user hasn't granted the app permission to write planned exercise session data.
return
}

val plannedDuration = Duration.ofMinutes(90)
val plannedStartDate = LocalDate.now().plusDays(2)

val plannedExerciseSessionRecord = PlannedExerciseSessionRecord(
startDate = plannedStartDate,
duration = plannedDuration,
Comment thread
shounbi marked this conversation as resolved.
Outdated
exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_RUNNING,
blocks = listOf(
PlannedExerciseBlock(
repetitions = 1, steps = listOf(
PlannedExerciseStep(
exerciseType = ExerciseSegment.EXERCISE_SEGMENT_TYPE_RUNNING,
exercisePhase = PlannedExerciseStep.EXERCISE_PHASE_ACTIVE,
completionGoal = ExerciseCompletionGoal.RepetitionsGoal(repetitions = 3),
performanceTargets = listOf(
ExercisePerformanceTarget.HeartRateTarget(
minHeartRate = 90.0, maxHeartRate = 110.0
)
)
),
), description = "Three laps around the lake"
)
),
title = "Run at lake",
notes = null,
metadata = Metadata(
device = Device(type = Device.Companion.TYPE_PHONE)
)
)
val insertedPlannedExerciseSessions =
healthConnectClient.insertRecords(listOf(plannedExerciseSessionRecord)).recordIdsList
val insertedPlannedExerciseSessionId = insertedPlannedExerciseSessions.first()
// [END android_healthconnect_check_permission_planned_excerise_session]
}

@SuppressLint("RestrictedApi")
Comment thread
shounbi marked this conversation as resolved.
suspend fun insertRecords(
healthConnectClient: HealthConnectClient,
record: ExerciseSessionRecord,
startTime: Instant
){
Comment thread
shounbi marked this conversation as resolved.
// [START android_healthconnect_create_insert_record]
val sessionId = UUID.randomUUID().toString()
val sessionClientId = UUID.randomUUID().toString()
val zoneOffset = ZoneOffset.systemDefault().rules.getOffset(startTime)

val session = ExerciseSessionRecord(
startTime = startTime,
startZoneOffset = zoneOffset,
endTime = startTime.plusSeconds(3600),
endZoneOffset = zoneOffset,
exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_RUNNING,
metadata = Metadata(clientRecordId = sessionClientId),
)

healthConnectClient.insertRecords(listOf(session))
// [END android_healthconnect_create_insert_record]
}

suspend fun heartRateRecordExample(
healthConnectClient: HealthConnectClient,
record: StepsRecord
Expand Down Expand Up @@ -978,4 +1237,45 @@ class HealthConnectManager(
healthConnectClient.insertRecords(listOf(session))
// [END android_healthconnect_write_exercise_route]
}

@SuppressLint("RestrictedApi")
Comment thread
shounbi marked this conversation as resolved.
suspend fun insertSegmentExerciseSession(startTime: Instant, endTime: Instant, insertedPlannedExerciseSessionId: String) {
Comment thread
shounbi marked this conversation as resolved.
Outdated
// [START android_healthconnect_insert_segment_exercise_session]
// Verify the user has granted all necessary permissions for this task
val grantedPermissions =
healthConnectClient.permissionController.getGrantedPermissions()
if (!grantedPermissions.contains(
HealthPermission.getWritePermission(ExerciseSessionRecord::class))) {
// The user doesn't granted the app permission to write exercise session data.
return
}

val sessionDuration = Duration.ofMinutes(90)
val sessionEndTime = Instant.now()
val sessionStartTime = sessionEndTime.minus(sessionDuration)

val exerciseSessionRecord = ExerciseSessionRecord(
startTime = sessionStartTime,
startZoneOffset = ZoneOffset.UTC,
endTime = sessionEndTime,
endZoneOffset = ZoneOffset.UTC,
exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_RUNNING,
segments = listOf(
ExerciseSegment(
startTime = sessionStartTime,
endTime = sessionEndTime,
repetitions = 3,
segmentType = ExerciseSegment.EXERCISE_SEGMENT_TYPE_RUNNING
)
),
title = "Run at lake",
plannedExerciseSessionId = insertedPlannedExerciseSessionId,
metadata = Metadata(
device = Device(type = Device.Companion.TYPE_PHONE)
)
)
val insertedExerciseSessions =
healthConnectClient.insertRecords(listOf(exerciseSessionRecord))
// [END android_healthconnect_insert_segment_exercise_session]
}
}