如何从 Google Fit REST API 像 Google Fit 应用程序一样获取步数?

How to get step count from Google Fit REST API like Google Fit app?

我正在开发一个 PHP 应用程序,它使用 Google Fit API 来收集每日用户的步数。

我想将我的步数从 "Jan 15 2015 00:00:00 GMT+0700" 计算到 "Jan 16 2015 00:00:00 GMT+0700"。 - 首先,我得到了我所有的数据源。 - 然后,对于数据类型等于 "com.google.step_count.delta" 的每个数据源,我获取上述时间戳之间的数据集并将 return 值加在一起。

我的代码:https://gist.github.com/daitr-gu/472c4f18522172542cca
我的结果:https://gist.github.com/daitr-gu/1a7e11eb483a657bdc8b

我发现,有很多数据源,它们 return 有不同的值。这些值与我在 phone.

上的 Google Fit 应用程序中看到的值相差太大

问题:
1. Google Fit 应用使用哪个数据源来计算步数?
2. 为什么datasources的值和Google Fit值不一样?
3. 如何获得Google拟合值?

我最幸运 derived:com.google.step_count.delta:com.google.android.gms:estimated_steps

最初的结果比我的 phone 读到的要高,所以我在我的两个主要步骤设备上进行了过滤 select{|q| q["originDataSourceId"] =~ /360|Nexus/},这给了我最接近的结果。

如果我稍后尝试不同的日期范围并且它完全脱离了墙壁,我会回来并在此处注明。

我认为您看到的区别是 Google 使用历史记录 API 和传感器 API 的方式之间的区别。如果您正在使用 PHP,您将通过可用的健身 API 查询 Google 健身商店,然后这取决于应用程序能够通过录音保存的内容 API。因此您可能看不到设备可用的所有数据。

我认为,但不确定 Fit 应用程序是否使用传感器 api。在应用程序中,您可以按照 Google 文档 Sensors API 中的描述使用传感器 API 并根据需要处理返回的数据。

下面显示了使用 TYPE_STEP_COUNT_CUMULATIVE 和 TYPE_RAW

获取步数的简单方法
Fitness.SensorsApi.findDataSources(mClient, new DataSourcesRequest.Builder()
            // At least one datatype must be specified.
            .setDataTypes(DataType.TYPE_STEP_COUNT_CUMULATIVE)
                    // Can specify whether data type is raw or derived.
            .setDataSourceTypes(DataSource.TYPE_RAW)
            .build())
            .setResultCallback(new ResultCallback<DataSourcesResult>() {
                @Override
                public void onResult(DataSourcesResult dataSourcesResult) {
                    Log.i(TAG, "Result: " + dataSourcesResult.getStatus().toString());
                    for (DataSource dataSource : dataSourcesResult.getDataSources()) {
                        Log.i(TAG, "Data source found: " + dataSource.toString());
                        Log.i(TAG, "Data Source type: " + dataSource.getDataType().getName());

                        //Let's register a listener to receive Activity data!
                        if (dataSource.getDataType().equals(DataType.TYPE_STEP_COUNT_CUMULATIVE) && mListener == null) {
                            Log.i(TAG, "Data source for TYPE_STEP_COUNT_CUMULATIVE found!  Registering.");
                            registerFitnessDataListener(dataSource, DataType.TYPE_STEP_COUNT_CUMULATIVE);
                        }
                    }
                }
            });

private void registerFitnessDataListener(DataSource dataSource, DataType dataType) {

    mListener = new OnDataPointListener() {
        @Override
        public void onDataPoint(DataPoint dataPoint) {
            for (Field field : dataPoint.getDataType().getFields()) {
                Value val = dataPoint.getValue(field);
                Log.i(TAG, "Detected DataPoint field: " + field.getName());
                Log.i(TAG, "Detected DataPoint value: " + val);

                Log.i(TAG, "Difference in steps: " + (val.asInt()-previousValue));

                previousValue = val.asInt();
            }
        }
    };

    Fitness.SensorsApi.add(
            mClient,
            new SensorRequest.Builder()
                    .setDataSource(dataSource) // Optional but recommended for custom data sets.
                    .setDataType(dataType) // Can't be omitted.
                    .setSamplingRate(10, TimeUnit.SECONDS)
                    .build(),
            mListener)
            .setResultCallback(new ResultCallback<Status>() {
                @Override
                public void onResult(Status status) {
                    if (status.isSuccess()) {
                        Log.i(TAG, "Listener registered!");
                    } else {
                        Log.i(TAG, "Listener not registered.");
                    }
                }
            });
}

您可能会发现这为您提供的值与 Fit 应用程序提供的值更接近。然而,这显然只能在设备上使用,因此您需要 运行 更新外部数据库的后台服务,这就是 Recording 和 History API 提供给您的。

请注意,当您的应用程序处于后台时,要确保数据继续发送到 Fitness Store,您需要使用记录 API,这也可能会改变您看到的值。

更新:

写完上面我觉得我应该测试一下。这是早上散步的。

  • 苹果 iPhone 6 HealthKit:6,762
  • Apple iPhone 6 我的应用程序:6,762
  • Android Nexus 6 飞度:6,920
  • Android Nexus 6 我的应用程序:6,920(使用历史记录API)
  • Android 休息 API estimated_steps: 6,928
  • Android 休息 API merge_step_deltas: 6,911

这是来自 Google+ post 你可以找到 here

"merge_step_deltas gives you the merged stream of all your step counters. estimated_steps also takes into account activity, and estimates steps when there are none"

我还没有深入了解的是使用上面显示的传感器的传感器,它只给了我 2,548 步。

另一件有点奇怪的事情是,一天后,Fit 向我展示了我完成了 6,668 步,这与 Apple 的结果非常接近,但这是在数据同步后重新计算的。我的应用程序仍然显示 6,920!

全部同步的时间我没有测量。

  1. Google Fit 应用使用哪个数据源来计算步数?

Google Fit App 使用 estimated_steps 数据源计算步数。 DataSourceId: derived:com.google.step_count.delta:com.google.android.gms:estimated_steps

  1. 为什么数据源的值和Google拟合值不一样?

每个数据源代表不同的 device/source。我看到您将 Sony 智能手表和 HTC Desire 连接到 Google Fit。您的每台设备都会向 Google 健身报告合并在一起的值。 Merge_step_deltas 为您提供所有计步器的合并流。 Estimated_steps也考虑了activity,有none.

时估计步数
  1. 如何获得 Google 拟合值?

REST API只能访问同步到后台的数据。 要获得与 Google Fit 相同的值,请阅读 estimated_steps 数据源。它应该与您在 https://fit.google.com/ 上看到的相同。该设备可能具有尚未同步到服务器的最新值。我们正在努力使同步和跨平台体验更加无缝。

-- Google Fit Team 的工程师。

Google 通过 REST 获取拟合步骤 Api

在通过 google 登录时请求用户 activity 并存储用户

的身份验证令牌

添加额外范围 例如 iOS =

GIDSignIn.sharedInstance()?.scopes.append("https://www.googleapis.com/auth/fitness.activity.read")

同样我们可以添加其他语言的范围

现在调用 api 获取步骤

Api Reference Link - https://developers.google.com/fit/scenarios/read-daily-step-total
Api URL - https://www.googleapis.com/fitness/v1/users/me/dataset:aggregate
Api     Method - POST
Headers - Authorization  Access Token
API Request -    {
                "aggregateBy": [{
                     "dataTypeName": "com.google.step_count.delta",
                        "dataSourceId": "derived:com.google.step_count.delta:com.google.android.gms:estimated_steps"
                 }],
                "bucketByTime": { "durationMillis": 86400000 }, //86400000 is 24 Hours in milli second
                 "startTimeMillis": 1582654903000, // Start time in milli second
                "endTimeMillis": 1582741303000 // End time in milli second
            }

这是来自 GoogleFit Steps api

的回复
{
"bucket": [
 {
     "startTimeMillis": "1582654903000",
    "endTimeMillis": "1582741303000",
     "dataset": [
         {
              "dataSourceId": "derived:com.google.step_count.delta:com.google.android.gms:aggregated",
            "point": [
                      {
                "startTimeNanos": "1582715420043664097",
                "endTimeNanos": "1582721490164126971",
                "dataTypeName": "com.google.step_count.delta",
                "originDataSourceId": "raw:com.google.step_count.cumulative:Xiaomi:Mi A1:e96661ecb4ffb28d:Step Counter",
                "value": [
                {
                    "intVal": 683, // This is steps value
                    "mapVal": []
                      }]
                }]
      } ]
 } ]
}