Śledzenie kroków

Health Connect udostępnia typ danych kroki do rejestrowania liczby kroków za pomocą StepsRecord. Kroki to podstawowy pomiar w śledzeniu zdrowia i aktywności.

Odczytywanie danych o krokach na urządzeniu mobilnym

W Androidzie 14 (API na poziomie 34) i w rozszerzeniu SDK w wersji 20 lub nowszej Health Connect zapewnia zliczanie kroków na urządzeniu. Jeśli jakiejkolwiek aplikacji przyznano uprawnienie READ_STEPS, Health Connect zaczyna rejestrować kroki z urządzenia z Androidem, a użytkownicy widzą dane o krokach automatycznie dodawane do wpisów Kroki w Health Connect.

Aby sprawdzić, czy na urządzeniu jest dostępna funkcja zliczania kroków, upewnij się, że urządzenie ma Androida 14 (poziom API 34) i co najmniej wersję 20 rozszerzenia pakietu SDK:

val isStepTrackingAvailable =
    Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE &&
        SdkExtensions.getExtensionVersion(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) >= 20

Jeśli Twoja aplikacja odczytuje zagregowane liczby kroków za pomocą funkcji aggregate i nie filtruje ich według parametru DataOrigin, kroki zarejestrowane na urządzeniu są automatycznie uwzględniane w sumie i nie trzeba wprowadzać żadnych zmian w związku z aktualizacją z czerwca 2026 r.

Zmiana atrybucji w przypadku kroków na urządzeniu

Od aktualizacji z czerwca 2026 r. kroki śledzone natywnie przez Health Connect będą przypisywane do syntetycznej nazwy pakietu (SPN), np. com.android.healthconnect.phone.jd5bdd37e1a8d3667a05d0abebfc4a89e.

Wcześniej wbudowane kroki były przypisywane do nazwy pakietu android. Dane historyczne o krokach zarejestrowane przed czerwcem 2026 r. zachowają nazwę pakietu android.

Identyfikatory SPN są powiązane z konkretnym urządzeniem i zakresem poszczególnych aplikacji, aby chronić prywatność użytkowników:

  • Stabilny: SPN na obecnym urządzeniu jest stabilny w przypadku Twojej aplikacji.
  • Zakres aplikacji: różne aplikacje na tym samym urządzeniu widzą różne SPN w przypadku danych o krokach na urządzeniu.

Zapytanie o kroki na urządzeniu

Numery SPN są ograniczone do konkretnych urządzeń, więc nie możesz zakodować na stałe wartości SPN. Zamiast tego użyj interfejsu getCurrentDeviceDataSource() API, aby pobrać numer SPN dla bieżącego urządzenia.

Licznik kroków na urządzeniu wymaga rozszerzenia pakietu SDK w wersji 20 lub nowszej, natomiast interfejs getCurrentDeviceDataSource() API jest dostępny na Androidzie 14 (API na poziomie 34) z rozszerzeniem pakietu SDK w wersji 11 lub nowszej.

Interfejs getCurrentDeviceDataSource() API nie jest jeszcze dostępny w bibliotece Jetpack Health Connect. W poniższych przykładach użyto interfejsu API platformy 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

Jeśli aplikacja musi odczytywać dane o krokach na urządzeniu lub wyświetla dane o krokach podzielone według aplikacji lub urządzenia źródłowego, musisz wysyłać zapytania o rekordy, w których DataOrigin jest równe android lub pasuje do numeru SPN urządzenia. Jeśli Twoja aplikacja wyświetla atrybucję danych o krokach, użyj metadata.device, aby określić urządzenie źródłowe poszczególnych rekordów. W przypadku kroków na urządzeniu oznaczonych w zagregowanych danych identyfikatorem SPN możesz używać metadanych urządzenia, takich jak model lub manufacturerDeviceDataSource, do atrybucji albo używać ogólnej etykiety, np. „Twój telefon”, w przypadku kroków na urządzeniu.

Przykład poniżej pokazuje, jak odczytać zagregowane dane o liczbie kroków na urządzeniu, filtrując zarówno android, jak i bieżący SPN urządzenia:

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

Liczenie kroków na urządzeniu

  • Korzystanie z czujników: Health Connect korzysta z czujnika TYPE_STEP_COUNTER firmy SensorManager. Ten czujnik jest zoptymalizowany pod kątem niskiego zużycia energii, dzięki czemu idealnie nadaje się do ciągłego śledzenia kroków w tle.
  • Szczegółowość danych: aby oszczędzać baterię, dane o krokach są zwykle przesyłane w pakietach i zapisywane w bazie danych Health Connect nie częściej niż raz na minutę.
  • Atrybucja: kroki zarejestrowane przez tę funkcję przed czerwcem 2026 r. są przypisywane do nazwy pakietu androidDataOrigin. Po tej dacie są one przypisywane do numeru SPN konkretnego urządzenia. Zobacz Zmiana atrybucji w przypadku kroków na urządzeniu.
  • Aktywacja: mechanizm zliczania kroków na urządzeniu jest aktywny tylko wtedy, gdy co najmniej 1 aplikacja na urządzeniu ma przyznane w Health Connect uprawnienie READ_STEPS.

Sprawdzanie dostępności Health Connect

Zanim spróbujesz użyć Health Connect, sprawdź, czy jest on dostępny na urządzeniu użytkownika. Health Connect może nie być wstępnie zainstalowana na wszystkich urządzeniach lub może być wyłączona. Dostępność możesz sprawdzić za pomocą HealthConnectClient.getSdkStatus()metody.

Jak sprawdzić dostępność 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
}

W zależności od stanu zwróconego przez getSdkStatus() możesz w razie potrzeby poprosić użytkownika o zainstalowanie lub zaktualizowanie Health Connect ze Sklepu Google Play.

Wymagane uprawnienia

Dostęp do danych o krokach jest chroniony przez te uprawnienia:

  • android.permission.health.READ_STEPS
  • android.permission.health.WRITE_STEPS

Aby dodać do aplikacji funkcję zliczania kroków, zacznij od poproszenia o uprawnienia do typu danych Steps.

Aby móc zapisywać kroki, musisz zadeklarować to uprawnienie:

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

Aby odczytać kroki, musisz poprosić o te uprawnienia:

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

Prośba użytkownika o uprawnienia

Po utworzeniu instancji klienta aplikacja musi poprosić użytkownika o uprawnienia. Użytkownicy muszą mieć możliwość przyznania lub odmowy przyznania uprawnień w dowolnym momencie. Aby to zrobić, utwórz zestaw uprawnień dla wymaganych typów danych. Sprawdź, czy uprawnienia w zestawie są najpierw zadeklarowane w pliku manifestu Androida.

val permissions =
    setOf(
        HealthPermission.getReadPermission(StepsRecord::class),
        HealthPermission.getWritePermission(StepsRecord::class)
    )
Użyj getGrantedPermissions, aby sprawdzić, czy Twoja aplikacja ma już przyznane wymagane uprawnienia. Jeśli nie, użyj createRequestPermissionResultContract aby poprosić o te uprawnienia. Wyświetli się ekran uprawnień Health Connect.
val permissions = setOf(
        HealthPermission.getReadPermission(StepsRecord::class),
        HealthPermission.getWritePermission(StepsRecord::class),
        HealthPermission.getReadPermission(HeartRateRecord::class),
        HealthPermission.getWritePermission(HeartRateRecord::class)
    )

val requestPermissionsLauncher = rememberLauncherForActivityResult(
    contract = PermissionController.createRequestPermissionResultContract()
) { grantedPermissions ->
    if (grantedPermissions.containsAll(permissions)) {
        coroutineScope.launch { snackbarHostState.showSnackbar("Permissions granted!") }
    } else {
        coroutineScope.launch { snackbarHostState.showSnackbar("Permissions denied.") }
    }
}
Użytkownicy mogą w każdej chwili przyznać lub cofnąć uprawnienia, dlatego aplikacja musi sprawdzać uprawnienia za każdym razem przed ich użyciem i obsługiwać sytuacje, w których uprawnienia zostaną utracone.

Informacje zawarte w rekordzie kroków

Każdy element StepsRecord zawiera te informacje:

  • count: liczba kroków wykonanych w danym przedziale czasu, wyrażona jako Long.
  • startTime: czas rozpoczęcia przedziału pomiarowego.
  • endTime: czas zakończenia przedziału pomiarowego.
  • startZoneOffset: przesunięcie strefy czasowej dla czasu rozpoczęcia.
  • endZoneOffset: przesunięcie strefy czasowej dla czasu zakończenia.

Obsługiwane agregacje

Dla elementu StepsRecord dostępne są te wartości zagregowane:

Dla elementu StepsCadenceRecord dostępne są te wartości zagregowane:

Przykład użycia

W sekcjach poniżej dowiesz się, jak odczytywać i zapisywać dane StepsRecord.

Zapisywanie danych o krokach

Aplikacja może zapisywać dane o liczbie kroków, wstawiając instancje StepsRecord. Poniższy przykład pokazuje, jak zarejestrować 1000 kroków wykonanych przez użytkownika:

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

Odczytywanie danych zbiorczych

Najczęstszym sposobem odczytywania danych o krokach jest agregowanie łącznej liczby kroków w określonym przedziale czasu. Poniższy przykład pokazuje, jak odczytać łączną liczbę kroków użytkownika w określonym przedziale czasu:

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
}

Odczytywanie nieprzetworzonych danych

Poniższy przykład pokazuje, jak odczytać nieprzetworzone dane StepsRecord w okresie między godziną rozpoczęcia a godziną zakończenia:

val response = healthConnectClient.readRecords(
    ReadRecordsRequest(
        StepsRecord::class,
        timeRangeFilter = TimeRangeFilter.between(startTime, endTime)
    )
)
response.records.forEach { record ->
    /* Process records */
}