Schritte zählen

Health Connect bietet den Datentyp Schritte zum Aufzeichnen von Schrittzahlen mit dem StepsRecord. Schritte sind ein grundlegender Messwert beim Gesundheits- und Fitnesstracking.

Schritte auf dem Smartphone lesen

Mit Android 14 (API-Level 34) und SDK-Erweiterung Version 20 oder höher bietet Health Connect eine Schrittzählung auf dem Gerät. Wenn einer App die Berechtigung READ_STEPS erteilt wurde, beginnt Health Connect mit der Erfassung von Schritten auf dem Android-Gerät. Nutzer sehen dann automatisch hinzugefügte Schrittdaten in den Health Connect-Einträgen unter Schritte.

So prüfen Sie, ob die Schrittzählung auf dem Gerät verfügbar ist: Das Gerät muss Android 14 (API-Level 34) ausführen und mindestens SDK-Erweiterungsversion 20 haben:

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

Wenn Ihre App aggregierte Schrittzahlen mit aggregate liest und nicht nach DataOrigin filtert, werden die Schritte auf dem Gerät automatisch in die Gesamtzahl einbezogen. Für das Update im Juni 2026 sind keine Änderungen erforderlich.

Änderung der Attribution für Schritte auf dem Gerät

Ab dem Update im Juni 2026 werden Schritte, die nativ von Health Connect erfasst werden, einem synthetischen Paketnamen (SPN) wie com.android.healthconnect.phone.jd5bdd37e1a8d3667a05d0abebfc4a89e zugeordnet.

Bisher wurden integrierte Schritte dem Paketnamen android zugeordnet. Bei Verlaufsdaten zu Schritten, die vor Juni 2026 aufgezeichnet wurden, wird der Paketname android beibehalten.

SPNs sind gerätespezifisch und werden zum Schutz des Datenschutzes für Nutzer pro Anwendung festgelegt:

  • Stabil:Der SPN für das aktuelle Gerät ist für Ihre Anwendung stabil.
  • Anwendungsspezifisch:Verschiedene Anwendungen auf demselben Gerät sehen unterschiedliche SPNs für Schrittdaten auf dem Gerät.

Schritte auf dem Gerät abfragen

Da SPNs bereichsbezogen und gerätespezifisch sind, dürfen Sie SPN-Werte nicht fest codieren. Verwenden Sie stattdessen die getCurrentDeviceDataSource API, um den SPN für das aktuelle Gerät abzurufen.

Die Schrittzählung auf dem Gerät erfordert SDK-Erweiterung Version 20 oder höher. Die getCurrentDeviceDataSource() API ist unter Android 14 (API-Level 34) mit SDK-Erweiterung Version 22 oder höher verfügbar. Wenn Sie diese API verwenden möchten, legen Sie in der Datei build.gradle.kts oder build.gradle auf Modulebene für compileSdkExtension den Wert 22 oder höher fest:

Kotlin

android {
    compileSdk = 35
    compileSdkExtension = 22
}

Groovy

android {
    compileSdk 35
    compileSdkExtension 22
}

Die getCurrentDeviceDataSource() API ist noch nicht in der Health Connect Jetpack-Bibliothek verfügbar. In den folgenden Beispielen wird die Android-Framework-API verwendet, für die ein Executor- und ein OutcomeReceiver-Callback erforderlich sind:

import android.content.Context
import android.health.connect.DeviceDataSource
import android.health.connect.HealthConnectException
import android.health.connect.HealthConnectManager
import android.os.OutcomeReceiver

val healthConnectManager = context.getSystemService(HealthConnectManager::class.java)
healthConnectManager?.getCurrentDeviceDataSource(
    context.mainExecutor,
    object : OutcomeReceiver<DeviceDataSource, HealthConnectException> {
        override fun onResult(result: DeviceDataSource) {
            val currentDeviceSpn = result.deviceDataOrigin.packageName
        }

        override fun onError(error: HealthConnectException) {
            // Handle error
        }
    }
)

Wenn Ihre App Schritte auf dem Gerät lesen muss oder Schrittdaten nach Quellanwendung oder Gerät aufgeschlüsselt angezeigt werden, müssen Sie Datensätze abfragen, bei denen DataOrigin android oder mit dem SPN des Geräts übereinstimmt. Wenn in Ihrer App die Quellenangabe für Schrittdaten angezeigt wird, verwenden Sie metadata.device, um das Quellgerät für einzelne Datensätze zu identifizieren. Für On-Device-Schritte, die in aggregierten Daten durch einen SPN identifiziert werden, können Sie Gerätemetadaten wie model oder manufacturer aus DeviceDataSource für die Zuordnung verwenden oder ein generisches Label wie „Ihr Smartphone“ für On-Device-Schritte.

Das folgende Beispiel zeigt, wie aggregierte Schrittzahldaten auf dem Gerät gelesen werden. Dazu wird sowohl nach android als auch nach dem SPN des aktuellen Geräts gefiltert:

import android.content.Context
import android.health.connect.DeviceDataSource
import android.health.connect.HealthConnectException
import android.health.connect.HealthConnectManager
import android.os.Build
import android.os.OutcomeReceiver
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
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
import kotlinx.coroutines.suspendCancellableCoroutine

suspend fun readDeviceStepsByTimeRange(
    healthConnectClient: HealthConnectClient,
    context: Context,
    startTime: Instant,
    endTime: Instant
) {
    // 1. Check if SDK Extension 22+ is available for getCurrentDeviceDataSource()
    val isDataSourceApiAvailable =
        Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE &&
            SdkExtensions.getExtensionVersion(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) >= 22

    try {
        val healthConnectManager = context.getSystemService(HealthConnectManager::class.java)

        // 2. Safely fetch the package name only if the API is available
        val currentDeviceSpn = if (isDataSourceApiAvailable && healthConnectManager != null) {
            suspendCancellableCoroutine { continuation ->
                healthConnectManager.getCurrentDeviceDataSource(
                    context.mainExecutor,
                    object : OutcomeReceiver<DeviceDataSource, HealthConnectException> {
                        override fun onResult(result: DeviceDataSource) {
                            continuation.resume(result.deviceDataOrigin.packageName)
                        }

                        override fun onError(error: HealthConnectException) {
                            continuation.resumeWithException(error)
                        }
                    }
                )
            }
        } 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.
    }
}

On-Device-Schrittzählung

  • Sensornutzung: Health Connect verwendet den Sensor TYPE_STEP_COUNTER von SensorManager. Dieser Sensor ist für einen geringen Stromverbrauch optimiert und eignet sich daher ideal für die kontinuierliche Schrittzählung im Hintergrund.
  • Detaillierungsgrad der Daten: Um den Akku zu schonen, werden Schrittdaten in der Regel gebündelt und höchstens einmal pro Minute in die Health Connect-Datenbank geschrieben.
  • Attribution: Schritte, die vor Juni 2026 mit dieser Funktion aufgezeichnet wurden, werden in der DataOrigin dem Paketnamen android zugeordnet. Danach werden sie einem gerätespezifischen SPN zugeordnet. Weitere Informationen finden Sie unter Änderung der Zuordnung für Schritte auf dem Gerät.
  • Aktivierung: Der Mechanismus zur Schrittzählung auf dem Gerät ist nur aktiv, wenn mindestens einer App auf dem Gerät die Berechtigung READ_STEPS in Health Connect erteilt wurde.

Verfügbarkeit von Health Connect prüfen

Bevor Ihre App versucht, Health Connect zu verwenden, sollte sie prüfen, ob Health Connect auf dem Gerät des Nutzers verfügbar ist. Health Connect ist möglicherweise nicht auf allen Geräten vorinstalliert oder deaktiviert. Sie können die Verfügbarkeit mit der HealthConnectClient.getSdkStatus()-Methode prüfen.

Verfügbarkeit von Health Connect prüfen

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
}

Je nach dem von getSdkStatus() zurückgegebenen Status kannst du den Nutzer bei Bedarf anleiten, Health Connect aus dem Google Play Store zu installieren oder zu aktualisieren.

Erforderliche Berechtigungen

Der Zugriff auf Schritte wird durch die folgenden Berechtigungen geschützt:

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

Wenn Sie Ihrer App die Möglichkeit zum Erfassen von Schritten hinzufügen möchten, müssen Sie zuerst Berechtigungen für den Datentyp Steps anfordern.

Hier ist die Berechtigung, die Sie deklarieren müssen, um Schritte schreiben zu können:

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

Wenn Sie Schritte lesen möchten, müssen Sie die folgenden Berechtigungen anfordern:

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

Berechtigungen vom Nutzer anfordern

Nachdem Sie eine Client-Instanz erstellt haben, muss Ihre App Berechtigungen vom Nutzer anfordern. Nutzer müssen jederzeit die Möglichkeit haben, Berechtigungen zu erteilen oder zu verweigern. Erstellen Sie dazu eine Reihe von Berechtigungen für die erforderlichen Datentypen. Achten Sie darauf, dass die Berechtigungen im Set zuerst in Ihrem Android-Manifest deklariert werden.

val permissions =
    setOf(
        HealthPermission.getReadPermission(StepsRecord::class),
        HealthPermission.getWritePermission(StepsRecord::class)
    )
Mit getGrantedPermissions können Sie prüfen, ob Ihrer App bereits die erforderlichen Berechtigungen erteilt wurden. Falls nicht, verwenden Sie createRequestPermissionResultContract, um diese Berechtigungen anzufordern. Der Bildschirm mit den Health Connect-Berechtigungen wird angezeigt.
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.") }
    }
}
Da Nutzer Berechtigungen jederzeit erteilen oder widerrufen können, muss Ihre App jedes Mal prüfen, ob die Berechtigungen vorhanden sind, bevor sie verwendet werden. Außerdem muss sie Szenarien berücksichtigen, in denen Berechtigungen verloren gehen.

In einem Schrittdatensatz enthaltene Informationen

Jede StepsRecord enthält die folgenden Informationen:

  • count: Die Anzahl der Schritte, die im Zeitintervall zurückgelegt wurden, als Long.
  • startTime: Der Beginn des Messzeitraums.
  • endTime: Die Endzeit des Messzeitraums.
  • startZoneOffset: Die Zonenabweichung für den Beginn.
  • endZoneOffset: Die Zeitzonenabweichung für die Endzeit.

Unterstützte Aggregationen

Für StepsRecord sind die folgenden aggregierten Werte verfügbar:

Für StepsCadenceRecord sind die folgenden aggregierten Werte verfügbar:

Nutzungsbeispiel

In den folgenden Abschnitten wird beschrieben, wie StepsRecord-Daten gelesen und geschrieben werden.

Schrittdaten schreiben

Ihre App kann Schrittzahldaten schreiben, indem sie StepsRecord-Instanzen einfügt. Im folgenden Beispiel wird gezeigt, wie 1.000 Schritte eines Nutzers aufgezeichnet werden:

val zoneOffset = ZoneOffset.systemDefault().rules.getOffset(startTime)
val stepsRecord = StepsRecord(
    count = 120,
    startTime = startTime,
    endTime = endTime,
    startZoneOffset = zoneOffset,
    endZoneOffset = zoneOffset,
    metadata = Metadata.autoRecorded(
        device = Device(type = Device.TYPE_WATCH)
    )
)
healthConnectClient.insertRecords(listOf(stepsRecord))

Aggregierte Daten lesen

Die gängigste Methode zum Lesen von Schrittdaten besteht darin, die Gesamtzahl der Schritte über einen Zeitraum hinweg zu aggregieren. Im folgenden Beispiel wird gezeigt, wie die Gesamtzahl der Schritte für einen Nutzer in einem bestimmten Zeitraum gelesen wird:

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
}

Rohdaten lesen

Im folgenden Beispiel wird gezeigt, wie Rohdaten für StepsRecord zwischen einem Start- und einem Endzeitpunkt gelesen werden:

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