我正在进行步数实施,因为我正在使用android的google fit api。
以下是我的代码。
public class GoogleFitDemoActivity extends AppCompatActivity {
public static final String TAG = "BasicSensorsApi";
private GoogleApiClient mClient = null;
private static final int REQUEST_PERMISSIONS_REQUEST_CODE = 34;
private OnDataPointListener mListener;
private TextView stepsCountTextView;
ProgressDialog progressDialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.google_fit_main);
progressDialog = new ProgressDialog(this);
if (!checkPermissions()) {
requestPermissions();
Debug.displayToast(this, "Requesting for permisstion ");
}
stepsCountTextView = (TextView) findViewById(R.id.sample_logview);
}
/**
* Return the current state of the permissions needed.
*/
private boolean checkPermissions() {
int permissionState = ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION);
return permissionState == PackageManager.PERMISSION_GRANTED;
}
/**
* Unregister the listener with the Sensors API.
*/
private void unregisterFitnessDataListener() {
if (mListener == null) {
return;
}
Fitness.SensorsApi.remove(
mClient,
mListener)
.setResultCallback(new ResultCallback<Status>() {
@Override
public void onResult(Status status) {
if (status.isSuccess()) {
Debug.print(TAG, "Listener was removed!");
} else {
Debug.print(TAG, "Listener was not removed.");
}
}
});
}
private void buildFitnessClient() {
if (progressDialog == null) {
return;
}
progressDialog.setMessage("Wait.....");
progressDialog.show();
if (mClient == null && checkPermissions()) {
mClient = new GoogleApiClient.Builder(this)
.addApi(Fitness.SENSORS_API)
.addScope(new Scope(Scopes.FITNESS_ACTIVITY_READ_WRITE))
.addConnectionCallbacks(
new GoogleApiClient.ConnectionCallbacks() {
@Override
public void onConnected(Bundle bundle) {
runOnUiThread(new Runnable() {
@Override
public void run() {
progressDialog.setMessage("Client Connected waiting for fit register");
}
});
Debug.print(TAG, "Connected!!!");
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) {
Debug.print(TAG, "Connection lost. Cause: Network Lost.");
} else if (i
== GoogleApiClient.ConnectionCallbacks.CAUSE_SERVICE_DISCONNECTED) {
Debug.print(TAG,
"Connection lost. Reason: Service Disconnected");
}
}
}
)
.enableAutoManage(this, 0, new GoogleApiClient.OnConnectionFailedListener() {
@Override
public void onConnectionFailed(ConnectionResult result) {
Debug.print(TAG, "Google Play services connection failed. Cause: " +
result.toString());
Snackbar.make(
GoogleFitDemoActivity.this.findViewById(R.id.main_activity_view),
"Exception while connecting to Google Play services: " +
result.getErrorMessage(),
Snackbar.LENGTH_INDEFINITE).show();
}
})
.build();
}
}
private void findFitnessDataSources() {
Fitness.SensorsApi.findDataSources(mClient, new DataSourcesRequest.Builder()
.setDataTypes(DataType.TYPE_STEP_COUNT_CUMULATIVE)
.setDataSourceTypes(DataSource.TYPE_DERIVED)
.build())
.setResultCallback(new ResultCallback<DataSourcesResult>() {
@Override
public void onResult(DataSourcesResult dataSourcesResult) {
progressDialog.dismiss();
Debug.print(TAG, "Result: " + dataSourcesResult.getStatus().toString());
for (DataSource dataSource : dataSourcesResult.getDataSources()) {
Debug.print(TAG, "Data source found: " + dataSource.toString());
Debug.print(TAG, DataType.TYPE_STEP_COUNT_CUMULATIVE + " 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) {
Debug.print(TAG, "Data source for LOCATION_SAMPLE found! Registering.");
registerFitnessDataListener(dataSource,
DataType.TYPE_STEP_COUNT_CUMULATIVE);
}
}
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
}
@Override
protected void onResume() {
super.onResume();
buildFitnessClient();
}
private void registerFitnessDataListener(DataSource dataSource, DataType dataType) {
mListener = new OnDataPointListener() {
@Override
public void onDataPoint(DataPoint dataPoint) {
for (Field field : dataPoint.getDataType().getFields()) {
final Value val = dataPoint.getValue(field);
runOnUiThread(new Runnable() {
@Override
public void run() {
stepsCountTextView.setText("Steps count is " + val);
}
});
Debug.print(TAG, "Detected DataPoint field: " + field.getName());
Debug.print(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()) {
Debug.print(TAG, "Listener registered!");
} else {
Debug.print(TAG, "Listener not registered.");
}
}
});
}
private void requestPermissions() {
boolean shouldProvideRationale =
ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_FINE_LOCATION);
if (shouldProvideRationale) {
Debug.print(TAG, "Displaying permission rationale to provide additional context.");
Snackbar.make(
findViewById(R.id.main_activity_view),
R.string.permission_rationale,
Snackbar.LENGTH_INDEFINITE)
.setAction(R.string.ok, new View.OnClickListener() {
@Override
public void onClick(View view) {
// Request permission
ActivityCompat.requestPermissions(GoogleFitDemoActivity.this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
REQUEST_PERMISSIONS_REQUEST_CODE);
}
})
.show();
} else {
Debug.print(TAG, "Requesting permission");
ActivityCompat.requestPermissions(GoogleFitDemoActivity.this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
REQUEST_PERMISSIONS_REQUEST_CODE);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
Debug.print(TAG, "onRequestPermissionResult");
if (requestCode == REQUEST_PERMISSIONS_REQUEST_CODE) {
if (grantResults.length <= 0) {
Debug.print(TAG, "User interaction was cancelled.");
} else if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
buildFitnessClient();
} else {
Snackbar.make(
findViewById(R.id.main_activity_view),
R.string.permission_denied_explanation,
Snackbar.LENGTH_INDEFINITE)
.setAction(R.string.settings, new View.OnClickListener() {
@Override
public void onClick(View view) {
// Build intent that displays the App settings screen.
Intent intent = new Intent();
intent.setAction(
Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package",
BuildConfig.APPLICATION_ID, null);
intent.setData(uri);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
})
.show();
}
}
}
}
以下是我所面对的此代码中的问题。
(假设我已经开始步行并且步数为10并且一旦我的onConnected()被调用我杀了我的所有并再次启动app我注册获取数据点并且我得到dataPoint值10,而它应该给0从第一个开始
1步长值不会重置为0并继续递增。
2每次运行代码时,步骤值都不会重置为0,因此它会接收一些过去的值。
3没有经常更新步骤计数更新。(当我走了5分钟然后它给出了第一步计数)
4即使在杀死应用程序并再次重新启动应用程序获取前面的步骤计数后,步骤计数也不会从0开始从0开始。(因为我没有在首选项或数据库中存储任何值。我如何获得上一步计数10)
请参阅结果日志
检测到的DataPoint值:1&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;在这应该从0开始
检测到的DataPoint字段:步骤 检测到的DataPoint值:1
检测到的DataPoint字段:步骤 检测到的DataPoint值:6
检测到的DataPoint字段:步骤 检测到的DataPoint值:6
检测到的DataPoint字段:步骤 检测到的DataPoint值:7
检测到的DataPoint字段:步骤 检测到的DataPoint值:7
检测到的DataPoint字段:步骤 检测到的DataPoint值:2
请在我犯错的地方帮忙。
答案 0 :(得分:0)
我认为有两种方法可以通过他们的API从Google Fit中获取步骤值:
1)历史API:我们只需要订阅GG Fit我们想要获得什么样的价值,GG Fit将自己保存信息(不知何故,它可以通过利用传感器,机器学习来检测您的步骤......(不是通过GPS - 您可以在Google上轻松找到它))。然后,如果我们想获得GG Fit保存的价值,只需撤销具有时间范围的历史API。
2)传感器API:我们将使用传感器API和一些出色的算法与设备中的传感器进行通信,以获得直接的步进值(不是通过GG Fit在服务器上保存并在以后获取)。但是,此方法将使用设备中的传感器临时存储器来保存步长值;并且这个值不断增加,只有你的设备重新启动,然后重置:( =&gt;所以,你可以做一些小技巧来获得真正的价值。 (例如,保存第一个值,然后继续减去后者。假设首先我们得到1990,然后保存它,然后得到1995,然后减去它1995 - 1190 = 5步)但是,我不知道如果保存在传感器内存中的值变得太大,并且溢出。 :(
**我的经验:不应该使用DELTA类型。由于时间范围,它可能会带来错误的值;例如,从17:30:00到17:31:00它有值步骤15,但是如果我们撤销17:30:00到17:30:10的时间范围,它没有价值和时间范围从17:30 :10到17:31:00,它有价值第10步。有时,当你的屏幕设备正在睡觉时,它会错过价值,GG Fit会在地下调用他们的API而不是录制时间。更重要的是,有时我得到负值@@。上帝知道他们在做什么!
最后,我认为GG Fit应用程序会以某种方式使用某种技巧实时显示步长值(可能是传感器API,大多数情况下,我使用带有步骤累积的传感器API(非delta),这样可以获得类似于GG Fit app)。然后,当我响应应用程序,唤醒设备的屏幕(如果你在Android中开发,这意味着你的活动调用onResume()方法),我撤销历史API从时间范围从开始到当前时间我重新启动我的应用程序并获得最新值。
https://developers.google.com/fit/android - &gt;这个链接向您展示了什么样的API GG Fit支持Android。
https://developer.android.com/reference/android/hardware/Sensor.html#TYPE_STEP_COUNTER - &gt;这个链接是来自传感器的TYPE_STEP的描述,据说它会一直增加,直到设备重启。