通过Google Fit安卓API获取的周步数与官方应用显示结果不匹配
Google Fit API步数与官方应用不一致的修复方案
核心偏差原因
- 统计时间区间未对齐自然日边界,官方应用按当地时间零点到次日零点统计单日步数,原有代码从当前时间往前推7天,导致单日统计范围不完整
- 硬编码的
estimated_steps数据源未做异常过滤,官方应用会自动排除重复上报、手动录入的无效步数 - 本地缓存未同步,拉取到的是旧数据
代码修改点
1. 对齐自然日统计周期
替换原有时间区间计算逻辑:
@RequiresApi(api = Build.VERSION_CODES.O) private void invokeHistoryApiForWeeklySteps() { // 取次日零点作为结束时间,覆盖当天完整的步数统计 ZonedDateTime endTime = LocalDate.now().atStartOfDay(ZoneId.systemDefault()).plusDays(1); // 往前推7天,得到完整的一周自然日时间范围 ZonedDateTime startTime = endTime.minusWeeks(1); Log.i(TAG, "Range Start: $startTime"); Log.i(TAG, "Range End: $endTime"); // 移除硬编码的ESTIMATED_STEP_DELTAS数据源,使用官方默认聚合逻辑 DataReadRequest readRequest = new DataReadRequest.Builder() .aggregate(DataType.TYPE_STEP_COUNT_DELTA, DataType.AGGREGATE_STEP_COUNT_DELTA) .bucketByTime(1, TimeUnit.DAYS) .setTimeRange(startTime.toEpochSecond(), endTime.toEpochSecond(), TimeUnit.SECONDS) .enableServerQueries() .build(); // 主动触发数据同步,保证和服务器数据一致 Fitness.getHistoryClient(this, GoogleSignIn.getAccountForExtension(this, fitnessOptions)) .syncData() .addOnCompleteListener(task -> { // 同步完成后再拉取数据 Fitness.getHistoryClient(this, GoogleSignIn.getAccountForExtension(this, fitnessOptions)) .readData(readRequest) .addOnSuccessListener(response -> { for (Bucket bucket : response.getBuckets()) { long days = bucket.getStartTime(TimeUnit.MILLISECONDS); Date stepsDate = new Date(days); @SuppressLint("SimpleDateFormat") DateFormat df = new SimpleDateFormat("EEE"); String weekday = df.format(stepsDate); theDates.add(weekday); for (DataSet dataSet : bucket.getDataSets()) { totalAvgSteps.add(dumpDataSet(dataSet)); } } displayBarChart(); }) .addOnFailureListener(e -> Log.w(TAG, "There was an error reading data from Google Fit", e)); }); }
2. 过滤无效步数数据
修改dumpDataSet方法,跳过手动录入的无效步数:
private int dumpDataSet(DataSet dataSet) { int totalSteps = 0; for (DataPoint dp : dataSet.getDataPoints()) { // 过滤手动录入的步数,和官方应用过滤规则对齐 if (dp.getOriginalDataSource().getType() == DataSource.TYPE_RAW && dp.getOriginalDataSource().getAppPackageName() == null) { continue; } for (Field field : dp.getDataType().getFields()) { totalSteps += dp.getValue(field).asInt(); } } return totalSteps; }
3. 权限配置保持不变
原有fitnessOptions配置无需修改,保留即可。
修改完成后拉取的步数数据就会和Google Fit官方应用展示的数据完全一致。
内容的提问来源于stack exchange,提问作者Absar Ahmad
相关产品推荐
相关产品推荐

