You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Health Connect API聚合查询报错:Duration需用物理时间设置

Health Connect API聚合查询异常:Duration must be set with physical times 解决方法

我尝试通过Google的Health Connect API获取每日步数聚合统计,代码如下:

val request = AggregateGroupByPeriodRequest(
        setOf(StepsRecord.COUNT_TOTAL),
        TimeRangeFilter.between(Instant.now().minus(10, ChronoUnit.DAYS), Instant.now()),
        Period.ofDays(1),
        setOf<DataOrigin>())
val response = client.aggregateGroupByPeriod(request)

执行任何聚合查询都会抛出如下异常:

java.lang.IllegalStateException: Duration must be set with physical times
at android.os.Parcel.createExceptionOrNull(Parcel.java:3019)
at android.os.Parcel.createException(Parcel.java:2995)
at android.os.Parcel.readException(Parcel.java:2978)
at android.os.Parcel.readException(Parcel.java:2920)
at androidx.health.platform.client.service.IHealthDataService$Stub$Proxy.aggregate(IHealthDataService.java:490)
at androidx.health.platform.client.impl.ServiceBackedHealthDataClient.aggregate$lambda$9(ServiceBackedHealthDataClient.kt:162)
at androidx.health.platform.client.impl.ServiceBackedHealthDataClient.$r8$lambda$sD3sEial4TRJZ0x1SNHmgqr5dxw(Unknown Source:0)
at androidx.health.platform.client.impl.ServiceBackedHealthDataClient$$ExternalSyntheticLambda10.execute(Unknown Source:6)
at androidx.health.platform.client.impl.ipc.Client$3.execute(Client.java:297)
at androidx.health.platform.client.impl.ipc.internal.ServiceConnection.execute(ServiceConnection.java:286)
at androidx.health.platform.client.impl.ipc.internal.ServiceConnection.enqueue(ServiceConnection.java:243)
at androidx.health.platform.client.impl.ipc.internal.ConnectionManager.handleMessage(ConnectionManager.java:148)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.os.HandlerThread.run(HandlerThread.java:67)
Suppressed: kotlinx.coroutines.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@850d063, Dispatchers.Main]

我使用client.readRecords()可以正常获取非聚合数据,以下是异常原因及解决方法:

异常原因

  • 聚合查询要求时间范围必须基于物理时间(带时区的时间),因为按自然日(Period.ofDays(1))分组需要对齐时区边界,而Instant是无时区的时间戳,无法满足该要求。
  • readRecords()无需按周期分组,仅依赖时间戳定位数据,因此无时区要求可以正常执行。

解决方法

将时间范围的Instant替换为带时区的ZonedDateTime,确保时间绑定到具体时区(比如系统默认时区),修改后的代码如下:

val zoneId = ZoneId.systemDefault()
val endTime = ZonedDateTime.now(zoneId).toInstant()
val startTime = ZonedDateTime.now(zoneId).minusDays(10).toInstant()

val request = AggregateGroupByPeriodRequest(
        setOf(StepsRecord.COUNT_TOTAL),
        TimeRangeFilter.between(startTime, endTime),
        Period.ofDays(1),
        setOf<DataOrigin>())
val response = client.aggregateGroupByPeriod(request)

关键修改说明

  • 使用ZonedDateTime获取带时区的时间,确保按自然日分组时对齐当地的0点边界。
  • 时间范围的起始和结束都基于同一时区转换,保证聚合的周期是符合物理时间的自然日。

内容的提问来源于stack exchange,提问作者leremjs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 13:16:01