Чтение необработанных данных

В следующем примере показано, как читать необработанные данные в рамках общего рабочего процесса.

Прочитать данные

Health Connect позволяет приложениям считывать данные из хранилища данных, когда приложение находится на переднем плане и в фоновом режиме:

  • Чтения на переднем плане : вы обычно можете читать данные из Health Connect, когда ваше приложение находится на переднем плане. В этих случаях вы можете рассмотреть возможность использования службы переднего плана для запуска этой операции в случае, если пользователь или система помещают ваше приложение в фоновый режим во время операции чтения.

  • Фоновые чтения : запросив дополнительное разрешение у пользователя, вы можете читать данные после того, как пользователь или система переведет ваше приложение в фоновый режим. Смотрите полный пример фонового чтения .

Тип данных Steps в Health Connect фиксирует количество шагов, сделанных пользователем между измерениями. Количество шагов представляет собой общее измерение на платформах для здоровья, фитнеса и оздоровления. Health Connect упрощает чтение и запись данных о количестве шагов.

Чтобы прочитать записи, создайте ReadRecordsRequest и предоставьте его при вызове readRecords .

Следующий пример показывает, как считывать данные о количестве шагов пользователя в течение определенного времени. Для расширенного примера с SensorManager см. руководство по данным о количестве шагов .

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
    }
}

Вы также можете прочитать свои данные в агрегированном виде, используя 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
    }
}

Пример фонового чтения

Чтобы читать данные в фоновом режиме, объявите следующее разрешение в файле манифеста:

<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-дневный лимит на чтение данных приложением.

Ограничения можно снять, запросив разрешение на чтение .

Чтобы прочитать исторические данные, вам необходимо указать имя пакета как объект DataOrigin в параметре dataOriginFilter вашего ReadRecordsRequest .

В следующем примере показано, как указать имя пакета при считывании записей сердечного ритма:

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
}

Чтение данных старше 30 дней

По умолчанию все приложения могут считывать данные из Health Connect за период до 30 дней до момента первого предоставления разрешения.

Если вам необходимо расширить разрешения на чтение за пределы ограничений по умолчанию , запросите PERMISSION_READ_HEALTH_DATA_HISTORY . В противном случае, без этого разрешения, попытка чтения записей старше 30 дней приведет к ошибке.

История разрешений для удаленного приложения

Если пользователь удаляет ваше приложение, все разрешения, включая разрешение на историю, отзываются. Если пользователь переустанавливает ваше приложение и снова предоставляет разрешение, применяются те же ограничения по умолчанию , и ваше приложение может считывать данные из Health Connect в течение 30 дней до этой новой даты.

Например, предположим, что пользователь удаляет ваше приложение 10 мая 2023 года, а затем переустанавливает приложение 15 мая 2023 года и предоставляет разрешения на чтение. Самая ранняя дата, с которой ваше приложение теперь может считывать данные по умолчанию, — это 15 апреля 2023 года .