讀取原始資料

以下範例說明如何在常見工作流程中讀取原始資料。

讀取資料

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 天以上舊的記錄會導致錯誤。

已刪除應用程式的權限記錄

如果使用者刪除您的應用程式,系統會撤銷所有權限,包括瀏覽記錄權限。當使用者重新安裝應用程式並再次授予權限後,會套用相同的預設限制,應用程式最多便可讀取從這個新日期回推 30 天的 Health Connect 資料。

舉例來說,假設使用者在 2023 年 5 月 10 日刪除您的應用程式,然後在 2023 年 5 月 15 日重新安裝應用程式,並授予讀取權限。此時,應用程式可讀取最早溯及 2023 年 4 月 15 日的資料。