Java版Android集成Google Health Connect API计步功能遇阻求助
在Java Android应用中集成Google Health Connect API计步功能的问题
我正在用Java开发Android原生应用,想要集成Google Health Connect API实现计步功能,但遇到了问题——无法将用Kotlin编写的Google Health Connect相关方法整合到Java项目的Fragment与Activity中。
我已经按照Google官方教程《Get started with Health Connect》的步骤操作,还修改了官方提供的代码,但仍然没能成功。
有没有开发者具备在Java版Android应用中集成这款Google新API的经验?
我的Kotlin代码:HealthConnectManager
import android.content.Context import android.util.Log import androidx.health.connect.client.HealthConnectClient import androidx.health.connect.client.aggregate.AggregateMetric import androidx.health.connect.client.aggregate.AggregationResultGroupedByPeriod import androidx.health.connect.client.permission.HealthPermission import androidx.health.connect.client.records.ExerciseSessionRecord import androidx.health.connect.client.records.SleepSessionRecord import androidx.health.connect.client.records.StepsRecord import androidx.health.connect.client.request.AggregateGroupByPeriodRequest import androidx.health.connect.client.time.TimeRangeFilter.Companion.between import com.google.android.gms.fitness.data.DataType import kotlinx.coroutines.CoroutineScope import java.time.Duration.between import java.time.LocalDate import java.time.LocalDateTime import java.time.LocalTime import java.time.Period import java.time.ZoneId import java.time.ZonedDateTime import java.time.format.DateTimeFormatter import java.util.TimeZone import kotlin.time.Duration data class DataRecord( val metricValue: String, val dataType: DataType, val fromDatetime: String, val toDatetime: String ) class HealthConnectManager(private val context: Context) { private var healthConnectClient: HealthConnectClient? = null val PERMISSIONS = setOf( HealthPermission.getReadPermission(StepsRecord::class), ) private val dateTimeFormatter: DateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssXXX") fun checkForHealthConnectInstalled(context: Context): Int { val availabilityStatus = HealthConnectClient.getSdkStatus(context, "com.google.android.apps.healthdata") when (availabilityStatus) { HealthConnectClient.SDK_UNAVAILABLE -> { Log.w("HealthConnectUtils", "Health Connect SDK is unavailable on this device.") } HealthConnectClient.SDK_UNAVAILABLE_PROVIDER_UPDATE_REQUIRED -> { Log.w("HealthConnectUtils", "Health Connect SDK needs an update.") } HealthConnectClient.SDK_AVAILABLE -> { Log.i("HealthConnectUtils", "Health Connect SDK is available.") healthConnectClient = HealthConnectClient.getOrCreate(context) } } return availabilityStatus } suspend fun checkPermissions(): Boolean { val granted = healthConnectClient?.permissionController?.getGrantedPermissions() return granted?.containsAll(PERMISSIONS) == true } suspend fun readStepsForInterval(interval: Long): List<DataRecord> { return readAggregateDataForInterval(interval, DataType.TYPE_STEP_COUNT_DELTA, StepsRecord.COUNT_TOTAL) } private suspend fun <T : Any> readAggregateDataForInterval(interval: Long, dataType: DataType, metric: AggregateMetric<T>): List<DataRecord> { val startTime: ZonedDateTime = LocalDate.now().atStartOfDay(ZoneId.systemDefault()).minusDays(interval - 1) val endTime = LocalDateTime.now().atZone(TimeZone.getDefault().toZoneId()).minusMinutes(1).plusSeconds(59) val response = healthConnectClient?.aggregateGroupByPeriod( AggregateGroupByPeriodRequest( metrics = setOf(metric), timeRangeFilter = between(startTime.toLocalDate().atStartOfDay(), endTime.toLocalDateTime()), timeRangeSlicer = Period.ofDays(1) ) ) return parseAggregateResponse(response, startTime, endTime, dataType, metric) } private fun <T : Any> parseAggregateResponse( response: List<AggregationResultGroupedByPeriod>?, startTime: ZonedDateTime, endTime: ZonedDateTime, dataType: DataType, metric: AggregateMetric<T> ): List<DataRecord> { val data = mutableListOf<DataRecord>() if (response != null) { response.sortedBy { it.startTime } var trackTime = startTime.toLocalDate().atStartOfDay() for (dailyResult in response) { if (dailyResult.startTime.isAfter(trackTime)) { while (trackTime.isBefore(dailyResult.startTime)) { data.add( DataRecord( metricValue = "No data", dataType = dataType, toDatetime = trackTime.toLocalDate().atTime(LocalTime.MAX) .atZone(ZoneId.systemDefault()).format(dateTimeFormatter), fromDatetime = if (trackTime.toLocalDate().isEqual(startTime.toLocalDate())) startTime.format(dateTimeFormatter) else trackTime.atZone(ZoneId.systemDefault()).format(dateTimeFormatter) ) ) trackTime = trackTime.plusDays(1) } } val totalValue = dailyResult.result[metric] data.add( DataRecord( metricValue = (totalValue ?: "No data").toString(), dataType = dataType, toDatetime = dailyResult.endTime.atZone(ZoneId.systemDefault()).minusSeconds(1).format(dateTimeFormatter), fromDatetime = if (dailyResult.startTime.toLocalDate().isEqual(startTime.toLocalDate())) startTime.format(dateTimeFormatter) else dailyResult.startTime.atZone(ZoneId.systemDefault()).format(dateTimeFormatter) ) ) trackTime = dailyResult.endTime } while (trackTime.isBefore(endTime.toLocalDateTime()) && between(trackTime, endTime).toMinutes() > 1) { data.add( DataRecord( metricValue = "No data", dataType = dataType, toDatetime = if (trackTime.toLocalDate().isEqual(endTime.toLocalDate())) endTime.format(dateTimeFormatter) else trackTime.toLocalDate().atTime(LocalTime.MAX) .atZone(ZoneId.systemDefault()).format(dateTimeFormatter), fromDatetime = if (trackTime.toLocalDate().isEqual(startTime.toLocalDate())) startTime.format(dateTimeFormatter) else trackTime.atZone(ZoneId.systemDefault()).format(dateTimeFormatter) ) ) trackTime = trackTime.plusDays(1).toLocalDate().atStartOfDay() } } Log.d("HealthConnectUtils", "Parsed Data: $data") return data } suspend fun writeStepsData(context: Context, steps: Int, startTime: ZonedDateTime, endTime: ZonedDateTime) { val stepsRecord = StepsRecord( count = steps.toLong(), startTime = startTime.toInstant(), startZoneOffset = startTime.offset, endTime = endTime.toInstant(), endZoneOffset = endTime.offset ) val response = healthConnectClient?.insertRecords(listOf(stepsRecord)) if (response != null) { Log.d("HealthConnectUtils", "Steps data written successfully: $response") } else { Log.e("HealthConnectUtils", "Failed to write steps data.") } } }
内容的提问来源于stack exchange,提问作者Otar
相关产品推荐
相关产品推荐

