Health Connect предоставляет тип данных «шаги» для записи количества шагов с помощью StepsRecord . Шаги — это основополагающий показатель в отслеживании здоровья и физической активности.
Прочитайте шаги для мобильных устройств.
При использовании Android 14 (уровень API 34) и SDK Extension версии 20 или выше, Health Connect обеспечивает подсчет шагов непосредственно на устройстве. Если какому-либо приложению предоставлено разрешение READ_STEPS , Health Connect начинает фиксировать шаги на устройстве под управлением Android, и пользователи автоматически видят данные о шагах, добавляемые в записи Health Connect Steps .
Чтобы проверить наличие функции подсчета шагов на устройстве, убедитесь, что устройство работает под управлением Android 14 (уровень API 34) и имеет как минимум версию расширения SDK 20:
val isStepTrackingAvailable =
Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE &&
SdkExtensions.getExtensionVersion(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) >= 20
Если ваше приложение считывает агрегированные данные о количестве шагов с помощью aggregate и не фильтрует по DataOrigin , то шаги, сделанные на устройстве, автоматически включаются в общую сумму, и никаких изменений для обновления в июне 2026 года не требуется.
Изменение атрибуции для шагов, выполняемых на устройстве.
Начиная с обновления от июня 2026 года, шаги, отслеживаемые приложением Health Connect, приписываются синтетическому имени пакета (SPN) , например, com.android.healthconnect.phone.jd5bdd37e1a8d3667a05d0abebfc4a89e .
Ранее встроенные данные о количестве шагов были привязаны к имени пакета android . В исторических данных о количестве шагов, записанных до июня 2026 года, сохраняется имя пакета android .
SPN (Single Podsecurity Networks) привязаны к конкретному устройству и используются в рамках каждого приложения для защиты конфиденциальности пользователей:
- Стабильность: Значение SPN для текущего устройства стабильно для вашего приложения.
- Ограничение по области действия приложения: разные приложения на одном устройстве видят разные SPN для данных о шагах, хранящихся на устройстве.
Запрос шагов, выполняемых на устройстве.
Поскольку SPN имеют ограниченную область видимости и зависят от устройства, не следует жестко задавать значения SPN. Вместо этого используйте API getCurrentDeviceDataSource() для получения SPN для текущего устройства.
В то время как для подсчета шагов на устройстве требуется расширение SDK версии 20 или выше, API getCurrentDeviceDataSource() доступен в Android 14 (уровень API 34) с расширением SDK версии 11 или выше.
API-функция getCurrentDeviceDataSource() пока недоступна в библиотеке Health Connect Jetpack. В следующих примерах используется API фреймворка Android:
import android.content.Context
import android.health.connect.HealthConnectManager
val healthConnectManager = context.getSystemService(HealthConnectManager::class.java)
val deviceDataSource = healthConnectManager?.getCurrentDeviceDataSource()
val currentDeviceSpn = deviceDataSource?.deviceDataOrigin?.packageName
Если вашему приложению необходимо считывать данные о шагах, выполняемых на устройстве, или если оно отображает данные о шагах с разбивкой по исходному приложению или устройству, вам необходимо запросить записи, где DataOrigin равен android или соответствует SPN устройства. Если ваше приложение отображает атрибуцию для данных о шагах, используйте metadata.device для идентификации исходного устройства для отдельных записей. Для шагов, выполняемых на устройстве и идентифицированных по SPN в агрегированных данных, вы можете использовать метаданные устройства, такие как model или manufacturer из DeviceDataSource для атрибуции, или использовать общую метку, например, «Ваш телефон», для шагов, выполняемых на устройстве.
В следующем примере показано, как считывать агрегированные данные о количестве шагов на устройстве, фильтруя их по типу android и по SPN текущего устройства:
import android.content.Context
import android.health.connect.HealthConnectManager
import android.os.Build
import android.os.ext.SdkExtensions
import androidx.health.connect.client.HealthConnectClient
import androidx.health.connect.client.records.StepsRecord
import androidx.health.connect.client.records.metadata.DataOrigin
import androidx.health.connect.client.request.AggregateRequest
import androidx.health.connect.client.time.TimeRangeFilter
import java.time.Instant
suspend fun readDeviceStepsByTimeRange(
healthConnectClient: HealthConnectClient,
context: Context,
startTime: Instant,
endTime: Instant
) {
// 1. Check if SDK Extension 11+ is available for getCurrentDeviceDataSource()
val isDataSourceApiAvailable = Build.VERSION.SDK_INT >= Build.VERSION_CODES.U &&
SdkExtensions.getExtensionVersion(Build.VERSION_CODES.U) >= 11
try {
val healthConnectManager = context.getSystemService(HealthConnectManager::class.java)
// 2. Safely fetch the package name only if API is available and data exists
val currentDeviceSpn = if (isDataSourceApiAvailable) {
healthConnectManager?.getCurrentDeviceDataSource()?.deviceDataOrigin?.packageName
} else {
null
}
val dataOriginFilters = mutableSetOf(DataOrigin("android"))
// 3. Explicit null-safety check using .let
currentDeviceSpn?.let {
dataOriginFilters.add(DataOrigin(it))
}
val response = healthConnectClient.aggregate(
AggregateRequest(
metrics = setOf(StepsRecord.COUNT_TOTAL),
timeRangeFilter = TimeRangeFilter.between(startTime, endTime),
dataOriginFilter = dataOriginFilters
)
)
val stepCount = response[StepsRecord.COUNT_TOTAL]
} catch (e: Exception) {
// Now this catch block only handles actual runtime exceptions,
// rather than Errors from missing methods.
}
}
Подсчет шагов на устройстве
- Использование датчика : Health Connect использует датчик
TYPE_STEP_COUNTERизSensorManager. Этот датчик оптимизирован для низкого энергопотребления, что делает его идеальным для непрерывного фонового отслеживания шагов. - Детализация данных : Для экономии заряда батареи данные о количестве шагов обычно объединяются в пакеты и записываются в базу данных Health Connect не чаще одного раза в минуту.
- Атрибуция : Шаги, записанные этой функцией до июня 2026 года, приписываются имени пакета
androidвDataOrigin. После этой даты они приписываются SPN, специфичному для устройства. См. Изменение атрибуции для шагов на устройстве . - Активация : Механизм подсчета шагов на устройстве активируется только в том случае, если хотя бы одному приложению на устройстве предоставлено разрешение
READ_STEPSв рамках Health Connect.
Проверьте доступность Health Connect.
Перед использованием Health Connect ваше приложение должно убедиться, что Health Connect доступен на устройстве пользователя. Health Connect может быть не предустановлен на всех устройствах или отключен. Проверить доступность можно с помощью метода HealthConnectClient.getSdkStatus() .
Как проверить доступность Health Connect
fun checkHealthConnectAvailability(context: Context) { val providerPackageName = "com.google.android.apps.healthdata" // Or get from HealthConnectClient.DEFAULT_PROVIDER_PACKAGE_NAME val availabilityStatus = HealthConnectClient.getSdkStatus(context, providerPackageName) if (availabilityStatus == HealthConnectClient.SDK_UNAVAILABLE) { // Health Connect is not available. Guide the user to install/enable it. // For example, show a dialog. return // early return as there is no viable integration } if (availabilityStatus == HealthConnectClient.SDK_UNAVAILABLE_PROVIDER_UPDATE_REQUIRED) { // Health Connect is available but requires an update. // Optionally redirect to package installer to find a provider, for example: val uriString = "market://details?id=$providerPackageName&url=healthconnect%3A%2F%2Fonboarding" context.startActivity( Intent(Intent.ACTION_VIEW).apply { setPackage("com.android.vending") data = Uri.parse(uriString) putExtra("overlay", true) putExtra("callerId", context.packageName) } ) return } // Health Connect is available, obtain a HealthConnectClient instance val healthConnectClient = HealthConnectClient.getOrCreate(context) // Issue operations with healthConnectClient }
В зависимости от статуса, возвращаемого функцией getSdkStatus() , вы можете предложить пользователю установить или обновить Health Connect из магазина Google Play, если это необходимо.
Необходимые разрешения
Доступ к ступеням защищен следующими разрешениями:
-
android.permission.health.READ_STEPS -
android.permission.health.WRITE_STEPS
Чтобы добавить возможность отслеживать шаги в ваше приложение, начните с запроса разрешений для типа данных Steps .
Вот какие разрешения вам необходимо указать, чтобы иметь возможность записывать шаги:
<application>
<uses-permission
android:name="android.permission.health.WRITE_STEPS" />
...
</application>
Для просмотра инструкций вам необходимо запросить следующие разрешения:
<application>
<uses-permission
android:name="android.permission.health.READ_STEPS" />
...
</application>
Запросить у пользователя разрешения
После создания экземпляра клиента ваше приложение должно запросить у пользователя разрешения. Пользователи должны иметь возможность предоставлять или отклонять разрешения в любое время.
Для этого создайте набор разрешений для необходимых типов данных. Убедитесь, что разрешения в этом наборе сначала объявлены в вашем Android-манифесте.
// Create a set of permissions for required data types
val PERMISSIONS =
setOf(
HealthPermission.getReadPermission(StepsRecord::class),
HealthPermission.getWritePermission(StepsRecord::class)
)
Используйте getGrantedPermissions , чтобы проверить, предоставлены ли вашему приложению уже необходимые разрешения. Если нет, используйте createRequestPermissionResultContract для запроса этих разрешений. После этого отобразится экран разрешений Health Connect.
// Create the permissions launcher
val requestPermissionActivityContract = PermissionController.createRequestPermissionResultContract()
val requestPermissions = registerForActivityResult(requestPermissionActivityContract) { granted ->
if (granted.containsAll(PERMISSIONS)) {
// Permissions successfully granted
} else {
// Lack of required permissions
}
}
suspend fun checkPermissionsAndRun(healthConnectClient: HealthConnectClient) {
val granted = healthConnectClient.permissionController.getGrantedPermissions()
if (granted.containsAll(PERMISSIONS)) {
// Permissions already granted; proceed with inserting or reading data
} else {
requestPermissions.launch(PERMISSIONS)
}
}
Поскольку пользователи могут предоставлять или отзывать разрешения в любое время, ваше приложение должно проверять наличие разрешений каждый раз перед их использованием и обрабатывать сценарии, в которых разрешение утрачивается.
Информация, содержащаяся в записи о шагах.
Каждый StepsRecord содержит следующую информацию:
-
count: Количество шагов, сделанных за интервал времени, в форматеLong. -
startTime: Время начала интервала измерения. -
endTime: Время окончания интервала измерения. -
startZoneOffset: Смещение зоны для времени начала. -
endZoneOffset: Смещение зоны для времени окончания.
Поддерживаемые агрегации
Для StepsRecord доступны следующие агрегированные значения:
Для StepsCadenceRecord доступны следующие агрегированные значения:
Пример использования
В следующих разделах показано, как читать и записывать данные StepsRecord .
Запись данных о шагах
Ваше приложение может записывать данные о количестве шагов, добавляя экземпляры StepsRecord . В следующем примере показано, как записать 1000 шагов, сделанных пользователем:
val zoneOffset = ZoneOffset.systemDefault().rules.getOffset(startTime) val stepsRecord = StepsRecord( count = 120, startTime = startTime, endTime = endTime, startZoneOffset = zoneOffset, endZoneOffset = zoneOffset, metadata = Metadata( device = Device(type = Device.TYPE_WATCH), recordingMethod = Metadata.RECORDING_METHOD_AUTOMATICALLY_RECORDED ) ) healthConnectClient.insertRecords(listOf(stepsRecord))
Прочитать сводные данные
Наиболее распространенный способ чтения данных о шагах — это суммирование общего количества шагов за определенный период времени. В следующем примере показано, как прочитать общее количество шагов пользователя за определенный период времени:
suspend fun readStepsAggregate(startTime: Instant, endTime: Instant): Long { val response = healthConnectClient.aggregate( AggregateRequest( metrics = setOf(StepsRecord.COUNT_TOTAL), timeRangeFilter = TimeRangeFilter.between(startTime, endTime) ) ) return response[StepsRecord.COUNT_TOTAL] ?: 0L }
Прочитать исходные данные
В следующем примере показано, как считывать необработанные данные StepsRecord в промежутке между временем начала и временем окончания:
val response = healthConnectClient.readRecords( ReadRecordsRequest( StepsRecord::class, timeRangeFilter = TimeRangeFilter.between(startTime, endTime) ) ) response.records.forEach { record -> /* Process records */ }