读取原始数据

以下示例展示了如何作为常见工作流的一部分读取原始数据。

读取数据

Health Connect 允许应用在应用处于前台和后台时从数据存储区读取数据

  • 前台读取:通常情况下,当您的应用处于前台时,您可以从 Health Connect 读取数据。在这种情况下,您可以考虑使用前台服务来运行此操作,以防用户或系统在读取操作期间将您的应用置于后台。

  • 后台读取:通过向用户请求额外权限,您可以在用户或系统将您的应用置于后台后读取数据。请参阅完整的后台读取示例

Health Connect 中的“步数”数据类型会捕获用户在两次读取之间所走的步数。步数是健康、健身和养生平台上的常见测量指标。Health Connect 让读写步数数据变得简单。

要读取记录,请创建一个 ReadRecordsRequest,并在调用 readRecords 时提供它。

以下示例展示了如何在特定时间内读取用户的步数数据。如需包含 SensorManager 的扩展示例,请参阅步数数据指南。

suspend fun readStepsByTimeRange(
    healthConnectClient: HealthConnectClient,
    startTime: Instant,
    endTime: Instant
) {
    try {
        val response = healthConnectClient.readRecords(
            ReadRecordsRequest(
                StepsRecord::class,
                timeRangeFilter = TimeRangeFilter.between(startTime, endTime)
            )
        )
        for (stepRecord in response.records) {
            // Process each step record
        }
    } catch (e: Exception) {
        // Run error handling here
    }
}

后台读取示例

要在后台读取数据,请在您的清单文件中声明以下权限

<application>
  <uses-permission android:name="android.permission.health.READ_HEALTH_DATA_IN_BACKGROUND" />
...
</application>

以下示例展示了如何使用 WorkManager 在特定时间内后台读取用户的步数数据

class ScheduleWorker(private val appContext: Context, workerParams: WorkerParameters):
    CoroutineWorker(appContext, workerParams) {

    override suspend fun doWork(): Result {
        // Read data and process it.
        ...

        // Return success indicating successful data retrieval
        return Result.success()
    }
}

if (healthConnectClient
    .features
    .getFeatureStatus(
    HealthConnectFeatures.FEATURE_READ_HEALTH_DATA_IN_BACKGROUND
    ) == HealthConnectFeatures.FEATURE_STATUS_AVAILABLE) {

    // Check if necessary permission is granted
    val grantedPermissions = healthConnectClient.permissionController.getGrantedPermissions()

    if (PERMISSION_READ_HEALTH_DATA_IN_BACKGROUND !in grantedPermissions) {
        // Perform read in foreground
        ...
    } else {
        // Schedule the periodic work request in background
        val periodicWorkRequest = PeriodicWorkRequestBuilder<ScheduleWorker>(1, TimeUnit.HOURS)
            .build()

        WorkManager.getInstance(context).enqueueUniquePeriodicWork(
            "read_health_connect",
            ExistingPeriodicWorkPolicy.KEEP,
            periodicWorkRequest
        )
    }
} else {
  // Background reading is not available, perform read in foreground
  ...
}

ReadRecordsRequest 参数的默认 pageSize 值为 1000。如果单个 readResponse 中的记录数超过请求的 pageSize,您需要迭代响应的所有页面,以使用 pageToken 检索所有记录。但是,请注意避免速率限制问题。

pageToken 读取示例

建议使用 pageToken 读取记录,以检索所请求时间段内的所有可用数据。

以下示例展示了如何读取所有记录,直到所有页面令牌都已用尽

val type = HeartRateRecord::class
val endTime = Instant.now()
val startTime = endTime.minus(Duration.ofDays(7))

try {
    var pageToken: String? = null
    do {
        val readResponse =
            healthConnectClient.readRecords(
                ReadRecordsRequest(
                    recordType = type,
                    timeRangeFilter = TimeRangeFilter.between(
                        startTime,
                        endTime
                    ),
                    pageToken = pageToken
                )
            )
        val records = readResponse.records
        // Do something with records
        pageToken = readResponse.pageToken
    } while (pageToken != null)
} catch (quotaError: IllegalStateException) {
    // Backoff
}

有关读取大型数据集时的最佳实践信息,请参阅规划避免速率限制

读取之前写入的数据

如果应用之前已将记录写入 Health Connect,则该应用可以读取历史数据。这适用于用户重新安装应用后,应用需要与 Health Connect 重新同步的场景。

存在一些读取限制

  • 对于 Android 14 及更高版本

    • 应用读取自身数据没有历史限制。
    • 应用读取其他数据有 30 天的限制。
  • 对于 Android 13 及更低版本

    • 应用读取任何数据有 30 天的限制。

通过请求读取权限可以移除这些限制。

要读取历史数据,您需要在 ReadRecordsRequestdataOriginFilter 参数中将软件包名称指示为 DataOrigin 对象。

以下示例展示了在读取步数记录时如何指示软件包名称

try {
    val response =  healthConnectClient.readRecords(
        ReadRecordsRequest(
            recordType = StepsRecord::class,
            timeRangeFilter = TimeRangeFilter.between(startTime, endTime),
            dataOriginFilter = setOf(DataOrigin("com.my.package.name"))
        )
    )
    for (record in response.records) {
        // Process each record
    }
} catch (e: Exception) {
    // Run error handling here
}

读取 30 天前的数据

默认情况下,所有应用都可以读取 Health Connect 中自首次授予任何权限之日起 30 天内的数据。

如果您需要将读取权限扩展到任何默认限制之外,请请求 PERMISSION_READ_HEALTH_DATA_HISTORY。否则,如果没有此权限,尝试读取 30 天前的记录将导致错误。

已删除应用的权限历史记录

如果用户删除您的应用,所有权限(包括历史记录权限)都将被撤销。如果用户重新安装您的应用并再次授予权限,则相同的默认限制适用,您的应用可以从该新日期起读取 Health Connect 中 30 天内的数据。

例如,假设用户在 2023 年 5 月 10 日删除您的应用,然后在 2023 年 5 月 15 日重新安装应用并授予读取权限。您的应用现在默认最早可以读取数据的日期是2023 年 4 月 15 日