无法在Google Fit API中累积过去一周的心率数据。

huangapple go评论78阅读模式
英文:

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(&quot;UTC&quot;))
        val now = Date()
        
        calendar.time = now
        val endTime = calendar.timeInMillis
        calendar.add(Calendar.WEEK_OF_YEAR, -1)
        val startTime = calendar.timeInMillis
    
        Log.i(TAG, &quot;Range Start: ${dateFormat.format(startTime)}&quot;)
        Log.i(TAG, &quot;Range End: ${dateFormat.format(endTime)}&quot;)
    
        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, &quot;Number of returned buckets of DataSets is: &quot; + dataReadResult.buckets.size)
                for (bucket in dataReadResult.buckets) {
                    bucket.dataSets.forEach { dumpDataSet(it) }
                }
            } else if (dataReadResult.dataSets.isNotEmpty()) {
                Log.i(TAG, &quot;Number of returned DataSets is: &quot; + 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, &quot;Data returned for Data type: ${dataSet.dataType.name}&quot;)
            val dateFormat: DateFormat = getTimeInstance()
            //THIS IS WHERE THE FOR LOOP DOESN&#39;T WORK!!
            for (dp in dataSet.dataPoints) {
                Log.i(TAG, &quot;Data point:&quot;)
                Log.i(TAG, &quot;\tType: ${dp.dataType.name}&quot;)
                Log.i(TAG, &quot;\tStart: ${dp.getStartTimeString()}&quot;)
                Log.i(TAG, &quot;\tEnd: ${dp.getEndTimeString()}&quot;)
                dp.dataType.fields.forEach {
                    Log.i(TAG, &quot;\tField: ${it.name} Value: ${dp.getValue(it)}&quot;)
                }
            }
        }
        // [END parse_dataset]


The only thing it gets logged is the data type which is the heart.rate.summary type.

Thefor loop doesn&#39;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(&quot;UTC&quot;))
        val now = Date()

                calendar.time = now
        val endTime = calendar.timeInMillis
        calendar.add(Calendar.WEEK_OF_YEAR, -1)
        val startTime = calendar.timeInMillis

        Log.i(TAG, &quot;Range Start: ${dateFormat.format(startTime)}&quot;)
        Log.i(TAG, &quot;Range End: ${dateFormat.format(endTime)}&quot;)

        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, &quot;Number of returned buckets of DataSets is: &quot; + 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, &quot;Number of returned DataSets is: &quot; + dataReadResult.dataSets.size)
            dataReadResult.dataSets.forEach { dumpDataSet(it) }
        }
        // [END parse_read_data_result]
    }

    // [START parse_dataset]
private fun dumpDataSet(dataSet: DataSet) {
	Log.i(TAG, &quot;Data returned for Data type: ${dataSet.dataType.name}&quot;)
	val dateFormat: DateFormat = getTimeInstance()
	for (dp:DataPoint in dataSet.dataPoints) {
		Log.i(TAG, &quot;\tStart: &quot; + dateFormat.format(dp.getStartTime(TimeUnit.MILLISECONDS)));
		Log.i(TAG, &quot;\tEnd: &quot; + dateFormat.format(dp.getEndTime(TimeUnit.MILLISECONDS)));
		Log.i(TAG, &quot;\tType: &quot; + dp.dataType.name);
		Log.i(TAG, &quot;TEST&quot;)
		for (field in dp.dataType.fields) {
			Log.i(TAG, &quot;TEST4&quot;)
			val fieldValue = &quot;Field name: &quot; + field.name.toString() + &quot;, value: &quot; + dp.getValue(field).asFloat();
			Log.i(TAG, fieldValue)
		}
	}
}

Hope I helped anyone struggling with Google's horrible Api Documentation!

huangapple
  • 本文由 发表于 2020年9月6日 23:35:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/63765894.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定