5

Google Fit API と連携して毎日のユーザーの歩数を収集する PHP アプリケーションを開発しています。

「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. データソースの値と Google Fit の値に違いがあるのはなぜですか?
3. Google Fit の値を取得するにはどうすればよいですか? </p>

4

4 に答える 4

11
  1. Google Fit アプリが歩数の計算に使用するデータソースはどれですか?

Google Fit アプリは、推定ステップ数データ ソースを使用して歩数を計算します。DataSourceId: 派生:com.google.step_count.delta:com.google.android.gms:estimated_steps

  1. データソースの値と Google Fit の値に違いがあるのはなぜですか?

各データ ソースは、異なるデバイス/ソースを表します。Sony Smart Watch と 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 チームのエンジニア。

于 2015-05-05T18:42:08.280 に答える
5

あなたが見ている違いは、Google が History API と Sensors API を使用する方法の違いだと思います。PHP を使用している場合は、利用可能なフィットネス API を介して Google Fit Store にクエリを実行しています。これは、アプリがレコーディング API を介して保存できる機能に依存します。そのため、デバイスで利用可能なすべてのデータが表示されない場合があります。

Google フィット API

確かなことはわかりませんが、Fit アプリはセンサー 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 API と History API が提供するものです。

アプリがバックグラウンドにあるときにデータが引き続きフィットネス ストアに送信されるようにするための注意点として、記録 API を使用する必要があります。これにより、表示される値も変わる可能性があります。

アップデート:

上記を書いたので、テストする必要があると思いました。これは朝の散歩からでした。

  • Apple iPhone 6 HealthKit: 6,762
  • Apple iPhone 6 マイアプリ: 6,762
  • Android Nexus 6 フィット: 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 は、すべてのステップ カウンターのマージされたストリームを提供します。effective_steps は、アクティビティも考慮に入れ、何もない場合に歩数を推定します」

私がまだ一番下に到達していないのは、上に示したものを使用したセンサーで、2,548 ステップしか得られません。

もう 1 つの興味深い点は、1 日後に Fit が 6,668 歩を実行したことを示していることです。これは Apple の結果に非常に近いものですが、データが同期された後に最初に表示されたものから再計算されています。私のアプリはまだ 6,920 を示しています。

すべてが同期するまでの時間は測定していません。

于 2015-02-18T12:23:38.240 に答える
0

一番運が良かったderived:com.google.step_count.delta:com.google.android.gms:estimated_steps

最初の結果は、私の電話が読み取ったものよりも高かったので、2 つの主要なステップ デバイスでフィルターselect{|q| q["originDataSourceId"] =~ /360|Nexus/}をかけたところ、最も近い結果が得られました。

後で別の日の範囲を試してみて、それが完全に壁から外れている場合は、戻ってきてここに注意してください.

于 2015-02-14T05:45:52.810 に答える