1

我正在使用 Google Fitness API 构建一个计步器应用程序。

我可以通过 HistoyAPI.readDailyTotal() 获取每日步数

private void getTodaySteps() {
    PendingResult<DailyTotalResult> result = Fitness.HistoryApi.readDailyTotal(mClient, DataType.TYPE_STEP_COUNT_DELTA);
    if (result != null) {
        DailyTotalResult totalResult = result.await(30, TimeUnit.SECONDS);
        if (totalResult.getStatus().isSuccess()) {
            DataSet totalSet = totalResult.getTotal();
            final long total = totalSet.isEmpty()
                    ? 0
                    : totalSet.getDataPoints().get(0).getValue(Field.FIELD_STEPS).asInt();
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Log.i(TAG, "Steps today: " + total);
                    tv_StepsToday.setText("" + total);
                    if (total >= (stepsToday + stepsNow)) {
                        stepsNow = 0;
                        stepsToday = total;
                        publishTodaysStepData();
                    }
                }
            });
        } else {
            // handle failure
            Log.e(TAG, "Não foi possível obter o histórico de passos");
        }
    } else {
        Log.e(TAG, "result nulo!");
    }
}

我还使用 SensorAPI 来获取上次读取的增量步骤,然后我只需将两者相加并获得一个很好的响应式计步器。

private void subscribeSteps() {
    Fitness.RecordingApi.subscribe(mClient, DataType.TYPE_STEP_COUNT_DELTA)
            .setResultCallback(new ResultCallback<Status>() {
                @Override
                public void onResult(Status status) {
                    if (status.isSuccess()) {
                        if (status.getStatusCode()
                                == FitnessStatusCodes.SUCCESS_ALREADY_SUBSCRIBED) {
                            Log.i(TAG, "Existing subscription for activity detected.");
                        } else {
                            Log.i(TAG, "Successfully subscribed!");
                        }
                    } else {
                        Log.i(TAG, "There was a problem subscribing.");
                    }
                }
            });
}

private void unsubscribeStepsAndDeleteData() {
    Fitness.RecordingApi.unsubscribe(mClient, DataType.TYPE_STEP_COUNT_DELTA)
            .setResultCallback(new ResultCallback<Status>() {
                @Override
                public void onResult(Status status) {
                    if (status.isSuccess()) {
                        Log.i(TAG, "Successfully unsubscribed for data type: step count delta");
                        deleteData();
                    } else {
                        // Subscription not removed
                        Log.i(TAG, "Failed to unsubscribe for data type: step count delta");
                    }
                }
            });
}
private void getLiveSteps() {
    if (!listenerRegistered) {
        Log.v(TAG, "mandando requisição do sensor...");
        SensorRequest req = new SensorRequest.Builder()
                .setDataType(DataType.TYPE_STEP_COUNT_DELTA)
                .setSamplingRate(1, TimeUnit.SECONDS)
                .build();


        OnDataPointListener listener = new OnDataPointListener() {
            @Override
            public void onDataPoint(final DataPoint dataPoint) {
                Log.v(TAG, "new datapoint: " + dataPoint.toString());
                for (final Field field : dataPoint.getDataType().getFields()) {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            if (dataPoint.getTimestampNanos() != oldTimeStampNanos) {
                                oldTimeStampNanos = dataPoint.getTimestampNanos();
                                long result = (long) dataPoint.getValue(field).asInt();
                                Log.i(TAG, "steps now: " + result);
                                stepsNow += result;
                                publishTodaysStepData();
                            }
                        }
                    });
                }
            }
        };

        Fitness.SensorsApi.add(mClient, req, listener).setResultCallback(new ResultCallback<Status>() {
            @Override
            public void onResult(Status status) {
                if (status.isSuccess()) {
                    Log.i(TAG, "Listener registered!");
                    listenerRegistered = true;
                } else {
                    Log.i(TAG, "Listener not registered.");
                }
            }
        });
    }
}

但是我无法清除日常步骤。我正在尝试使用API 示例中的代码:

private void deleteData() {
    Log.i(TAG, "Deleting today's step count data");

    // [START delete_dataset]
    // Set a start and end time for our data, using a start time of 1 day before this moment.
    Calendar cal = Calendar.getInstance();
    Date now = new Date();
    cal.setTime(now);
    long endTime = cal.getTimeInMillis();
    cal.add(Calendar.DAY_OF_YEAR, -1);
    long startTime = cal.getTimeInMillis();

    //  Create a delete request object, providing a data type and a time interval
    DataDeleteRequest request = new DataDeleteRequest.Builder()
            .setTimeInterval(startTime, endTime, TimeUnit.MILLISECONDS)
            .addDataType(DataType.TYPE_STEP_COUNT_DELTA)
            .build();

    // Invoke the History API with the Google API client object and delete request, and then
    // specify a callback that will check the result.
    Fitness.HistoryApi.deleteData(mClient, request)
            .setResultCallback(new ResultCallback<Status>() {
                @Override
                public void onResult(Status status) {
                    if (status.isSuccess()) {
                        Log.i(TAG, "Successfully deleted today's step count data");
                    } else {
                        // The deletion will fail if the requesting app tries to delete data
                        // that it did not insert.
                        Log.i(TAG, "Failed to delete today's step count data");
                    }
                }
    });
    // [END delete_dataset]
}

这是一个错误,还是我只是做错了什么?

--编辑: 我的 GoogleApiClient 生成器

private void buildFitnessClient() {
    // Create the Google API Client
    mClient = new GoogleApiClient.Builder(this)
            .addApi(Fitness.SENSORS_API)
            .addApi(Fitness.HISTORY_API)
            .addApi(Fitness.RECORDING_API)
            .addScope(new Scope(Scopes.FITNESS_LOCATION_READ_WRITE))
            .addScope(new Scope(Scopes.FITNESS_ACTIVITY_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.subscribeSteps();
                            refreashAll();
                        }

                        @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(),
                                        LoginActivity.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(LoginActivity.this,
                                            REQUEST_OAUTH);
                                } catch (IntentSender.SendIntentException e) {
                                    Log.e(TAG,
                                            "Exception while starting resolution activity", e);
                                }
                            }
                        }
                    }
            )
            .build();

}

和我的日志:

07-20 09:03:53.161 10647-10647/br.com.penseavanti.gump I/LoginActivity﹕ Successfully unsubscribed for data type: step count delta 07-20 09:03:53.161 10647-10647/br.com.penseavanti.gump I/LoginActivity﹕ Deleting today's step count data 07-20 09:03:53.209 10647-10647/br.com.penseavanti.gump I/LoginActivity﹕ Successfully deleted today's step count data 07-20 09:03:53.388 10647-10647/br.com.penseavanti.gump I/LoginActivity﹕ Steps today: 509 07-20 09:03:53.434 10647-10647/br.com.penseavanti.gump I/LoginActivity﹕ Successfully subscribed!

4

0 回答 0