android - 未调用 Google Fit : How to Use Multiple Data Sources, 和 onDataPoint

标签 android google-fit

我一直在使用 Google FIT API,因此我可以读取总步数、步数、行走距离、总卡路里等信息。当我运行应用程序时,似乎什么也没有发生。我认为为了从每个类别接收数据,您需要为每个类别创建一个单独的数据点监听器。这些似乎没有被调用 - 我没有得到任何具有更新值的 toast 。

这是我的代码:

private void getFitnessDataSources()
{
    Fitness.SensorsApi.findDataSources(googleApiClient, new DataSourcesRequest.Builder()
            .setDataTypes(dataTypes[0]).setDataTypes(dataTypes[1]).setDataTypes(dataTypes[2])
            .setDataTypes(dataTypes[3]).setDataTypes(dataTypes[4]).setDataTypes(dataTypes[5])
            .setDataTypes(dataTypes[6]).setDataTypes(dataTypes[7])
            .setDataSourceTypes(DataSource.TYPE_DERIVED)
            .build())
            .setResultCallback(new ResultCallback<DataSourcesResult>() {
        @Override public void onResult(@NonNull DataSourcesResult dataSourcesResult) {

                 for (DataSource dataSource : dataSourcesResult.getDataSources()) {
                    displayToast("Data source found: "+dataSource.getName());

                     if (dataSource.getDataType() == dataTypes[0]) {
                        caloriesListener = new OnDataPointListener() {
                            @Override
                            public void onDataPoint(DataPoint dataPoint) {
                                for (Field field : dataPoint.getDataType().getFields()) {
                                    Value fieldValue = dataPoint.getValue(field);
                                    displayToast("Field Name: "+field.getName() + "Value: " +
                                            ""+fieldValue);
                                    totalTimeTextView.setText(fieldValue.toString());
                                }
                            }
                        };
                         registerFitnessDataListener(dataSource, dataTypes[0], caloriesListener);
                     } else if (dataSource.getDataType().equals(dataTypes[1])) {
                        currentCaloriesListener = new OnDataPointListener() {
                            @Override
                            public void onDataPoint(DataPoint dataPoint) {
                                for (Field field: dataPoint.getDataType().getFields()) {
                                    Value fieldValue = dataPoint.getValue(field);
                                    displayToast("Field Name: "+field.getName()+"Value: "+fieldValue);
                                    distanceCoveredTextView.setText(fieldValue.toString());
                                }
                            }
                        };
                         registerFitnessDataListener(dataSource, dataTypes[1], currentCaloriesListener);
                     } else if (dataSource.getDataType().equals(dataTypes[2])) {
                        stepCountsListener = new OnDataPointListener() {
                            @Override
                            public void onDataPoint(DataPoint dataPoint) {
                                for (Field field: dataPoint.getDataType().getFields()) {
                                    Value fieldValue = dataPoint.getValue(field);
                                    displayToast("Field Name: "+field.getName()+"Value: "+fieldValue);

                                }
                            }
                        };
                         registerFitnessDataListener(dataSource, dataTypes[2], stepCountsListener);
                     } else if (dataSource.getDataType().equals(dataTypes[3])) {
                         totalStepCountsListener = new OnDataPointListener() {
                             @Override
                             public void onDataPoint(DataPoint dataPoint) {
                                 for (Field field: dataPoint.getDataType().getFields()) {
                                     Value fieldValue = dataPoint.getValue(field);
                                     displayToast("Field Name: "+field.getName()+"Value: "+fieldValue);
                                 }
                             }
                         };
                         registerFitnessDataListener(dataSource, dataTypes[3], totalStepCountsListener);

                     } else if (dataSource.getDataType().equals(dataTypes[4])) {
                         distanceListener = new OnDataPointListener() {
                             @Override
                             public void onDataPoint(DataPoint dataPoint) {
                                 for (Field field: dataPoint.getDataType().getFields()) {
                                     Value fieldValue = dataPoint.getValue(field);
                                     displayToast("Field Name: "+field.getName()+"Value: "+fieldValue);
                                 }
                             }
                         };
                         registerFitnessDataListener(dataSource, dataTypes[4], distanceListener);
                     } else if (dataSource.getDataType().equals(dataTypes[5])){
                         totalDistanceListener = new OnDataPointListener() {
                             @Override
                             public void onDataPoint(DataPoint dataPoint) {
                                 for (Field field: dataPoint.getDataType().getFields()) {
                                     Value fieldValue = dataPoint.getValue(field);
                                     displayToast("Field Name: "+field.getName()+"Value: "+fieldValue);
                                 }
                             }
                         };
                         registerFitnessDataListener(dataSource, dataTypes[5], totalDistanceListener);
                     } else if (dataSource.getDataType().equals(dataTypes[6])) {
                         speedListener = new OnDataPointListener() {
                             @Override
                             public void onDataPoint(DataPoint dataPoint) {
                                 for (Field field: dataPoint.getDataType().getFields()) {
                                     Value fieldValue = dataPoint.getValue(field);
                                     displayToast("Field Name: "+field.getName()+"Value: "+fieldValue);
                                 }
                             }
                         };
                         registerFitnessDataListener(dataSource, dataTypes[6], speedListener);
                     } else if (dataSource.getDataType().equals(dataTypes[7])) {
                         speedSummaryListener = new OnDataPointListener() {
                             @Override
                             public void onDataPoint(DataPoint dataPoint) {
                                 for (Field field: dataPoint.getDataType().getFields()) {
                                     Value fieldValue = dataPoint.getValue(field);
                                     displayToast("Field Name: "+field.getName()+"Value: "+fieldValue);
                                 }
                             }
                         };
                         registerFitnessDataListener(dataSource, dataTypes[7], speedSummaryListener);
                     }
                 }
        }
    });
}

这是初始化我正在使用的数据类型数组的代码:

private void initializeSessionDataTypes()
{
    dataTypes = new DataType[] {DataType.AGGREGATE_CALORIES_EXPENDED, DataType
            .TYPE_CALORIES_EXPENDED, DataType.TYPE_STEP_COUNT_DELTA, DataType
            .TYPE_STEP_COUNT_CUMULATIVE, DataType.TYPE_DISTANCE_DELTA, DataType
            .AGGREGATE_DISTANCE_DELTA, DataType.TYPE_SPEED, DataType.AGGREGATE_SPEED_SUMMARY};
}

这是我用来注册每个健身数据源的代码:

private void registerFitnessDataListener(DataSource dataSource, DataType dataType,
                                         OnDataPointListener listener) {
    Fitness.SensorsApi.add(googleApiClient, new SensorRequest.Builder().setDataSource
            (dataSource).setDataType(dataType).setSamplingRate(1, TimeUnit.SECONDS).build(),
            listener).setResultCallback(new ResultCallback<Status>() {
        @Override
        public void onResult(@NonNull Status status) {
            if (status.isSuccess()) {
                displayToast("Listener is registered");
            } else {
                displayToast("Listener is not registered");
            }
        }
    });
    subscribeToFitnessData(dataType);
}

我的谷歌 API 客户端:

private void buildFitnessApi() {

    Scope activityRead = new Scope(Scopes.FITNESS_ACTIVITY_READ);
    Scope fitnessActivityReadWrite = new Scope(Scopes.FITNESS_ACTIVITY_READ_WRITE);
    Scope bodyRead = new Scope(Scopes.FITNESS_BODY_READ);
    Scope bodyReadWrite = new Scope(Scopes.FITNESS_BODY_READ_WRITE);
    Scope locationRead = new Scope(Scopes.FITNESS_LOCATION_READ);
    Scope locationReadWrite = new Scope(Scopes.FITNESS_LOCATION_READ_WRITE);

        googleApiClient = new GoogleApiClient.Builder(this.getActivity()).addApi(LocationServices.API)
                .addApi(Fitness.SENSORS_API).addApi(Fitness.HISTORY_API).addApi(Fitness.SESSIONS_API)
                        .addApi(Fitness
                        .RECORDING_API).addScope(activityRead).addScope
                        (fitnessActivityReadWrite).addScope(bodyRead).addScope(bodyReadWrite)
                .addScope(locationRead).addScope(locationReadWrite)
                        .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this).build();
}

有人可以帮助我吗?如果您尝试获取多个数据流(步数、燃烧的卡路里等),使用 google fit api 的最佳方式是什么。

谢谢

最佳答案

我认为您不需要为不同的数据源使用那么多 else if 语句。我只想在每个数据源上调用 registerFitnessDataListener,在使用 SensorsAPI 添加监听器之前,您需要这段代码...

final DataType dataType = dataSource.getDataType();
    if (dataType.equals(DataType.TYPE_STEP_COUNT_DELTA) ||
            dataType.equals(DataType.TYPE_CALORIES_EXPENDED) ||
            dataType.equals(DataType.TYPE_DISTANCE_DELTA) ||
            dataType.equals(DataType.TYPE_ACTIVITY_SEGMENT)){

我怀疑问题出在为多个数据源注册多个 onDataPointListeners。我已经测试过了,结果是: 由于每个 onDataPointListener 都有这个 onDataPoint 方法

@Override
                        public void onDataPoint(DataPoint dataPoint) {
                            for (Field field : dataPoint.getDataType().getFields()) {
                                Value fieldValue = dataPoint.getValue(field);
                                displayToast("Field Name: "+field.getName() + "Value: " +
                                        ""+fieldValue);
                                totalTimeTextView.setText(fieldValue.toString());
                            }
                        }

注册的最后一个(或可能是第一个)onDataPointerListener 只能监听接收到的数据点,因此不会调用其他监听器的 OnDataPoint 方法。

所以,这是一个并发问题,我们应该为每个监听器创建一个线程。我不知道该怎么做,但我希望其他人可以帮助我们。

关于android - 未调用 Google Fit : How to Use Multiple Data Sources, 和 onDataPoint,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37603524/

相关文章:

android - 在真实设备上模拟慢速互联网连接?

java - 避免在 ImageView android中多次单击

ios - Xamarin iOS : Check if Google fit app is installed on the device

android - 未找到 GoogleApiClient 类

android - 位置更改通知android

android - 如何在 Android 中将 int 传递给我的 onDraw(Canvas canvas)?

java - Android 改造预计为 BEGIN_ARRAY

google-api - 如何使用google fit在后台获取心率?

node.js - 我怎样才能获得谷歌健身数据

android - 如何从 Google Fit 历史记录中获取心率值?