英文:
Cannot accumulate heart rate data in Google Fit Api for the past week
问题
我正在尝试从Google API中获取一周的心率摘要数据,但我只得到了数据类型名称,没有结果。如果我只获取特定小时的数据,API会返回大约每5分钟从我的Mi Band 5抓取的心率数据。如果有人能帮忙,我将非常感激。
**构建函数:**
```kotlin
private fun queryFitnessData2(): DataReadRequest {
// [START build_read_data_request]
// 使用1周前到现在的时间范围设置开始和结束日期。
val calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"))
val now = Date()
calendar.time = now
val endTime = calendar.timeInMillis
calendar.add(Calendar.WEEK_OF_YEAR, -1)
val startTime = calendar.timeInMillis
Log.i(TAG, "Range Start: ${dateFormat.format(startTime)}")
Log.i(TAG, "Range End: ${dateFormat.format(endTime)}")
return DataReadRequest.Builder()
.aggregate(DataType.TYPE_HEART_RATE_BPM, DataType.AGGREGATE_HEART_RATE_SUMMARY)
.enableServerQueries()
.bucketByTime(1, TimeUnit.DAYS)
.setTimeRange(startTime, endTime, TimeUnit.MILLISECONDS)
.build()
}
数据打印函数:
private fun printData(dataReadResult: DataReadResponse) {
// [START parse_read_data_result]
// 如果DataReadRequest对象指定了聚合数据,dataReadResult将作为包含DataSets的bucket返回,而不仅仅是DataSets。
if (dataReadResult.buckets.isNotEmpty()) {
Log.i(TAG, "Number of returned buckets of DataSets is: " + dataReadResult.buckets.size)
for (bucket in dataReadResult.buckets) {
bucket.dataSets.forEach { dumpDataSet(it) }
}
} else if (dataReadResult.dataSets.isNotEmpty()) {
Log.i(TAG, "Number of returned DataSets is: " + dataReadResult.dataSets.size)
dataReadResult.dataSets.forEach { dumpDataSet(it) }
}
// [END parse_read_data_result]
}
数据集解析函数:
// [START parse_dataset]
private fun dumpDataSet(dataSet: DataSet) {
Log.i(TAG, "Data returned for Data type: ${dataSet.dataType.name}")
val dateFormat: DateFormat = getTimeInstance()
// 这是循环无法正常工作的地方!!
for (dp in dataSet.dataPoints) {
Log.i(TAG, "Data point:")
Log.i(TAG, "\tType: ${dp.dataType.name}")
Log.i(TAG, "\tStart: ${dp.getStartTimeString()}")
Log.i(TAG, "\tEnd: ${dp.getEndTimeString()}")
dp.dataType.fields.forEach {
Log.i(TAG, "\tField: ${it.name} Value: ${dp.getValue(it)}")
}
}
}
// [END parse_dataset]
唯一记录的是数据类型,即心率摘要类型。
如果我对每天使用桶(buckets),for循环就不起作用,但如果我对每天的每个小时使用桶,它就能正常工作。非常感谢任何帮助。
<details>
<summary>英文:</summary>
I am tyrying to grab the Heart Rate Summary for one week from the Google Api, but I get no result just the datatype name. If I grab only for a specific hour the Api return the heart rate grabbed from mi Mi Band 5 every 5 minutes or so. If anyone could help I would be grateful.
**Builder Function:**
private fun queryFitnessData2(): DataReadRequest {
// [START build_read_data_request]
// Setting a start and end date using a range of 1 week before this moment.
val calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"))
val now = Date()
calendar.time = now
val endTime = calendar.timeInMillis
calendar.add(Calendar.WEEK_OF_YEAR, -1)
val startTime = calendar.timeInMillis
Log.i(TAG, "Range Start: ${dateFormat.format(startTime)}")
Log.i(TAG, "Range End: ${dateFormat.format(endTime)}")
return DataReadRequest.Builder()
.aggregate(DataType.TYPE_HEART_RATE_BPM, DataType.AGGREGATE_HEART_RATE_SUMMARY)
.enableServerQueries()
.bucketByTime(1, TimeUnit.DAYS)
.setTimeRange(startTime, endTime, TimeUnit.MILLISECONDS)
.build();
}
**Data Printer:**
private fun printData(dataReadResult: DataReadResponse) {
// [START parse_read_data_result]
// If the DataReadRequest object specified aggregated data, dataReadResult will be returned
// as buckets containing DataSets, instead of just DataSets.
if (dataReadResult.buckets.isNotEmpty()) {
Log.i(TAG, "Number of returned buckets of DataSets is: " + dataReadResult.buckets.size)
for (bucket in dataReadResult.buckets) {
bucket.dataSets.forEach { dumpDataSet(it) }
}
} else if (dataReadResult.dataSets.isNotEmpty()) {
Log.i(TAG, "Number of returned DataSets is: " + dataReadResult.dataSets.size)
dataReadResult.dataSets.forEach { dumpDataSet(it) }
}
// [END parse_read_data_result]
}
**Dataset Parser Function:**
// [START parse_dataset]
private fun dumpDataSet(dataSet: DataSet) {
Log.i(TAG, "Data returned for Data type: ${dataSet.dataType.name}")
val dateFormat: DateFormat = getTimeInstance()
//THIS IS WHERE THE FOR LOOP DOESN'T WORK!!
for (dp in dataSet.dataPoints) {
Log.i(TAG, "Data point:")
Log.i(TAG, "\tType: ${dp.dataType.name}")
Log.i(TAG, "\tStart: ${dp.getStartTimeString()}")
Log.i(TAG, "\tEnd: ${dp.getEndTimeString()}")
dp.dataType.fields.forEach {
Log.i(TAG, "\tField: ${it.name} Value: ${dp.getValue(it)}")
}
}
}
// [END parse_dataset]
The only thing it gets logged is the data type which is the heart.rate.summary type.
Thefor loop doesn't work if I use the buckets for each day but works fine if I use them for each hour of the day. Any help is much appreciated.
</details>
# 答案1
**得分**: 1
我终于找到了一种方法来汇总心率数据(它在我的手机上运行正常,但在Android Studio的模拟器上不行,记住这一点)。
首先为心率和汇总心率添加数据类型:
```java
FitnessOptions fitnessOptions =
FitnessOptions.builder()
.addDataType(DataType.TYPE_HEART_RATE_BPM, FitnessOptions.ACCESS_WRITE)
.addDataType(DataType.AGGREGATE_HEART_RATE_SUMMARY,FitnessOptions.ACCESS_WRITE)
.build();
然后按以下方式创建FitnessQuery函数:
private fun queryFitnessData2(): DataReadRequest {
val calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"))
val now = Date()
calendar.time = now
val endTime = calendar.timeInMillis
calendar.add(Calendar.WEEK_OF_YEAR, -1)
val startTime = calendar.timeInMillis
Log.i(TAG, "Range Start: ${dateFormat.format(startTime)}")
Log.i(TAG, "Range End: ${dateFormat.format(endTime)}")
return DataReadRequest.Builder()
.enableServerQueries()
.bucketByTime(1, TimeUnit.DAYS)
.setTimeRange(startTime, endTime, TimeUnit.MILLISECONDS)
.aggregate(DataType.TYPE_HEART_RATE_BPM, DataType.AGGREGATE_HEART_RATE_SUMMARY)
.build()
}
最后,在每个桶中转储数据集,每个桶对应一天:
private fun printData(dataReadResult: DataReadResponse) {
if (dataReadResult.buckets.isNotEmpty()) {
Log.i(TAG, "Number of returned buckets of DataSets is: " + dataReadResult.buckets.size)
for (i in 0 until dataReadResult.buckets.size) {
for (j in 0 until dataReadResult.buckets[i].dataSets.size) {
dumpDataSet(dataReadResult.buckets[i].dataSets[j])
}
}
} else if (dataReadResult.dataSets.isNotEmpty()) {
Log.i(TAG, "Number of returned DataSets is: " + dataReadResult.dataSets.size)
dataReadResult.dataSets.forEach { dumpDataSet(it) }
}
}
private fun dumpDataSet(dataSet: DataSet) {
Log.i(TAG, "Data returned for Data type: ${dataSet.dataType.name}")
val dateFormat: DateFormat = getTimeInstance()
for (dp: DataPoint in dataSet.dataPoints) {
Log.i(TAG, "\tStart: " + dateFormat.format(dp.getStartTime(TimeUnit.MILLISECONDS)))
Log.i(TAG, "\tEnd: " + dateFormat.format(dp.getEndTime(TimeUnit.MILLISECONDS)))
Log.i(TAG, "\tType: " + dp.dataType.name)
for (field in dp.dataType.fields) {
val fieldValue = "Field name: " + field.name.toString() + ", value: " + dp.getValue(field).asFloat()
Log.i(TAG, fieldValue)
}
}
}
希望我对那些在使用谷歌可怕的API文档时遇到困难的人有所帮助!
英文:
I finally found a way to aggregate Heart Rate Data ( it works on my phone but not on the Android Studio's Emulator so have that in mind.
First add a data type for the heart rate and the aggregated heart rate:
FitnessOptions fitnessOptions =
FitnessOptions.builder()
.addDataType(DataType.TYPE_HEART_RATE_BPM, FitnessOptions.ACCESS_WRITE)
.addDataType(DataType.AGGREGATE_HEART_RATE_SUMMARY,FitnessOptions.ACCESS_WRITE)
.build();
Then make the FitnessQuery Function as follows:
private fun queryFitnessData2(): DataReadRequest {
// [START build_read_data_request]
// Setting a start and end date using a range of 1 week before this moment.
val calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"))
val now = Date()
calendar.time = now
val endTime = calendar.timeInMillis
calendar.add(Calendar.WEEK_OF_YEAR, -1)
val startTime = calendar.timeInMillis
Log.i(TAG, "Range Start: ${dateFormat.format(startTime)}")
Log.i(TAG, "Range End: ${dateFormat.format(endTime)}")
return DataReadRequest.Builder()
.enableServerQueries()
.bucketByTime(1, TimeUnit.DAYS)
.setTimeRange(startTime, endTime, TimeUnit.MILLISECONDS)
.aggregate(DataType.TYPE_HEART_RATE_BPM, DataType.AGGREGATE_HEART_RATE_SUMMARY)
.build();
}
And finally the dataset dump in buckets where each bucket corresponds to one day:
private fun printData(dataReadResult: DataReadResponse) {
// [START parse_read_data_result]
// If the DataReadRequest object specified aggregated data, dataReadResult will be returned
// as buckets containing DataSets, instead of just DataSets.
if (dataReadResult.buckets.isNotEmpty()) {
Log.i(TAG, "Number of returned buckets of DataSets is: " + dataReadResult.buckets.size)
for (i in 0 until dataReadResult.buckets.size) {
for (j in 0 until dataReadResult.buckets[i].dataSets.size) {
dumpDataSet(dataReadResult.buckets[i].dataSets[j]);
}
}
} else if (dataReadResult.dataSets.isNotEmpty()) {
Log.i(TAG, "Number of returned DataSets is: " + dataReadResult.dataSets.size)
dataReadResult.dataSets.forEach { dumpDataSet(it) }
}
// [END parse_read_data_result]
}
// [START parse_dataset]
private fun dumpDataSet(dataSet: DataSet) {
Log.i(TAG, "Data returned for Data type: ${dataSet.dataType.name}")
val dateFormat: DateFormat = getTimeInstance()
for (dp:DataPoint in dataSet.dataPoints) {
Log.i(TAG, "\tStart: " + dateFormat.format(dp.getStartTime(TimeUnit.MILLISECONDS)));
Log.i(TAG, "\tEnd: " + dateFormat.format(dp.getEndTime(TimeUnit.MILLISECONDS)));
Log.i(TAG, "\tType: " + dp.dataType.name);
Log.i(TAG, "TEST")
for (field in dp.dataType.fields) {
Log.i(TAG, "TEST4")
val fieldValue = "Field name: " + field.name.toString() + ", value: " + dp.getValue(field).asFloat();
Log.i(TAG, fieldValue)
}
}
}
Hope I helped anyone struggling with Google's horrible Api Documentation!
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论