5

我正在尝试使用 Google Fit API 在我的应用中获取步数。但我没有得到除位置以外的任何数据源。如何获取步数的数据源?我被困在这已经超过 4 天了。请帮我解决这个问题。谢谢。下面是我正在使用的代码

public class Home extends BaseActivity {
  private static String TAG = "HOME Activity";
  private static final int REQUEST_OAUTH = 1;

  /**
   * Track whether an authorization activity is stacking over the current activity, i.e. when
   * a known auth error is being resolved, such as showing the account chooser or presenting a
   * consent dialog. This avoids common duplications as might happen on screen rotations, etc.
   */
  private static final String AUTH_PENDING = "auth_state_pending";
  private boolean authInProgress = false;

  private GoogleApiClient mClient = null;
  private OnDataPointListener mListener;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_home);


    if (savedInstanceState != null) {
      authInProgress = savedInstanceState.getBoolean(AUTH_PENDING);
    }

    buildFitnessClient();


  }

  private void findFitnessDataSources() {
    // [START find_data_sources]
    Fitness.SensorsApi.findDataSources(mClient, new DataSourcesRequest.Builder()
        // At least one datatype must be specified.
        .setDataTypes(DataType.TYPE_STEP_COUNT_DELTA).setDataTypes(DataType.TYPE_STEP_COUNT_CADENCE).setDataTypes(DataType.TYPE_LOCATION_SAMPLE)
            // 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.v("Inside", "Callback");
            Log.i(TAG, "Result: " + dataSourcesResult.getStatus().toString());
            Log.v("Len", dataSourcesResult.getDataSources().size() + "");
            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_CADENCE)
                  && mListener == null) {
                Log.i(TAG, "Data source for STEP found!  Registering.");
                registerFitnessDataListener(dataSource,
                    DataType.TYPE_STEP_COUNT_CADENCE);
              }
            }
          }
        });
    // [END find_data_sources]
  }

  private void registerFitnessDataListener(DataSource dataSource, DataType dataType) {
    // [START register_data_listener]
    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);
        }
      }
    };
    Fitness.SensorsApi.add(
        mClient,
        new SensorRequest.Builder()
            .setDataSource(dataSource) // Optional but recommended for custom data sets.
            .setDataType(dataType) // Can't be omitted.
            .setSamplingRate(1, 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.");
            }
          }
        });
    // [END register_data_listener]
  }

  private void buildFitnessClient() {
    // Create the Google API Client
    mClient = new GoogleApiClient.Builder(this)
        .addApi(Fitness.SENSORS_API).addApi(Fitness.RECORDING_API).addApi(Fitness.SESSIONS_API)
        .addScope(new Scope(Scopes.FITNESS_ACTIVITY_READ_WRITE)).addScope(Fitness.SCOPE_ACTIVITY_READ_WRITE).addScope(Fitness.SCOPE_BODY_READ_WRITE)
        .addConnectionCallbacks(
            new GoogleApiClient.ConnectionCallbacks() {

              @Override
              public void onConnected(Bundle bundle) {
                Log.i(TAG, "Connected!!!");
                // Now you can make calls to the Fitness APIs.
                // Put application specific code here.
                findFitnessDataSources();
//                makeFitnessAPIRequest();
              }


              @Override
              public void onConnectionSuspended(int i) {
                // If your connection to the sensor gets lost at some point,
                // you'll be able to determine the reason and react to it here.
                if (i == GoogleApiClient.ConnectionCallbacks.CAUSE_NETWORK_LOST) {
                  Log.i(TAG, "Connection lost.  Cause: Network Lost.");
                } else if (i == GoogleApiClient.ConnectionCallbacks.CAUSE_SERVICE_DISCONNECTED) {
                  Log.i(TAG, "Connection lost.  Reason: Service Disconnected");
                }
              }
            }
        )
        .addOnConnectionFailedListener(
            new GoogleApiClient.OnConnectionFailedListener() {
              // Called whenever the API client fails to connect.
              @Override
              public void onConnectionFailed(ConnectionResult result) {
                Log.i(TAG, "Connection failed. Cause: " + result.toString());
                if (!result.hasResolution()) {
                  // Show the localized error dialog
                  GooglePlayServicesUtil.getErrorDialog(result.getErrorCode(),
                      Home.this, 0).show();
                  return;
                }
                // The failure has a resolution. Resolve it.
                // Called typically when the app is not yet authorized, and an
                // authorization dialog is displayed to the user.
                if (!authInProgress) {
                  try {
                    Log.i(TAG, "Attempting to resolve failed connection");
                    authInProgress = true;
                    result.startResolutionForResult(Home.this,
                        REQUEST_OAUTH);
                  } catch (IntentSender.SendIntentException e) {
                    Log.e(TAG,
                        "Exception while starting resolution activity", e);
                  }
                }
              }
            }
        )
        .build();
  }

  private void makeFitnessAPIRequest() {
    SensorRequest request = new SensorRequest.Builder().setDataType(DataType.TYPE_STEP_COUNT_DELTA)
        .setSamplingRate(1, TimeUnit.SECONDS).build();
    PendingResult<Status> reqResult = Fitness.SensorsApi.add(mClient, request, mListener);
  }

  @Override
  protected void onStart() {
    super.onStart();
    // Connect to the Fitness API
    Log.i(TAG, "Connecting...");
    mClient.connect();
  }

  @Override
  protected void onStop() {
    super.onStop();
    if (mClient.isConnected()) {
      mClient.disconnect();
    }
    Log.v("Inside", "Stop");
  }

  @Override
  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_OAUTH) {
      authInProgress = false;
      if (resultCode == RESULT_OK) {
        // Make sure the app is not already connected or attempting to connect
        if (!mClient.isConnecting() && !mClient.isConnected()) {
          mClient.connect();
          Log.v("Inside", "connect");
        }
      }
    }
  }

  @Override
  protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putBoolean(AUTH_PENDING, authInProgress);
  }

  /**
   * Unregister the listener with the Sensors API.
   */
  private void unregisterFitnessDataListener() {
    if (mListener == null) {
      // This code only activates one listener at a time.  If there's no listener, there's
      // nothing to unregister.
      return;
    }

    // [START unregister_data_listener]
    // Waiting isn't actually necessary as the unregister call will complete regardless,
    // even if called from within onStop, but a callback can still be added in order to
    // inspect the results.
    Fitness.SensorsApi.remove(
        mClient,
        mListener)
        .setResultCallback(new ResultCallback<Status>() {
          @Override
          public void onResult(Status status) {
            if (status.isSuccess()) {
              Log.i(TAG, "Listener was removed!");
            } else {
              Log.i(TAG, "Listener was not removed.");
            }
          }
        });
    // [END unregister_data_listener]
  }

}
4

4 回答 4

3

这对我有用,如果有人卡住,使用这个----

像这样初始化 FitnessClient 对象:

 private void buildFitnessClient() {
            if (mClient == null && checkPermissions()) {
                mClient = new GoogleApiClient.Builder(this)
                        .addApi(Fitness.SENSORS_API)
                        .addScope(new Scope(Scopes.FITNESS_LOCATION_READ))
                        .addConnectionCallbacks(
                                new GoogleApiClient.ConnectionCallbacks() {
                                    @Override
                                    public void onConnected(Bundle bundle) {
                                        Log.i(TAG, "Connected!!!");
                                        // Now you can make calls to the Fitness APIs.
                                        findFitnessDataSources();
                                    }

现在将您想要获取的数据类型定义为回调,我们必须将其设置为 DataType.TYPE_STEP_COUNT_DELTA,如下所示:

 private void findFitnessDataSources() {
        // [START find_data_sources]
        // Note: Fitness.SensorsApi.findDataSources() requires the ACCESS_FINE_LOCATION permission.
        Fitness.SensorsApi.findDataSources(mClient, new DataSourcesRequest.Builder()
                // At least one datatype must be specified.
                .setDataTypes(DataType.TYPE_STEP_COUNT_DELTA)

                        // Can specify whether data type is raw or derived.
                .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_DELTA)
                                && mListener == null) {
                            Log.i(TAG, "Data source for LOCATION_SAMPLE found!  Registering.");
                            registerFitnessDataListener(dataSource,
                                    DataType.TYPE_STEP_COUNT_DELTA);
                        }
                    }
                }
            });
    // [END find_data_sources]
}

现在使用 Sensors API 为提供的 DataSource 和 DataType 注册一个侦听器,如下所示:

private void registerFitnessDataListener(DataSource dataSource, DataType dataType) {
        // [START register_data_listener]
        mListener = new OnDataPointListener() {
            @Override
            public void onDataPoint(DataPoint dataPoint) {
                for (Field field : dataPoint.getDataType().getFields()) {
                    Value val = dataPoint.getValue(field);
//                    Value(TotalSteps);
//                     TotalSteps=val+TotalSteps;
                    Log.i(TAG, "Detected DataPoint field: " + field.getName());
                    Log.i(TAG, "Detected DataPoint value: " + val);
                }
            }
        };

        Fitness.SensorsApi.add(
                mClient,
                new SensorRequest.Builder()
                        .setDataSource(dataSource) // Optional but recommended for custom data sets.
                        .setDataType(dataType) // Can't be omitted.
                        .setSamplingRate(1, 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.");
                        }
                    }
                });
        // [END register_data_listener]
    }

也不要忘记注销您的听众:

 private void unregisterFitnessDataListener() {
        if (mListener == null) {
            // This code only activates one listener at a time.  If there's no listener, there's
            // nothing to unregister.
            return;
        }

        // [START unregister_data_listener]
        // Waiting isn't actually necessary as the unregister call will complete regardless,
        // even if called from within onStop, but a callback can still be added in order to
        // inspect the results.
        Fitness.SensorsApi.remove(
                mClient,
                mListener)
                .setResultCallback(new ResultCallback<Status>() {
                    @Override
                    public void onResult(Status status) {
                        if (status.isSuccess()) {
                            Log.i(TAG, "Listener was removed!");
                        } else {
                            Log.i(TAG, "Listener was not removed.");
                        }
                    }
                });
        // [END unregister_data_listener]
    }
于 2016-06-16T06:56:18.963 回答
1

我面临同样的问题

我通过改变来解决它

.setDataSourceTypes(DataSource.TYPE_RAW)

.setDataSourceTypes(DataSource.TYPE_DERIVED)

尝试改变它。

于 2015-05-12T13:49:53.630 回答
1

好的,我的朋友。请试试这个。它还不计算步数,但它可以读取您的计步器数据类型。当我尝试你的时,我在设置屏幕上遇到了 OAuth 问题。我对 addApi 的东西做了一些改变。

public class MainActivity extends ActionBarActivity {
public static final String TAG = "BasicSensorsApi";
// [START auth_variable_references]
private static final int REQUEST_OAUTH = 1;

private static final String AUTH_PENDING = "auth_state_pending";
private boolean authInProgress = false;

private GoogleApiClient mClient = null;
// [END auth_variable_references]


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // Put application specific code here.
    // [END auth_oncreate_setup_beginning]
    setContentView(R.layout.activity_main);
    // This method sets up our custom logger, which will print all log messages to the device
    // screen, as well as to adb logcat.


    // [START auth_oncreate_setup_ending]

    if (savedInstanceState != null) {
        authInProgress = savedInstanceState.getBoolean(AUTH_PENDING);
    }

    buildFitnessClient();
}


private void buildFitnessClient() {
    // Create the Google API Client
    mClient = new GoogleApiClient.Builder(this)
            .addApi(Fitness.SENSORS_API)
            .addScope(new Scope(Scopes.FITNESS_ACTIVITY_READ))
            .addScope(new Scope(Scopes.FITNESS_BODY_READ))
            .addConnectionCallbacks(
                    new GoogleApiClient.ConnectionCallbacks() {

                        @Override
                        public void onConnected(Bundle bundle) {
                            Log.i(TAG, "Connected!!!");
                            // Now you can make calls to the Fitness APIs.
                            // Put application specific code here.
                            // [END auth_build_googleapiclient_beginning]
                            //  What to do? Find some data sources!
                            findFitnessDataSources();

                            // [START auth_build_googleapiclient_ending]
                        }

                        @Override
                        public void onConnectionSuspended(int i) {

                            if (i == ConnectionCallbacks.CAUSE_NETWORK_LOST)    
   {
                                Log.i(TAG, "Connection lost.  Cause: Network 
   Lost.");
                            } else if (i == 
   ConnectionCallbacks.CAUSE_SERVICE_DISCONNECTED) {
                                Log.i(TAG, "Connection lost.  Reason: 
   Service Disconnected");
                            }
                        }
                    }
            )
            .addOnConnectionFailedListener(
                    new GoogleApiClient.OnConnectionFailedListener() {
                        // Called whenever the API client fails to connect.
                        @Override
                        public void onConnectionFailed(ConnectionResult 
       result) {
                            Log.i(TAG, "Connection failed. Cause: " + 
       result.toString());
                            if (!result.hasResolution()) {
                                // Show the localized error dialog

         GooglePlayServicesUtil.getErrorDialog(result.getErrorCode(),
                                        MainActivity.this, 0).show();
                                return;
                            }

                            if (!authInProgress) {
                                try {
                                    Log.i(TAG, "Attempting to resolve failed 
          connection");
                                    authInProgress = true;

         result.startResolutionForResult(MainActivity.this,
                                            REQUEST_OAUTH);
                                } catch (IntentSender.SendIntentException e) 
         {
                                    Log.e(TAG,
                                            "Exception while starting 
         resolution activity", e);
                                }
                            }
                        }
                    }
            )
            .build();
}

@Override
protected void onStart() {
    super.onStart();
    // Connect to the Fitness API
    Log.i(TAG, "Connecting...");
    mClient.connect();
}

@Override
protected void onStop() {
    super.onStop();
    if (mClient.isConnected()) {
        mClient.disconnect();
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent 
  data) {
    if (requestCode == REQUEST_OAUTH) {
        authInProgress = false;
        if (resultCode == RESULT_OK) {

            if (!mClient.isConnecting() && !mClient.isConnected()) {
                mClient.connect();
            }
        }
    }
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putBoolean(AUTH_PENDING, authInProgress);
}

private void findFitnessDataSources() {
    // [START find_data_sources]
    Fitness.SensorsApi.findDataSources(mClient, new 
  DataSourcesRequest.Builder()
            // At least one datatype must be specified.

            .setDataTypes(DataType.TYPE_STEP_COUNT_DELTA)
            // Can specify whether data type is raw or derived.
            .setDataSourceTypes(DataSource.TYPE_DERIVED)
            .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());


                        if 
   (dataSource.getDataType().equals(DataType.TYPE_STEP_COUNT_DELTA)
                                && mListener == null) {
                            Log.i(TAG, "Data source for STEP_COUNT_DELTA 
   found!  Registering.");
                            registerFitnessDataListener(dataSource,
                                    DataType.TYPE_STEP_COUNT_DELTA);
                        }
                    }
                }
            });
    // [END find_data_sources]
}


private void registerFitnessDataListener(DataSource dataSource, DataType 
dataType) {
    // [START register_data_listener]
    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);
            }
        }
    };

    Fitness.SensorsApi.add(
            mClient,
            new SensorRequest.Builder()
                    .setDataSource(dataSource) 
                    .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.");
                    }
                }
            });
     // [END register_data_listener]
  }



}
于 2015-05-13T09:07:52.037 回答
1

还要更改 onDataPointListener 内的这一行

 Log.i(TAG, "Detected DataPoint value: " + val);

 Log.i(TAG, "Detected DataPoint value: " + val.asInt());

你会得到计步,但它对我来说很有趣。例如,它达到 25 步,但随后它下降而不是计数。至少我让步数计数器位在做某事。

于 2015-05-13T09:32:24.337 回答