如何使用Google Fit API的RecordingClient对DataType.TYPE_LOCATION_SAMPLE进行后台采集?

How to use Google Fit API's RecordingClient for background collection of DataType.TYPE_LOCATION_SAMPLE?

我按照 Google Fit examples 进行操作并使用以下代码(在请求所有需要的权限之后)为 DataType.TYPE_LOCATION_SAMPLE 订阅了 RecordingClient:

Fitness.getRecordingClient(this, GoogleSignIn.getLastSignedInAccount(this))
    .subscribe(DataType.TYPE_LOCATION_SAMPLE)
    .addOnSuccessListener(new OnSuccessListener<Void>() {
        @Override
        public void onSuccess(Void aVoid) {
            Log.d(LOG_TAG, "Successfully subscribed!");
        }
    })
    .addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception e) {
            Log.d(LOG_TAG, "There was a problem subscribing.");
        }
    });

在 Logcat 上,我收到消息 Successfully subscribed!,所以一切似乎都正常。 另外,如果我运行下面的代码,要仔细检查:

Fitness.getRecordingClient(MainActivity.this, GoogleSignIn.getLastSignedInAccount(MainActivity.this))
    .listSubscriptions()
    .addOnSuccessListener(new OnSuccessListener<List<Subscription>>() {
        @Override
        public void onSuccess(List<Subscription> subscriptions) {
            for (Subscription sc : subscriptions) {
                Log.d(LOG_TAG, "Active subscription for data type: " + sc.getDataType().getName());
            }
        }
    });

我收到输出:

D/mygpsapp.log: Active subscription for data type: com.google.location.sample

确认订阅确实有效。 但是,如果(移动一小时后,为了测试)我尝试使用以下代码从 HistoryClient 读取数据:

DataReadRequest readRequest = new DataReadRequest.Builder()
    .read(DataType.TYPE_LOCATION_SAMPLE)
    .setTimeRange(startTime, endTime, TimeUnit.MILLISECONDS)
    .build();

Fitness.getHistoryClient(MainActivity.this, GoogleSignIn.getLastSignedInAccount(MainActivity.this))
    .readData(readRequest)
    .addOnSuccessListener(new OnSuccessListener<DataReadResponse>() {
        @Override
        public void onSuccess(DataReadResponse dataReadResponse) {
        Log.d(LOG_TAG, "HistoryClient.readData: onSuccess()");
        DataSet dataSet;

        List<DataSet> dataSets = dataReadResponse.getDataSets();
        Log.d(LOG_TAG, "# of DataSets: " + dataSets.size());
        dataSet = dataReadResponse.getDataSet(DataType.TYPE_LOCATION_SAMPLE);
            Log.d(LOG_TAG, "DataSet: " + dataSet);
            Log.d(LOG_TAG, "DataSource: " + dataSet.getDataSource());
            Log.d(LOG_TAG, "DataType: " + dataSet.getDataType());

        int count = 0;
        for (DataPoint dp : dataSet.getDataPoints()) {
            Log.d(LOG_TAG, "Data point #" + count++);
            Log.d(LOG_TAG, "\tType: " + dp.getDataType().getName());
            Log.d(LOG_TAG, "\tStart: " + dateFormat.format(dp.getStartTime(TimeUnit.MILLISECONDS)));
            Log.d(LOG_TAG, "\tEnd: " + dateFormat.format(dp.getEndTime(TimeUnit.MILLISECONDS)));
            for (Field field : dp.getDataType().getFields()) {
                Log.d(LOG_TAG, "\tField: " + field.getName() + ", Value: " + dp.getValue(field));
            }
            Log.d(LOG_TAG, "\tSource: " + dp.getOriginalDataSource().getAppPackageName());
        }
        }
    })
    .addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception e) {
        Log.e(LOG_TAG, "HistoryClient.readData: onFailure()", e);
        }
    });

我确实得到了一个相关的 DataSet,但它总是空的:

D/mygpsapp.log: # of DataSets: 1
D/mygpsapp.log: DataSet: DataSet{d:location.sample:gms:default_location_samples []}
D/mygpsapp.log: DataSource: DataSource{derived:Application{com.google.android.gms}:default_location_samples:DataType{com.google.location.sample[latitude(f), longitude(f), accuracy(f), altitude(f)]}}
D/mygpsapp.log: DataType: DataType{com.google.location.sample[latitude(f), longitude(f), accuracy(f), altitude(f)]}

我确认 Google Fit API 文档 reports the following:

Exceptions: Whilst any application can write data to a public data type, there are certain data types which can only be read by the application that wrote the data:

com.google.location.sample, The user's current location.

但我确实尝试使用相同的应用程序读回数据。 令我怀疑的是,前面的Logcat似乎表明写入数据的应用程序是com.google.android.gms(是RecordingClient吗?)不是我的,可能解释了为什么DataSet returns为空.但如果是这种情况,我的应用程序应该如何回读本身要求(成功!)记录的数据?

Google Fit 不支持通过历史 API.

读取通过记录 API 收集的位置数据

我们将在文档中阐明这一点。