如何通过Google Fit API正确读取已记录的锻炼运动名称及相关数据
Google Fit 运动数据读取问题解答
1. 正确的运动锻炼数据访问实现方式
你当前读取不到运动名称的核心原因是读取逻辑适配场景不全,正确实现可按以下步骤调整:
- 首先检查权限配置:必须同时完成两个权限申请,缺一不可
- 运行时权限申请
android.permission.ACTIVITY_RECOGNITION - 谷歌账号授权时,要在
FitnessOptions中显式添加DataType.TYPE_WORKOUT_EXERCISE的读权限
- 运行时权限申请
- 优先使用会话接口读取运动记录:大多数结构化的运动记录(包括系统同步、其他APP写入的运动)都是以
Session形式存储,比直接读HistoryClient的原始数据点更稳定,不用依赖零散的TYPE_WORKOUT_EXERCISE数据点 - 如果坚持使用HistoryClient,可先从bucket的activity属性读取运动类型:你当前用了
bucketByActivitySegment,每个bucket的getActivity()方法会返回运动类型的常量,直接用FitnessActivities.getName(bucket.getActivity())就能转成可读的运动名称,不用遍历数据点获取
2. 参考示例代码
以下是读取运动会话的标准示例,可直接整合到你的现有逻辑中:
// 构建会话读取请求 val sessionReadRequest = SessionReadRequest.Builder() .setTimeRange(start2B, end2B, TimeUnit.MILLISECONDS) .readSessionsFromAllApps() .read(DataType.TYPE_DISTANCE_DELTA) .read(DataType.TYPE_CALORIES_EXPENDED) .read(DataType.TYPE_HEART_RATE_BPM) .build() // 调用会话客户端读取数据 Fitness.getSessionsClient(this, account) .readSession(sessionReadRequest) .addOnSuccessListener { response -> // 遍历所有运动会话 for (session in response.sessions) { // 直接获取运动名称 val exerciseName = session.name ?: FitnessActivities.getName(session.activity) exerciseNames.add(exerciseName) // 读取该次运动对应的统计数据 for (dataSet in response.getDataSet(session)) { for (point in dataSet.dataPoints) { when (point.dataType) { DataType.TYPE_DISTANCE_DELTA -> distanceTotal.add(point.getValue(Field.FIELD_DISTANCE).asFloat()) DataType.TYPE_HEART_RATE_BPM -> heartRateTotal.add(point.getValue(Field.FIELD_BPM).asFloat()) DataType.TYPE_CALORIES_EXPENDED -> caloriesTotal.add(point.getValue(Field.FIELD_CALORIES).asFloat()) } } } } Log.i("GOOGLE-FIT", "读取结果:距离$distanceTotal 心率$heartRateTotal 卡路里$caloriesTotal 运动类型$exerciseNames") }
你可以保留原有HistoryClient的逻辑读取日常活动的累计数据,用上述会话逻辑读取结构化的单次运动记录,两者结合即可覆盖所有数据场景。
3. 官方技术支持渠道
- Google Issue Tracker的Fit API专属分区,可提交bug、功能请求,官方工程师会跟进处理
- Stack Overflow平台带
google-fit标签的技术提问区,官方开发人员会定期回复高优先级问题 - Google Fit开发者文档内置的反馈通道,可直接提交文档或接口相关的问题
内容的提问来源于stack exchange,提问作者TheBearF8
相关产品推荐
相关产品推荐

