【问题标题】:How to get step count from Google Fit REST API like Google Fit app?如何从 Google Fit REST API(如 Google Fit 应用程序)获取步数?
【发布时间】:2020-04-30 13:27:45
【问题描述】:

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

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

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

我发现,有很多数据源,它们返回不同的值。而且这些值与我在手机上的 Google Fit 应用中看到的相差太大。

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

【问题讨论】:

  • 链接目前无效。请更新或删除它们。

标签: google-api-php-client google-fit


【解决方案1】:
  1. Google Fit 应用程序使用哪个数据源来计算步数?

Google 健身应用使用estimated_steps 数据源来计算步数。 DataSourceId:派生:com.google.step_count.delta:com.google.android.gms:estimated_steps

  1. 为什么数据源的值和 Google Fit 的值不同?

每个数据源代表不同的设备/源。我了解到您将 Sony 智能手表和 HTC Desire 连接到 Google Fit。您的每台设备都会向 Fit 报告合并在一起的值。 Merge_step_deltas 为您提供所有计步器的合并流。 Estimated_steps 还考虑了活动,并在没有活动时估计步数。

  1. 如何获取 Google Fit 值?

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

-- Google Fit 团队的工程师。

【讨论】:

  • 关于任何应用程序可以通过 REST API 查询 Google Fit 数据的最佳频率是否有任何更新...比如每 1 分钟一次?
【解决方案2】:

我认为您看到的区别在于 Google 使用 History API 和 Sensors API 的方式之间的区别。如果您使用的是 PHP,则您正在通过可用的健身 API 查询 Google Fit Store,这取决于应用程序能够通过记录 API 保存的内容。因此,您可能无法看到设备可用的所有数据。

我认为,但不确定,Fit App 使用传感器 API。在应用程序中,您可以使用 Google Docs 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 为您提供的。

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

更新:

写完上面的内容,我想我应该测试一下。这是早上散步时拍的。

  • Apple iPhone 6 HealthKit:6,762
  • Apple iPhone 6 我的应用程序:6,762
  • Android Nexus 6 适配:6,920
  • Android Nexus 6 我的应用:6,920(使用 HistoryAPI)
  • Android Rest API 估计步数:6,928
  • Android Rest API merge_step_deltas:6,911

这是来自您可以找到 here 的 Google+ 帖子

“merge_step_deltas 为您提供所有计步器的合并流。estimated_steps 还考虑了活动,并在没有计步器时估计步数”

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

另一件有点奇怪的事情是,一天后,Fit 显示我做了 6,668 步,如此接近 Apple 的结果,但在数据同步后,它重新计算了它最初显示给我的结果。我的应用程序仍然显示 6,920!

我没有衡量所有同步的时间。

【讨论】:

  • 我现在很确定 Google Fit 不使用 History API 来获取其数据。今天同步花了 2 个多小时,整个应用程序显示 0,Google Fit 显示 5,672 步。
【解决方案3】:

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

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

如果我稍后尝试不同的日期范围并且它完全不在墙上,我会回来并在这里注意。

【讨论】:

  • 嗨,即使我用我的手机 Galaxy S5 进行过滤,我仍然可以获得更高的步数读数
【解决方案4】:

Google Fit Steps 通过 REST Api 获取

通过谷歌登录时请求用户活动并存储用户的身份验证令牌

添加额外范围 例如在 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": []
                      }]
                }]
      } ]
 } ]
}

【讨论】:

    猜你喜欢
    • 2023-03-07
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-26
    • 1970-01-01
    • 1970-01-01
    • 2015-06-26
    相关资源
    最近更新 更多