我第一次使用Google Fit API。我修改了BasicSensorsApi sample代码来计算步数。它工作正常,但问题是当我在GoogleApiClient.disconnect()
函数中调用onStop()
然后再次调用GoogleApiClient.connect()
函数中的onStart()
时,OnDataPointListener
停止获取回调。我不是在任何地方取消注册这个监听器。
当我没有打电话给GoogleApiClient.disconnect()
时,它工作正常,并且在调用活动onStop()
函数后得到回调事件。
我不确定是否应该在GoogleApiClient
功能中断开onStop()
。如果是,那么我该如何解决上述问题?
以下是相关代码:
private void buildFitnessClient() {
// Create the Google API Client
mClient = new GoogleApiClient.Builder(this)
.addApi(Fitness.SENSORS_API)
.addScope(new Scope(Scopes.FITNESS_LOCATION_READ))
.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.
findFitnessDataSources();
}
@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(), MainActivity.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(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) {
// Make sure the app is not already connected or attempting to connect
if (!mClient.isConnecting() && !mClient.isConnected()) {
mClient.connect();
}
}
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean(AUTH_PENDING, authInProgress);
}
// [END auth_connection_flow_in_activity_lifecycle_methods]
/**
* Find available data sources and attempt to register on a specific {@link DataType}.
* If the application cares about a data type but doesn't care about the source of the data,
* this can be skipped entirely, instead calling
* {@link com.google.android.gms.fitness.SensorsApi
* #register(GoogleApiClient, SensorRequest, DataSourceListener)},
* where the {@link SensorRequest} contains the desired data type.
*/
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_CADENCE)
.setDataTypes(DataType.TYPE_STEP_COUNT_CUMULATIVE)
.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());
//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 TYPE_STEP_COUNT_CADENCE found! Registering.");
registerFitnessDataListener(dataSource, DataType.TYPE_STEP_COUNT_CADENCE);
} else 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);
} else if (dataSource.getDataType().equals(DataType.TYPE_STEP_COUNT_DELTA) && mListener == null) {
Log.i(TAG, "Data source for TYPE_STEP_COUNT_DELTA found! Registering.");
registerFitnessDataListener(dataSource, DataType.TYPE_STEP_COUNT_DELTA);
}
}
}
});
// [END find_data_sources]
}
/**
* Register a listener with the Sensors API for the provided {@link DataSource} and
* {@link DataType} combo.
*/
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(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]
}
答案 0 :(得分:1)
如果您正在跟踪前台的步数,那么这是正确的行为,因为您在onstop()中断开了google api客户端。一旦GoogleApiClient断开连接,所有听众都将从GoogleApiClient中删除。但是,如果您希望在后台跟踪步数,则可能需要将实施移至服务并确定何时要与GoogleApiclient断开连接。
答案 1 :(得分:0)
与文档相反,您必须断开onDestroy而不是onStop。连接onCreate并在onStop / onStart中不执行任何操作。
为什么?
因为等待调用onConnect的应用程序不会阻止调用onStop。在您的应用收到活动之前,onStop会被称为。然后,当然,它断开连接,永远不会得到它。