已通过Google Fit REST API获取活动会话列表,如何获取对应活动的距离信息
我目前正在用PHP的cURL调用Google Fit的REST API,已经完成了以下步骤:
- 通过OAuth 2.0授权,获取到了包含
fitness.activity.read和fitness.location.read权限的访问令牌 - 调用
sessions接口获取到了活动会话列表,能拿到活动的类型、开始/结束时间等元数据,返回示例如下:
"session": [ { "id": "Run1629350880000", "name": "Run", "startTimeMillis": "1629350880000", "endTimeMillis": "1629352020000", "activityType": 8, "application": { "packageName": "com.xiaomi.hm.health" } } ]
但我无法从会话接口中获取到活动的行进距离信息,请问后续应该如何操作?
嗨,我刚好处理过类似的Google Fit API调用问题,你遇到的情况很常见——因为会话(sessions)接口本身只返回活动的元数据(比如类型、时间范围),并不包含具体的运动数据(比如距离、卡路里)。要获取行进距离,你需要调用Google Fit的数据集(datasets)接口,从对应的数据源中提取聚合数据。下面是具体的操作步骤和示例代码:
1. 确定距离对应的数据源ID
Google Fit把距离数据归类为com.google.distance.delta类型,推荐使用合并后的衍生数据源(它会整合来自不同设备/应用的距离数据,比如你的小米运动数据),对应的数据源ID是:derived:com.google.distance.delta:com.google.android.gms:merge_distance_delta
如果你只想获取某一个特定应用(比如小米运动)的距离数据,可以先调用https://www.googleapis.com/fitness/v1/users/me/dataSources接口列出所有可用数据源,找到packageName为com.xiaomi.hm.health且dataType.name为distance_delta的数据源ID。
2. 构造数据集请求的时间范围
用你从会话接口拿到的startTimeMillis和endTimeMillis,拼接成数据集ID格式:{start_time}-{end_time}。比如某个会话的开始时间是1629350880000,结束时间是1629352020000,那数据集ID就是1629350880000-1629352020000。
3. 调用数据集接口获取距离数据
使用你已经获取到的Bearer令牌,向构造好的URL发送GET请求。下面是PHP cURL的示例代码,你可以把它和之前的会话遍历逻辑结合:
// 假设你已经拿到授权令牌 $accessToken,以及当前遍历的会话的 $startTime 和 $endTime $datasetId = "{$startTime}-{$endTime}"; $dataSourceId = "derived:com.google.distance.delta:com.google.android.gms:merge_distance_delta"; $url = "https://www.googleapis.com/fitness/v1/users/me/dataSources/{$dataSourceId}/datasets/{$datasetId}"; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, [ "Authorization: Bearer {$accessToken}", "Content-Type: application/json" ]); $response = curl_exec($ch); curl_close($ch); $distanceData = json_decode($response, true); // 解析距离值(单位:米) $totalDistance = 0; if (!empty($distanceData['point'])) { foreach ($distanceData['point'] as $point) { // 距离值存储在 value[0]['fpVal'] 字段中 $totalDistance += $point['value'][0]['fpVal']; } // 转换成公里(可选) $totalDistanceKm = round($totalDistance / 1000, 2); echo "该活动的行进距离:{$totalDistanceKm} 公里"; } else { echo "该活动没有记录距离数据"; }
关键注意事项
- 确保你的OAuth权限包含
fitness.location.read(你之前的授权已经覆盖,无需额外申请) - 部分活动(如静态拉伸、冥想)可能没有距离数据,所以一定要做好空值判断
- 如果返回的数据集数据较多,你可以添加
aggregateBy参数来聚合数据,减少返回的点数,但对于单会话的时间范围来说,通常不需要额外聚合
内容的提问来源于stack exchange,提问作者Max

