Lire des données brutes

L'exemple suivant vous montre comment lire des données brutes dans le cadre du workflow commun.

Lire des données

Santé Connect permet aux applications de lire les données du datastore lorsqu'elles sont au premier plan et en arrière-plan :

  • Lecture au premier plan : vous pouvez normalement lire les données de Santé Connect lorsque votre application est au premier plan. Dans ce cas, vous pouvez envisager d'utiliser un service de premier plan pour exécuter cette opération si l'utilisateur ou le système place votre application en arrière-plan lors d'une opération de lecture.

  • Lectures en arrière-plan : en demandant une autorisation supplémentaire à l'utilisateur, vous pouvez lire les données une fois que l'utilisateur ou le système a placé votre application en arrière-plan. Consultez l'exemple de lecture en arrière-plan complet.

Le type de données Pas dans Santé Connect enregistre le nombre de pas qu'un utilisateur a effectués entre deux lectures. Le nombre de pas est une unité de mesure courante pour les plates-formes de santé, de remise en forme et de bien-être. Santé Connect vous permet de lire et d'écrire des données sur le nombre de pas.

Pour lire des enregistrements, créez une ReadRecordsRequest et fournissez-la lorsque vous appelez readRecords.

L'exemple suivant montre comment lire le nombre de pas d'un utilisateur au cours d'une certaine période. Pour obtenir un exemple détaillé avec SensorManager, consultez le guide sur les données Nombre de pas.

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

Vous pouvez également lire des données agrégées à l'aide de aggregate.

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
}

Lire les étapes mobiles

Avec Android 14 (niveau d'API 34) et la version 20 ou ultérieure de SDK Extension, Santé Connect fournit un compteur de pas sur l'appareil. Si une application a reçu l'autorisation READ_STEPS, Santé Connect commence à enregistrer les pas effectués sur l'appareil Android. Les utilisateurs voient alors les données de pas ajoutées automatiquement aux entrées Pas de Santé Connect.

Pour vérifier si le comptage de pas sur l'appareil est disponible, assurez-vous que l'appareil exécute Android 14 (niveau d'API 34) et dispose au moins de la version 20 de l'extension SDK :

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

Si votre application lit le nombre de pas agrégé à l'aide de aggregate et ne filtre pas par DataOrigin, les pas enregistrés sur l'appareil sont automatiquement inclus dans le total. Aucune modification n'est requise pour la mise à jour de juin 2026.

Modification de l'attribution pour les pas effectués sur l'appareil

À partir de la mise à jour de juin 2026, les pas suivis de manière native par Santé Connect seront attribués à un nom de package synthétique (SPN), tel que com.android.healthconnect.phone.jd5bdd37e1a8d3667a05d0abebfc4a89e.

Auparavant, les étapes intégrées étaient attribuées au nom de package android. Les données historiques sur les pas enregistrées avant juin 2026 conservent le nom de package android.

Les SPN sont spécifiques à l'appareil et sont limités à chaque application pour protéger la confidentialité des utilisateurs :

  • Stable : le SPN de l'appareil actuel est stable pour votre application.
  • Portée de l'application : différentes applications sur le même appareil voient différents SPN pour les données de pas sur l'appareil.

Requête pour les étapes sur l'appareil

Étant donné que les SPN sont spécifiques à un appareil et à une portée, vous ne devez pas coder en dur les valeurs SPN. Utilisez plutôt l'API getCurrentDeviceDataSource() pour récupérer le SPN de l'appareil actuel.

Bien que le comptage de pas sur l'appareil nécessite la version 20 ou ultérieure de SDK Extension, l'API getCurrentDeviceDataSource() est disponible sur Android 14 (niveau d'API 34) avec la version 11 ou ultérieure de SDK Extension.

L'API getCurrentDeviceDataSource() n'est pas encore disponible dans la bibliothèque Jetpack Santé Connect. Les exemples suivants utilisent plutôt l'API du framework 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

Si votre application doit lire les pas effectués sur l'appareil ou afficher des données sur les pas ventilées par application ou appareil source, vous devez interroger les enregistrements où DataOrigin est android ou correspond au SPN de l'appareil. Si votre application affiche l'attribution des données de pas, utilisez metadata.device pour identifier l'appareil source des enregistrements individuels. Pour les étapes sur l'appareil identifiées par un SPN dans les données agrégées, vous pouvez utiliser des métadonnées d'appareil telles que model ou manufacturer à partir de DeviceDataSource pour l'attribution, ou utiliser un libellé générique tel que "Votre téléphone" pour les étapes sur l'appareil.

L'exemple suivant montre comment lire les données agrégées sur le nombre de pas sur l'appareil en filtrant à la fois android et le SPN de l'appareil actuel :

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

Comptage des pas sur l'appareil

  • Utilisation des capteurs : Santé Connect utilise le capteur TYPE_STEP_COUNTER de SensorManager. Ce capteur est optimisé pour une faible consommation d'énergie, ce qui le rend idéal pour le suivi continu des pas en arrière-plan.
  • Précision des données : pour préserver l'autonomie de la batterie, les données sur les pas sont généralement regroupées et écrites dans la base de données Santé Connect au maximum une fois par minute.
  • Attribution : les pas enregistrés par cette fonctionnalité avant juin 2026 sont attribués au nom de package android dans DataOrigin. Après cette date, elles sont attribuées à un SPN spécifique à l'appareil. Consultez Modification de l'attribution pour les étapes sur l'appareil.
  • Activation : le mécanisme de comptage des pas sur l'appareil n'est actif que lorsqu'au moins une application sur l'appareil a reçu l'autorisation READ_STEPS dans Santé Connect.

Exemple de lecture en arrière-plan

Pour lire les données en arrière-plan, déclarez l'autorisation suivante dans votre fichier manifeste :

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

L'exemple suivant montre comment lire le nombre de pas d'un utilisateur en arrière-plan au cours d'une certaine période à l'aide de WorkManager :

class ScheduleWorker(appContext: Context, workerParams: WorkerParameters) :
    CoroutineWorker(appContext, workerParams) {

    override suspend fun doWork(): Result {
        val healthConnectClient = HealthConnectClient.getOrCreate(applicationContext)
        // Perform background read logic here
        return Result.success()
    }
}
@OptIn(ExperimentalFeatureAvailabilityApi::class)
fun enqueueBackgroundReadWorker(context: Context, healthConnectClient: HealthConnectClient) {
    if (healthConnectClient
            .features
            .getFeatureStatus(
                HealthConnectFeatures.FEATURE_READ_HEALTH_DATA_IN_BACKGROUND
            ) == HealthConnectFeatures.FEATURE_STATUS_AVAILABLE
    ) {

        val periodicWorkRequest = PeriodicWorkRequestBuilder<ScheduleWorker>(1, TimeUnit.HOURS)
            .build()

        WorkManager.getInstance(context).enqueueUniquePeriodicWork(
            "read_health_connect",
            ExistingPeriodicWorkPolicy.KEEP,
            periodicWorkRequest
        )
    }
}

Le paramètre ReadRecordsRequest a une valeur par défaut pageSize de 1 000. Si le nombre d'enregistrements dans un seul readResponse dépasse le pageSize de la requête, vous devez parcourir toutes les pages de la réponse pour récupérer tous les enregistrements à l'aide de pageToken. Toutefois, veillez à ne pas dépasser les limites de débit.

Exemple de lecture de pageToken

Nous vous recommandons d'utiliser pageToken pour lire les enregistrements et récupérer toutes les données disponibles pour la période demandée.

L'exemple suivant montre comment lire tous les enregistrements jusqu'à ce que tous les jetons de page aient été épuisés :

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
}
Pour en savoir plus sur les bonnes pratiques à suivre lors de la lecture d'ensembles de données volumineux, consultez Planifier pour éviter la limitation du débit.

Lire les données déjà écrites

Si une application a déjà écrit des enregistrements sur Santé Connect, elle peut lire les données historiques. Cela s'applique aux scénarios dans lesquels l'application doit se resynchroniser avec Santé Connect après que l'utilisateur l'a réinstallée.

Certaines restrictions de lecture s'appliquent :

  • Pour Android 14 ou version ultérieure

    • Aucune limite historique pour une application qui lit ses propres données.
    • Une limite de 30 jours s'applique à la lecture d'autres données par une application.
  • Pour Android 13 et versions antérieures

    • Limite de 30 jours pour la lecture des données par les applications.

Pour supprimer les restrictions, vous pouvez demander une autorisation de lecture.

Pour lire les données historiques, vous devez indiquer le nom du package en tant qu'objet DataOrigin dans le paramètre dataOriginFilter de votre ReadRecordsRequest.

L'exemple suivant montre comment indiquer un nom de package lors de la lecture des enregistrements de fréquence cardiaque :

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
}

Lire les données datant de plus de 30 jours

Par défaut, toutes les applications peuvent lire les données de Santé Connect remontant jusqu'à 30 jours avant la date d'octroi de la première autorisation.

Si vous devez étendre les autorisations de lecture au-delà des restrictions par défaut, demandez le PERMISSION_READ_HEALTH_DATA_HISTORY. Sinon, sans cette autorisation, toute tentative de lecture d'enregistrements datant de plus de 30 jours génère une erreur.

Historique des autorisations pour une application supprimée

Si un utilisateur supprime votre application, toutes les autorisations, y compris l'autorisation d'historique, sont révoquées. Si l'utilisateur réinstalle votre application et accorde de nouveau l'autorisation, les mêmes restrictions par défaut s'appliquent, et votre application peut lire les données de Santé Connect remontant jusqu'à 30 jours avant cette nouvelle date.

Par exemple, supposons que l'utilisateur supprime votre application le 10 mai 2023, puis la réinstalle le 15 mai 2023 et accorde des autorisations de lecture. Par défaut, votre application pourra donc lire les données remontant au 15 avril 2023.

Gérer les exceptions

Santé Connect génère des exceptions standards pour les opérations CRUD en cas de problème. Votre application doit détecter et gérer chacune de ces exceptions de manière appropriée.

Chaque méthode sur HealthConnectClient indique les exceptions qui peuvent être levées. En général, votre application doit gérer les exceptions suivantes :

Tableau 1 : Exceptions Santé Connect et bonnes pratiques recommandées
Exception Description Bonne pratique recommandée
IllegalStateException L'un des scénarios suivants s'est produit :

  • Le service Santé Connect n'est pas disponible.
  • La requête n'est pas une construction valide (par exemple, une requête globale dans des buckets périodiques où un objet Instant est utilisé pour timeRangeFilter).

Traitez d'abord les problèmes potentiels liés aux entrées avant d'effectuer une requête. De préférence, attribuez des valeurs aux variables ou utilisez-les comme paramètres dans une fonction personnalisée plutôt que de les utiliser directement dans vos requêtes afin de pouvoir appliquer des stratégies de gestion des erreurs.
IOException Des problèmes surviennent lors de la lecture et de l'écriture des données sur le disque. Pour éviter cela, voici quelques suggestions :

  • Sauvegardez les entrées utilisateur.
  • Soyez prêt à gérer les problèmes qui surviennent lors des opérations d'écriture groupée. Par exemple, assurez-vous que le processus ne reste pas bloqué par le problème et qu'il poursuit les opérations restantes.
  • Appliquez des stratégies spécifiques aux nouvelles tentatives et aux intervalles entre les tentatives pour gérer les problèmes de requête.

RemoteException Des erreurs se sont produites au sein du service sous-jacent auquel le SDK se connecte, ou lors de sa communication avec celui-ci.

(par exemple, votre application tente de supprimer un enregistrement associé à un uid donné). Toutefois, l'exception est générée lorsque l'application découvre que l'enregistrement n'existe pas après avoir vérifié le service sous-jacent.
Pour éviter cela, voici quelques suggestions :

  • Effectuez des synchronisations régulières entre le datastore de votre application et Santé Connect.
  • Appliquez des stratégies spécifiques aux nouvelles tentatives et aux intervalles entre les tentatives pour gérer les problèmes de requête.

SecurityException Des problèmes surviennent lorsque les requêtes nécessitent des autorisations qui ne sont pas accordées. Pour éviter cela, assurez-vous d'avoir déclaré l'utilisation des types de données Santé Connect pour l'application que vous avez publiée. Vous devez également déclarer les autorisations Santé Connect dans le fichier manifeste et dans votre activité.