Odczyt nieprzetworzonych danych

Poniższy przykład pokazuje, jak odczytywać dane pierwotne w ramach typowego procesu.

Odczytywanie danych

Health Connect umożliwia aplikacjom odczytywanie danych z pamięci, gdy są one na pierwszym planie i w tle:

  • Odczytywanie na pierwszym planie: dane z Health Connect możesz zwykle odczytywać, gdy aplikacja jest na pierwszym planie. W takich przypadkach możesz użyć usługi na pierwszym planie, aby wykonać tę operację, jeśli użytkownik lub system umieści aplikację w tle podczas operacji odczytu.

  • Odczytywanie w tle: prosząc użytkownika o dodatkowe uprawnienia, możesz odczytywać dane po tym, jak użytkownik lub system umieści Twoją aplikację w tle. Zobacz pełny przykład odczytu w tle.

Typ danych Kroki w Health Connect rejestruje liczbę kroków, które użytkownik wykonał między odczytami. Liczba kroków to powszechny pomiar na platformach związanych ze zdrowiem, aktywnością fizyczną i dobrym samopoczuciem. Health Connect ułatwia odczytywanie i zapisywanie danych o liczbie kroków.

Aby odczytać rekordy, utwórz ReadRecordsRequest i podaj go podczas wywoływania funkcji readRecords.

Przykład poniżej pokazuje, jak odczytać dane o liczbie kroków użytkownika w określonym czasie. Rozszerzony przykład z SensorManager znajdziesz w przewodniku po danych dotyczących liczby kroków.

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

Możesz też odczytywać dane w formie zagregowanej za pomocą aggregate.

suspend fun readStepsByTimeRange(
    healthConnectClient: HealthConnectClient,
    startTime: Instant,
    endTime: Instant
) {
    try {
        val response = healthConnectClient.aggregate(
            AggregateRequest(
                metrics = setOf(StepsRecord.COUNT_TOTAL),
                timeRangeFilter = TimeRangeFilter.between(startTime, endTime)
            )
        )
        // The result may be null if no data is available in the time range
        val stepCount = response[StepsRecord.COUNT_TOTAL]
    } catch (e: Exception) {
        // Run error handling here
    }
}

Przykład odczytywania w tle

Aby odczytywać dane w tle, zadeklaruj w pliku manifestu to uprawnienie:

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

Przykład poniżej pokazuje, jak odczytać dane o liczbie kroków w tle dla użytkownika w określonym czasie za pomocą funkcji 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
  ...
}

Parametr ReadRecordsRequest ma domyślną wartość pageSize 1000. Jeśli liczba rekordów w jednym readResponse przekracza pageSize żądania, musisz przejść przez wszystkie strony odpowiedzi, aby pobrać wszystkie rekordy, używając pageToken. Uważaj jednak, aby nie przekroczyć limitu żądań.

Przykład odczytu pageToken

Do odczytywania rekordów zalecamy używanie pageToken, aby pobierać wszystkie dostępne dane z wybranego okresu.

Poniższy przykład pokazuje, jak odczytać wszystkie rekordy, dopóki nie zostaną wykorzystane wszystkie tokeny strony:

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
}

Informacje o sprawdzonych metodach odczytywania dużych zbiorów danych znajdziesz w artykule Planowanie, aby uniknąć ograniczenia liczby żądań.

Odczytywanie wcześniej zapisanych danych

Jeśli aplikacja zapisywała wcześniej rekordy w Health Connect, może odczytywać dane historyczne. Dotyczy to sytuacji, w których aplikacja musi ponownie zsynchronizować się z Health Connect po ponownym zainstalowaniu przez użytkownika.

Obowiązują pewne ograniczenia dotyczące odczytu:

  • Android 14 lub nowszy

    • Brak historycznego limitu odczytywania przez aplikację własnych danych.
    • 30-dniowy limit odczytywania przez aplikację innych danych.
  • Android 13 lub starszy

    • 30-dniowy limit odczytywania danych przez aplikację.

Ograniczenia można usunąć, prosząc o uprawnienia do odczytu.

Aby odczytać dane historyczne, musisz wskazać nazwę pakietu jako obiekt DataOrigin w parametrze dataOriginFilter elementu ReadRecordsRequest.

Poniższy przykład pokazuje, jak podczas odczytywania rekordów tętna wskazać nazwę pakietu:

try {
    val response =  healthConnectClient.readRecords(
        ReadRecordsRequest(
            recordType = HeartRateRecord::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
}

Odczytywanie danych starszych niż 30 dni

Domyślnie wszystkie aplikacje mogą odczytywać dane z Health Connect z okresu do 30 dni przed przyznaniem im uprawnień.

Jeśli chcesz rozszerzyć uprawnienia do odczytu poza domyślne ograniczenia, poproś o PERMISSION_READ_HEALTH_DATA_HISTORY. W przeciwnym razie próba odczytania rekordów starszych niż 30 dni bez tego uprawnienia spowoduje błąd.

Historia uprawnień usuniętej aplikacji

Jeśli użytkownik usunie Twoją aplikację, wszystkie uprawnienia, w tym uprawnienia do historii, zostaną cofnięte. Jeśli użytkownik ponownie zainstaluje aplikację i ponownie przyzna jej uprawnienia, będą obowiązywać te same domyślne ograniczenia, a aplikacja będzie mogła odczytywać dane z Health Connect z okresu do 30 dni przed tą nową datą.

Załóżmy na przykład, że użytkownik usunie Twoją aplikację 10 maja 2023 r., a następnie zainstaluje ją ponownie 15 maja 2023 r. i przyzna jej uprawnienia do odczytu. Najwcześniejsza data, od której aplikacja może domyślnie odczytywać dane, to 15 kwietnia 2023 r..