Google Health API עוקב אחרי סשנים של אימונים והיסטוריית האימונים של המשתמשים באמצעות סוג נתוני הסשן exercise. הסשן פועל כקונטיינר שמאגד מטא-נתונים של פעילות, אירועי השהיה והמשך, הקפות או פיצולים ומדדי סיכום.
כדי לספק למשתמשים את חוויית השימוש הטובה ביותר, חשוב להבין איך לקרוא, לכתוב ולבנות אימונים באפליקציה.
סוגי נתונים נתמכים
ה-API תומך בסוג הנתונים הבא למעקב אחרי אימונים וסשנים של פעילות:
| סוג הנתונים | פעולות אפשריות |
היקף |
|---|---|---|
|
פעילות גופנית
dataType:
exercisefilter parameter: exercise
סוג הרשומה: סשן
מכשירים תואמים
|
list, get, reconcile, create, update, batchDelete | .activity_and_fitness.readonly.activity_and_fitness.writeonly |
סוגים קשורים של נתוני טלמטריה
בסשנים של אימונים, סוג הנתונים exercise משמש כמאגר, אבל מכשירים לבישים מתעדים גם נתוני טלמטריה מפורטים בתדירות גבוהה במהלך הסשן. ב-Google Health API, סוגי הנתונים המפורטים האלה של טלמטריה במהלך היום הם לקריאה בלבד, ואי אפשר ליצור או לשנות אותם ישירות דרך נקודות הקצה (endpoints) שלהם ב-REST.
כשכותבים אימון באמצעות ה-API בארכיטקטורת REST, מעבירים מדדי אימון מצטברים בתוך האובייקט metricsSummary של הנקודה על הגרף exercise.
בטבלה הבאה מופיע מיפוי של שדות הסיכום ב-exercise.metricsSummary לסוגי הנתונים המתאימים של טלמטריה במהלך היום לקריאה בלבד, שאפשר לשלוח לגביהם שאילתות לחלון הזמן של האימון:
שדה סיכום (metricsSummary) |
שם סוג הנתונים של הטלמטריה במהלך היום | מזהה סוג הנתונים של נתוני הטלמטריה של ה-API (לקריאה בלבד) | שדה סינון (?filter=) |
היקף הרשאות הקריאה הנדרש של OAuth |
|---|---|---|---|---|
caloriesKcal |
אנרגיה שנשרפה בזמן פעילות | active-energy-burned |
active_energy_burned.interval.start_time |
activity_and_fitness.readonly |
distanceMillimeters |
מרחק | distance |
distance.interval.start_time |
activity_and_fitness.readonly |
steps |
שלבים | steps |
steps.interval.start_time |
activity_and_fitness.readonly |
averageHeartRateBeatsPerMinute |
דופק | heart-rate |
heart_rate.sample_time.physical_time |
health_metrics_and_measurements.readonly |
activeZoneMinutes |
דקות טווח דופק | active-zone-minutes |
active_zone_minutes.interval.start_time |
activity_and_fitness.readonly |
בקטעים הבאים מפורטים פרטים טכניים על סוג הנתונים exercise, כולל דוגמאות לייצוג REST, טיפול במסלולי GPS והנחיות לשילוב.
אימוני כושר
לכתוב פעילויות או אימונים יומיים כנקודות על הגרף של נתוני סשנים ב-exercise. כל נקודה על הגרף מתארת את הסשן הכולל, מפרטת את מרווחי הזמן של האירועים (כמו פעולות השהיה והמשך) ומספקת מדדי סיכום (כמו מרחק כולל, צעדים ודופק ממוצע).
מאפייני סשן
כשמבנים נקודה על הגרף של אימון, צריך לוודא שרכיבי הליבה הבאים קיימים:
- Session Time (
interval): שעת ההתחלה ושעת הסיום של האימון כולו, כולל הפרשי השעות מאזור הזמן שפעילים בנקודות הזמן האלה. - סוג הפעילות (
exerciseType): קטגוריית הפעילות שבוצעה (למשלRUNNING,WALKING,BIKINGאוAEROBIC_WORKOUT). צריך לציין את הסוג המדויק של האימון הגופני. - שם לתצוגה (
displayName): שם ידידותי למשתמש של האימון. כשיוצרים את ה-exerciseTypeבאמצעות ה-API בארכיטקטורת REST, השרת מאכלס את השם המותאם לשפה המקומית שמוצג, למשל"Run"ל-RUNNING. - משך הזמן הפעיל (
activeDuration): משך הזמן הפעיל בפועל של האימון, לא כולל מרווחי זמן של השהיה. הפורמט הרגיל הואDuration(לדוגמה,"1800s"). בשרת, הערך שלactiveDurationמחושב לפי הערך שלintervalבסשן, פחות כל מרווח שלPAUSE/RESUMEאוAUTO_PAUSE/AUTO_RESUMEב-exerciseEvents.
מדדי סיכום
האובייקט המקונן metricsSummary מכיל מדדים כוללים וממוצעים שמחושבים לאורך כל משך האימון:
-
caloriesKcal: סך הקלוריות הפעילות שנשרפו במהלך האימון, בקילוקלוריות (kcal). -
distanceMillimeters: המרחק הכולל שנמדד במילימטרים כדי לשמור על דיוק גבוה בכל היחידות. -
steps: מספר הצעדים הכולל במהלך האימון. -
averageHeartRateBeatsPerMinute: הדופק הממוצע של המשתמש במהלך דקות הפעילות של הסשן. -
activeZoneMinutes: מספר מצטבר של דקות טווח דופק שנצברו במהלך האימון. -
averageSpeedMillimetersPerSecond: מהירות התנועה הממוצעת במילימטרים לשנייה. -
averagePaceSecondsPerMeter: הקצב הממוצע במהלך הדקות הפעילות בסשן, נמדד בשניות למטר. -
elevationGainMillimeters: סה"כ עלייה במהלך הסשן.
הקפות ופיצולים
באימונים שכוללים הקפות (כמו ריצה במסלול או שחייה בבריכה) שמסונכרנים ממכשירים נתמכים, splitSummaries מחלק את הסשן לפי הקפה או פיצול.
כל פיצול מכיל:
startTimeוendTimeספציפיים.activeDurationשמייצג את זמן ההקפה האמיתי.metricsSummaryשמוגדר רק לפלח הזה.-
splitTypeלהגדרת גבולות הפיצול (למשלDISTANCE,DURATIONאוMANUAL).
אירועי פעילות גופנית
כדי לחשב במדויק את משך הזמן הפעיל, צריך לעקוב אחרי מעברי מצב (כמו אירועי השהיה ידניים או אוטומטיים) באמצעות exerciseEvents.
כל אירוע מכיל את חותמת הזמן (eventTime) ואת הסוג:
-
START/STOP: מציין את חותמות הזמן של הגבולות שבהם המשתמש התחיל או הפסיק את ההקלטה באופן מפורש. -
PAUSE/RESUME: מציין מתי הסשן הושהה או חודש באופן ידני. -
AUTO_PAUSE/AUTO_RESUME: מציין השהיות אוטומטיות או המשך אוטומטי שמופעלים על ידי חיישן.
כתיבת נתוני אימון
כדי ליצור, לעדכן או לייבא אימון, כותבים נקודה על הגרף לאוסף סוגי הנתונים של exercise. משתמשים בנקודת הקצה create dataPoints.
דוגמה לייצוג REST
בדוגמה הבאה אפשר לראות איך כותבים אימון באמצעות השיטה POST:
בקשה
POST https://health.googleapis.com/v4/users/me/dataTypes/exercise/dataPoints
Authorization: Bearer access-token
Content-Type: application/json
{
"dataSource": {
"recordingMethod": "ACTIVELY_MEASURED",
"platform": "GOOGLE_WEB_API"
},
"exercise": {
"interval": {
"startTime": "2026-04-20T08:00:00Z",
"startUtcOffset": "0s",
"endTime": "2026-04-20T08:35:00Z",
"endUtcOffset": "0s"
},
"exerciseType": "RUNNING",
"activeDuration": "1800s",
"metricsSummary": {
"caloriesKcal": 380.0,
"distanceMillimeters": 5000000.0,
"steps": "6200",
"averageHeartRateBeatsPerMinute": "148",
"averagePaceSecondsPerMeter": 0.36
},
"exerciseEvents": [
{
"eventTime": "2026-04-20T08:15:00Z",
"eventUtcOffset": "0s",
"exerciseEventType": "PAUSE"
},
{
"eventTime": "2026-04-20T08:20:00Z",
"eventUtcOffset": "0s",
"exerciseEventType": "RESUME"
}
]
}
}תשובה
{
"done": true,
"response": {
"@type": "type.googleapis.com/google.devicesandservices.health.v4.DataPoint",
"name": "users/999298779973222220/dataTypes/exercise/dataPoints/3054085373369111216",
"dataSource": {
"recordingMethod": "ACTIVELY_MEASURED",
"application": {
"googleWebClientId": "438076457939-example.apps.googleusercontent.com"
},
"platform": "GOOGLE_WEB_API"
},
"exercise": {
"interval": {
"startTime": "2026-04-20T08:00:00Z",
"startUtcOffset": "0s",
"endTime": "2026-04-20T08:35:00Z",
"endUtcOffset": "0s"
},
"exerciseType": "RUNNING",
"metricsSummary": {
"caloriesKcal": 380,
"distanceMillimeters": 5000000,
"steps": "6200",
"averagePaceSecondsPerMeter": 0.36,
"averageHeartRateBeatsPerMinute": "148"
},
"exerciseMetadata": {},
"displayName": "Run",
"activeDuration": "1800s",
"exerciseEvents": [
{
"eventTime": "2026-04-20T08:15:00Z",
"eventUtcOffset": "0s",
"exerciseEventType": "PAUSE"
},
{
"eventTime": "2026-04-20T08:20:00Z",
"eventUtcOffset": "0s",
"exerciseEventType": "RESUME"
}
],
"updateTime": "2026-04-20T08:35:10.123456Z",
"createTime": "2026-04-20T08:35:10.123456Z"
}
}
}מסלולי GPS ומעקב אחר מיקום
ה-API שומר סיכומי סשנים בסיסיים ישירות בנקודת הנתונים exercise, אבל מטפל בהיסטוריית מיקומים מפורטת ובקואורדינטות של מסלול GPS כסטרימינג נפרד.
כדי להוריד את נתוני המסלול המפורטים של סשן בחוץ, צריך להפעיל את השיטה המותאמת אישית exportExerciseTcx. נקודת הקצה הזו מחזירה את המסלול בפורמט Training Center XML (TCX), שהוא הפורמט המקובל בתחום.
ייצוא מסלול GPS
בקשה
GET https://health.googleapis.com/v4/users/me/dataTypes/exercise/dataPoints/exercise-data-point-id:exportExerciseTcx?alt=media Authorization: Bearer access-token
תשובה
מטען ייעודי (payload) של HTTP עם Content-Type: application/tcx+xml ועם
כותרות שמורות לדפדפן לשמור את הקובץ.
<?xml version="1.0" encoding="UTF-8"?>
<TrainingCenterDatabase xmlns="http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2">
<Activities>
<Activity Sport="Running">
<Id>2026-04-20T08:00:00Z</Id>
<Lap StartTime="2026-04-20T08:00:00Z">
<TotalTimeSeconds>1800</TotalTimeSeconds>
<DistanceMeters>5000</DistanceMeters>
<Calories>380</Calories>
<Intensity>Active</Intensity>
<TriggerMethod>Manual</TriggerMethod>
<Track>
<Trackpoint>
<Time>2026-04-20T08:00:00Z</Time>
<Position>
<LatitudeDegrees>37.7749</LatitudeDegrees>
<LongitudeDegrees>-122.4194</LongitudeDegrees>
</Position>
<AltitudeMeters>15.0</AltitudeMeters>
<DistanceMeters>0.0</DistanceMeters>
</Trackpoint>
</Track>
</Lap>
</Activity>
</Activities>
</TrainingCenterDatabase>היקפי ההרשאות והמיקום הנדרשים
כדי להשתמש בתכונה מסלולי GPS ומעקב אחר מיקום, האפליקציה צריכה לבקש את היקפי ההרשאות הבאים של OAuth:
- קריאה:
https://www.googleapis.com/auth/googlehealth.activity_and_fitness.readonly - כתיבה:
https://www.googleapis.com/auth/googlehealth.activity_and_fitness.writeonly - קריאה:
https://www.googleapis.com/auth/googlehealth.location.readonly
הנחיות
כשמשלבים מעקב אחרי אימונים באפליקציה, צריך לפעול לפי ההנחיות הבאות לעיצוב ולהטמעה.
משך הזמן הפעיל לעומת משך הזמן הכולל
כדי לחשב מדדי מהירות או קצב, תמיד צריך להשתמש ב-activeDuration ולא בהפרש בין startTime ל-endTime. כך מרווחים מושהים לא מעוותים את המדדים.
לדוגמה, אם משתמש מתחיל אימון בשעה 08:00 ומסיים בשעה 08:35, משך הזמן הכולל של האימון הוא 2,100 שניות. אם המשתמש השהה את האימון למשך 5 דקות (300 שניות) וכללתם אירועים מסוג PAUSE ו-RESUME ב-exerciseEvents, משך הזמן הפעיל הוא "1800s" (2,100 פחות 300). ה-API משתמש במשך הפעילות כדי לחשב ממוצעים, ומחלק את המרחק הכולל ב-1,800 שניות במקום ב-2,100.
חישוב מהירות וקצב
Google Health API משתמש בנוסחאות סטנדרטיות כדי לחשב את המהירות והקצב:
- מהירות =
distance / time(hour) - קצב =
time(seconds) / distance
הכותרת Accept-Language שצוינה בבקשה קובעת את יחידת המרחק.
בקשת מיקום בשלב מוקדם
אם האפליקציה ממפה מסלולי אימון, צריך לבקש הרשאות מיקום ואת ההיקף של Google Health location בנוסף להיקף של הפעילות והכושר. הסבירו למשתמשים למה האפליקציה צריכה את היקף ההרשאות למיקום כשבודקים אימונים עם GPS.
כשהאפליקציה מבקשת את היקף ההרשאות למיקום (https://www.googleapis.com/auth/googlehealth.location.readonly), מערכת Google OAuth מציגה למשתמש בקשה להסכמה. הסבירו למשתמשים שההרשאה הזו נדרשת כדי להציג שכבות-על של מסלולים ולייצא קובצי מעקב באמצעות GPS (TCX). אם משתמש מעניק את היקף הפעילות אבל דוחה את הרשאת המיקום, הפונקציה exportExerciseTcx מחזירה שגיאת הרשאה, אבל עדיין אפשר לגשת לנתונים מצטברים של סשנים ב-metricsSummary.
סנכרון בזמן אמת באמצעות תגובות לפעולה מאתר אחר (webhooks)
נרשמים לסוג הנתונים exercise כדי להודיע לקצה העורפי באמצעות תגובות לפעילות אינטרנט (webhooks) כשנתוני אימון חדשים זמינים. כך אפשר להפעיל חוויות אחרי האימון בזמן אמת.
כשהשרת מקבל התראת webhook, היא מכילה את ה-healthUserId ואת מרווח הזמן האזרחי (civilIso8601TimeInterval) של האימון המעודכן. השרת צריך לאשר את ההתראה באופן מיידי באמצעות 204 No Content, לעבד את המטען הייעודי (payload) באופן אסינכרוני ולשלוח שאילתה לנקודת הקצה (endpoint) המותאמת של exercise באמצעות מסנן exercise.interval.civil_start_time (שימו לב ש-exercise תומך רק בסינון לפי civil_start_time):
GET https://health.googleapis.com/v4/users/healthUserId/dataTypes/exercise/dataPoints:reconcile?filter=exercise.interval.civil_start_time >= "2026-04-20T08:00:00" AND exercise.interval.civil_start_time < "2026-04-20T10:00:00"
במאמר מינויים ל-Webhook מוסבר איך מגדירים מינויים.
שמירה על מדדים עקביים
כדי לספק חוויית אימון מלאה, כדאי לכלול מדדי סיכום כשכותבים סשנים של exercise, ולשלוח שאילתות לנקודות הקצה של הטלמטריה לקריאה בלבד באמצעות מסננים של טווחי תאריכים כשמציגים תרשימים מפורטים.
כתיבת מדדים של סיכום אימון (נתיב כתיבה)
כשמייבאים או כותבים אימון שהושלם ל-Google Health API, צריך לכלול את מדדי הטלמטריה המצטברים של האימון (steps, caloriesKcal, distanceMillimeters, averageHeartRateBeatsPerMinute ו-averagePaceSecondsPerMeter) בתוך האובייקט metricsSummary של נקודה על הגרף exercise:
POST https://health.googleapis.com/v4/users/me/dataTypes/exercise/dataPoints
שאילתות על נתונים מפורטים לתרשימים (נתיב קריאה)
כדי ליצור מרכזי בקרה או תרשימים של אימונים לסשן ספציפי, שולחים שאילתה לנקודות הקצה של נתוני הטלמטריה שתואמים לחלון הזמן של האימון:
אחזור של סשן האימון מנקודת הקצה
exerciseבאמצעות מסנןcivil_start_timeכדי לקבל את הערכיםintervalו-metricsSummary:GET https://health.googleapis.com/v4/users/me/dataTypes/exercise/dataPoints:reconcile?filter=exercise.interval.civil_start_time >= "2026-04-20T00:00:00" AND exercise.interval.civil_start_time < "2026-04-21T00:00:00"
משתמשים ב-
interval.startTimeוב-interval.endTimeשל הסשן כדי לשלוח שאילתות לנקודות הקצה של נתוני הטלמטריה בחלון הזמן הפיזי הזה.אם הערך של
exerciseMetadata.hasGpsהואtrue, צריך להפעיל אתexportExerciseTcxכדי להוריד את הקואורדינטות של המסלול.