Как узнать количество шагов в Google Fit REST API, например в приложении Google Fit?

Я занимаюсь разработкой приложения PHP, которое работает с API Google Fit для сбора ежедневного количества шагов пользователя.

Я хочу получить количество шагов от "15 января 2015 00:00:00 GMT+0700" до "16 января 2015 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. Почему существуют различия между значением источника данных и значением Google Fit?
3. Как я могу получить значение Google Fit?

3 ответа

Решение

Я думаю, что разница, которую вы видите, заключается в том, как Google использует History API и Sensors API. Если вы используете PHP, вы запрашиваете Google Fit Store через доступный фитнес-API, и это зависит от того, что приложение могло сохранять через API записи. Таким образом, вы можете не видеть все данные, имеющиеся на устройстве.

Google Fit API

Я думаю, но не знаю наверняка, что приложение Fit использует датчики API. В приложении вы можете использовать API датчиков, как описано в API Google Docs Sensors, и управлять возвращенными данными по своему усмотрению.

Ниже показан простой способ получить шаги, используя 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 App. Однако это, очевидно, доступно только на устройстве, поэтому вам потребуется запустить фоновую службу, которая обновляет внешнюю базу данных, что и дают API-интерфейсы записи и истории.

Чтобы убедиться, что данные продолжают отправляться в Fitness Store, когда ваше приложение работает в фоновом режиме, вам необходимо использовать API записи, это также может изменить значения, которые вы видите.

ОБНОВИТЬ:

Написав выше, я подумал, что должен это проверить. Это было от утренней прогулки.

  • Apple iPhone 6 HealthKit: 6,762
  • Apple iPhone 6 My App: 6,762
  • Android Nexus 6 Fit: 6,920
  • Android Nexus 6 My App: 6,920 (используется HistoryAPI)
  • Android Rest API приблизительно: 6 928
  • Android Rest API merge_step_deltas: 6,911

Это из поста Google+ вы можете найти здесь

"merge_step_deltas дает вам объединенный поток всех ваших счетчиков шагов.timate_steps также учитывает активность и оценивает шаги, когда их нет"

Единственное, чего я еще не понял, - это датчики, использующие то, что я показываю выше, они дают мне всего 2548 шагов.

Другая незначительная любопытная вещь заключается в том, что через день Fit показывает мне, что я сделал 6 668 шагов, что ближе к результату Apple, но пересчет по сравнению с тем, что он первоначально показал мне после синхронизации данных. Мое приложение все еще показывает 6,920!

Время для синхронизации всего этого я не измерял.

  1. Какой источник данных использует приложение Google Fit для расчета количества шагов?

Google Fit App использует источник данных оценочных_шагов для расчета количества шагов. DataSourceId: производный:com.google.step_count.delta:com.google.android.gms: оценочный_ этапов

  1. Почему существуют различия между значением источника данных и значением Google Fit?

Каждый источник данных представляет свое устройство / источник. Я вижу, у вас есть смарт-часы Sony и HTC Desire, подключенные к Google Fit. Каждое из ваших устройств сообщает значения Fit, которые объединяются вместе. Merge_step_deltas дает вам объединенный поток всех ваших счетчиков шагов. Estimated_steps также учитывает активность и оценивает шаги, когда их нет.

  1. Как я могу получить значение Google Fit?

REST API может получить доступ только к данным, которые были синхронизированы с серверной частью. Чтобы получить те же значения, что и в Google Fit, прочитайте источник данных оценочных_шагов. Это должно быть то же, что вы видите на https://fit.google.com/. Устройство может иметь последние значения, которые еще не синхронизированы с сервером. Мы работаем над тем, чтобы сделать синхронизацию и кроссплатформенность более удобной.

- Инженер в Google Fit Team.

Шаги Google Fit получают через REST Api

Запрос активности пользователя при входе в систему через Google и сохранение токена авторизации пользователя

Добавить дополнительную область для примера в 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
            }

Вот ответ от API GoogleFit Steps

{
"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": []
                      }]
                }]
      } ]
 } ]
}

Мне больше всего повезло с derived:com.google.step_count.delta:com.google.android.gms:estimated_steps

Первоначально результат был выше, чем то, что читал мой телефон, и затем я отфильтровал данные по двум основным шаговым устройствам. select{|q| q["originDataSourceId"] =~ /360|Nexus/} и это дало мне самый близкий результат.

Если я попробую другой диапазон дня позже, и это будет полностью за стеной, я вернусь и отмечу это здесь.

Другие вопросы по тегам