Bonne année et ... bonne santé avec Google Fit !

le 02/01/2018 par Paul Bancarel
Tags: Software Engineering

Suite au développement d'une application sportive et à une conférence en interne. Je me suis rendu compte que les APIs Google Fit étaient très largement méconnues de la communauté des développeurs. Que peut-on faire avec Google Fit ? À quoi ça sert ? Est-ce vraiment utile ? Autant d'interrogations qui trouvent leurs réponses dans cet article. Avec Google Fit, Google propose un “Fitness Store” afin d’héberger et de centraliser toutes les données liées à la santé. Le but étant de créer une sorte de standard afin de pouvoir échanger des données facilement entre applications.  Il permet ainsi de stocker tout type de données liées à l’activité physique, l’alimentation ainsi qu’à certaines données médicales. Google Fit est accessible sur Android mais aussi directement depuis le web c’est pourquoi Google met à disposition deux jeux d’APIs: REST et Android.

Cet article ce concentrera sur celles d'Android celles destinées au web restent tout aussi complètes.

1. API & Permissions

1.1 Une histoire de famille

Google Fit est accessible via sept familles d’APIs comme l’illustre la Figure 1:

FIGURE 1: Google Fit APIs

  • **HistoryApi** : Permet de manipuler des données du “Fitness Store”(ex: insertions, suppressions, mises à jour). [Voir 3.1, 3.2].
  • **RecordingApi** : Permet de s’abonner à un type de donnée (ex: le nombre de pas de l’utilisateur) afin d’être prévenu en cas de changement.
  • **SensorApi** : Permet de lire les données brutes d’un capteur.
  • **SessionApi** : Permet de manipuler des sessions [Voir 3.3, 3.4].
  • **BLE Api** : Permet de communiquer avec des wearable devices et autres appareils bluetooth. Vous pourrez ensuite vous rediriger vers SensorApi pour collecter des données.
  • **ConfigApi** : Permet de créer des data types personnalisés [Voir 2.2].
  • **GoalsApi** : Permet d’accéder aux objectifs de votre utilisateur ainsi qu’à son taux d’achèvement. Il existe trois types d’objectifs durée, distance, nombre de calories.

1.2 Demander l’autorisation !

Google Fit manipule des données sensibles,  ainsi avant de pouvoir pleinement exploiter les APIs il est nécessaire d’en demander l’autorisation à l’utilisateur.

Pour cela il faudra passer par un GoogleApiClient auquel on précise les APIs que l’on souhaite exploiter ainsi que leurs scopes (droits)  associés.

Voir le lien github

ce qui devrait résulter en un dialog comme suit que l’utilisateur devra accepter:

FIGURE 2: Exemple d’autorisations

On remarque que l’utilisateur ne peut pas priver l’accès à certains types de données comme c’est par exemple le cas pour les permissions d’applications. Ici il doit autoriser l’accès à toutes ses données “Fitness” sans exception. Apple HealthKit permet par exemple de restreindre l’accès à certains types de données (âge, sexe, etc) tout en acceptant les autres.

2 - Un peu de théorie

2.1 - Les objets

Au sein de Google Fit que vous vouliez insérer de la nourriture, des exercices physiques ou autres vous utiliserez les six objets suivant:

  • DataType
  • DataSource
  • DataPoint
  • DataSet
  • Session

FIGURE 3: Structure des objets

2.2 DataType & DataSource

Un datatype est généralement utilisé à la construction d’une datasource.

Voir le lien github

Google Fit vous fournit bon nombre de datatype par défaut afin de créer vos datasources et d’enrichir le “Fitness Store” de l’utilisateur. Ils sont regroupés  en 5 catégories. Les données liées à une activité sportive (Activity), les données liées à une position (Location), les données liées à un état physique (Body) et enfin les données liées à l’alimentation (Nutrition). Nous les listons dans le tableau suivant:

DatatypePermission ScopeFieldsAssociated value
com.google.activity.samplesActivityactivity (int—enum)<br><br>confidence (float—percent)TYPE_ACTIVITY_SAMPLES
com.google.activity.segmentActivityactivity (int—enum)TYPE_ACTIVITY_SEGMENT
com.google.calories.bmrXcalories (float—kcal)TYPE_BASAL_METABOLIC_RATE
com.google.body.fat.percentageXbody_mass (float—percent)TYPE_BODY_FAT_PERCENTAGE
com.google.calories.expendedActivitycalories (float—kcal)TYPE_CALORIES_EXPENDED
com.google.cycling.pedaling.cadenceActivityrpm (float—rpm)TYPE_CYCLING_PEDALING_CADENCE
com.google.cycling.pedaling.cumulativeXrpm (float—rpm)TYPE_CYCLING_PEDALING_CUMULATIVE
com.google.cycling.wheel_revolution.rpmLocationrpm (float—rpm)TYPE_CYCLING_WHEEL_REVOLUTION
com.google.cycling.wheel.revolutionsXrpm (float—rpm)TYPE_CYCLING_WHEEL_RPM
com.google.distance.deltaLocationdistance (float—meters)TYPE_DISTANCE_DELTA
com.google.heart_rate.bpmBodybpm (float—bpm)TYPE_HEART_RATE_BPM
com.google.heightBodyheight (float—meters)TYPE_HEIGHT
com.google.location.sampleLocationlatitude (float—degrees)<br><br>longitude (float—degrees)<br><br>accuracy (float—meters)<br><br>altitude (float—meters)TYPE_LOCATION_SAMPLE
com.google.location.trackXlatitude (float—degrees)<br><br>longitude (float—degrees)<br><br>accuracy (float—meters)<br><br>altitude (float—meters)TYPE_LOCATION_TRACK<br><br>(The difference between the two data types is that, while location.sample data points have an exact timestamp, location.track data points have an inexact time interval)
com.google.nutritionNutritionnutrients (Map<String, float>—calories/grams/IU) meal_type (int—enum)<br><br>food_item (String—n/a)TYPE_NUTRITION
com.google.hydrationNutritionfield_volume(float-liters)TYPE_HYDRATION
com.google.power.sampleActivitywatts (float—watts)TYPE_POWER_SAMPLE
com.google.speedLocationspeed (float—m/s)TYPE_SPEED
com.google.step_count.cadenceActivityrpm (float—steps/min)TYPE_STEP_COUNT_CADENCE
com.google.step_count.deltaActivitysteps (int—count)TYPE_STEP_COUNT_DELTA
com.google.weightBodyweight (float—kg)TYPE_WEIGHT
com.google.activity.exerciseActivityexercise (int—enum)<br><br>repetitions (int—count)<br><br>resistance type (int—enum)<br><br>resistance (float—kg)<br><br>duration (int—milliseconds)TYPE_WORKOUT_EXERCISE

X: No reference in scopes array

TABLE 1:DataType par défaut

Cependant certains types, nommés HealthDataType, vous seront interdits avant de vous être inscrits auprès de Google (vous pouvez en faire la demande à cette adresse google-fit-restricted@google.com). Ces données sont considérées comme trop sensibles pour y avoir accès par défaut.

De plus si vous utilisez un appareil annexe pour collecter ce type de données vous devrez renseigner le modèle de l’appareil, les protocoles qu’ils respectent (ex: ISO15197) et les données que vous comptez collecter avec auprès de Google.

Ci-dessous la liste des données considérées sensibles:

DatatypeFields
com.google.body.temperature.basalbody_temperature_measurement_location (int—enum)<br><br>body_temperature (float-celsius)
com.google.blood_glucoseblood_glucose_level(float-mmol/L)<br><br>temporal_relation_to_meal(int-enum)<br><br>meal_type(int-enum)<br><br>temporal_relation_to_sleep(int-enum)<br><br>blood_glucose_specimen_source(int-enum)
com.google.blood_pressureblood_pressure_systolic(float-mmHg)<br><br>blood_pressure_diastolic(float-mmHg)<br><br>body_position(int-enum)<br><br>blood_pressure_measurement_location(int-enum)
com.google.body.temperaturebody_temperature(float-celsius)<br><br>body_temperature_measurement_location(int-enum)
com.google.cervical_mucuscervical_mucus_texture(int-enum)<br><br>cervical_mucus_amount(int-enum)
com.google.cervical_positioncervical_position(int-enum)<br><br>cervical_dilation(int-enum)<br><br>cervical_firmness(int-enum)
com.google.menstruationmenstrual_flow(int-enum)
com.google.ovulation_testovulation_test_result(int-enum)
com.google.oxygen_saturationoxygen_saturation(float-percent)<br><br>supplemental_oxygen_flow_rate(float-L/min))<br><br>oxygen_therapy_administration_mode(int-enum)<br><br>oxygen_saturation_system(int-enum)<br><br>oxygen_saturation_measurement_method(int-enum)
com.google.vaginal_spottingfield_occurrences(int-enum)

Because health data is potentially sensitive, Google Fit restricts write access for the data types in HealthDataTypes to only certain developers.

TABLE 2: HealthDataType

Si malgré tout aucunes de ces données ne vous conviennent, Google vous donne la possibilité de créer la vôtre et de lui donner une visibilité public, private, shareable, restricted. C’est le cas de Nike et Adidas qui ont tous deux créé leur propre type de donnée.

2.3 Dataset & DataPoint

Un dataset quant à lui est toujours instancié à l’aide d’une datasource. Le dataset contient plusieurs datapoints qui représentent une donnée brute à un instant t. Prenons un exemple, afin d’éclaircir notre discours:

Camille décide de faire un jogging d’une heure le dimanche matin. Reprenant le sport depuis peu elle n’arrive pas à terminer son jogging entièrement. Elle a couru les 30 premières minutes puis a marché 10 minutes afin de se reposer et a repris la fin de sa course pendant les 20 minutes restantes.

Essayons maintenant de traduire cette activité physique avec les objets que nous avons décrits précédemment. Tout d’abord il faut choisir ce que l’on souhaite enregistrer dans le “Fitness Store”. En se référant au tableau 1 en 2.2, nous décidons d’enregistrer la vitesse de Camille ainsi que l’activité qu’elle a pratiqué. On construit un premier dataset instancié à partir d’une datasource de datatype ACTIVITY_SEGMENT (toujours en se référant au tableau en 2.2 colonne 4).

Voir le lien github

Ensuite on insère trois datapoints correspondants aux trois phases du jogging de Camille (course puis marche puis course). Attention puisque l’on a choisi une datasource ACTIVITY_SEGMENT, les champs des datapoints doivent correspondre à ceux du tableau 1 en 2.2 suivant le datatype que l’on a sélectionné. Ici ce sera le FIELD_ACTIVITY comme l'indique la colonne 3.

Voir le lien github

De la même manière on peut crée un deuxième dataset à partir d’une datasource de datatype TYPE_SPEED nous obligeant à insérer des trois datapoints avec les champs FIELD_SPEED cette fois-ci.

La Figure 4 se propose de résumer cet exemple graphiquement:

FIGURE 4: Exemple d’une session de running

On remarque qu’en choisissant une datasource on établit en quelque sorte un contrat nous engageant à fournir des datapoints possédants les champs correspondants au datatype de la datasource (voir tableau en 2.2). On peut donc dire qu’un dataset regroupe plusieurs datapoints de même “type”. C’est pourquoi il existe des sessions qui elles vont regrouper plusieurs datasets qui pourront être de types différents.

Pour terminer l’insertion on utilise HistoryAPI:

Voir le lien github

3. Play with data

Dans l’exemple précédent nous avons insérer des données sportives mais le scénario est identique pour insérer des aliments ou des données liées à la santé (sommeil, taille, poids, …). Il faut retenir que le datatype décrit la structure des datapoints que vous devrez compléter.

Pour insérer une donnée il faut donc une datasource qui précise le package name car une application ne peut accéder qu’aux données qu’elle a elle même inséré dans le "Fitness Store" (cas particulier du nombre de pas avec RecordingApi et des objectifs avec GoalsApi). Noter que pour insérer un datapoint vous devez obligatoirement renseigner tous les champs du DataType que vous avez sélectionné.

3.2 Read Data

Pour lire les données du jogging de Camille on utilise la requête suivante:

Voir le lien github

Pour supprimer ou mettre à jour des données, le principe reste le même mais il vous faudra utiliser les objets DataDeleteRequest et DataUpdateRequest.

Voir le lien github

A Retenir:

  • Tous les champs du datapoint doivent être remplis
  • Utilisez HistoryApi.updateData si vous insérez deux datapoints qui se chevauchent sinon la requête d’insertion sera ignorée.
  • Vous ne pouvez pas modifier de données insérées par une autre application.
  • Vous ne pouvez pas supprimer de données insérées par une autre application.
  • Requêtes limitées à 1000 DataPoints
  • Les données peuvent ensuite être englobés en sessions.

3.3 Insert Session

Comme nous l’évoquions précédemment il est possible de créer des sessions, il nous faut utiliser SessionApi.

Actuellement Google propose 124 activités sportives pour vos sessions.

FIGURE 5: Fitness activities available on Google Fit

Les sessions représentent un regroupement de dataset pour l’exemple de Camille la session serait de type RUNNING. Même si elle a marché, initialement cela reste une session de Jogging pour elle. Attention donc à ne pas confondre l’activité que l’on affecte à un datapoint et à une session.

Plus concrètement, vous avez deux manières d’insérer une session, soit directement via une insertion manuelle.

Voir le lien github

Soit en lançant un enregistrement.

Voir le lien github

En lançant un enregistrement Google Fit collecte lui même les datapoints et les insère dans le “Fitness Store”. Pratique !

3.4 Read Session

Voir le lien github

Une chose également appréciable avec les API Google Fit est que Google estime automatiquement les calories dépensées de l’utilisateur en fonction de l’activité physique pratiquée si vous ne les renseignez pas.

Conclusion

Google Fit fournit une plateforme complète qui permet de regrouper données sportives, données de santé et données alimentaires au même endroit afin d’offrir à l’utilisateur un environnement centralisé et cohérent afin qu’il bénéficie d’une meilleure expérience.

Cependant Google averti que l’utilisation de Google Fit doit être clair pour l’utilisateur donc toujours explicité, il avertit également que Google Fit ne doit pas être utilisé à des fins commerciales ou pour des données autres que celles citées précédemment. Enfin si les datatypes fournit par la plateforme ne vous conviennent pas il vous est toujours possible de créer la votre. Pour rappel c'est le cas de Nike et d'Adidas.

Au fil du temps Google Fit ne cesse de s'améliorer et permet maintenant de :

  • Reconnaitre automatiquement le début d'une activité
  • Notifier quand certaines données arrivent dans le "Fitness store" permettant ainsi de créer des expériences utilisateurs cohérentes (ie: Encourager l'utilisateur à faire une activité après un repas trop calorique, Encourager l'utilisateur à boire après un long entraînement, ...)
  • Augmenter la fédération des utilisateurs envers votre application: J'entends ici qu'en tant que sportif je préfère toujours une application qui sera compatible Google Fit et qui pourra enrichir mon écosystème existant qu'une application isolée.

Ces APIs gagnent à être connues et leurs intégration au sein d'Android Wear ouvrent de belles perspectives.

Sources

https://developers.google.com/fit/android/

https://www.youtube.com/watch?v=tP8yKNXXGmQ

table, th, td { font-size: 70%; } .caption { color: #767676; font-size: 12px; font-style: italic; margin-bottom:25px; }