【问题标题】:Google Fit data pattern change since Google fit App update, implementation apparently broken自 Google Fit App 更新以来 Google Fit 数据模式发生变化,实施显然已损坏
【发布时间】:2021-01-19 09:00:49
【问题描述】:

我们在用户群中发现,自上次 google fit 应用更新以来,数据急剧下降,从一开始,我们就试图找出代码中的问题。给出时间,我们认为我们使用的版本(当时是 18.0)是问题所在。 升级到 SDK 20.0 并没有改善结果,但阻止了数据停滞。目前我们可以假设 50-60% 通过 SDK 连接到 google fit 的用户不再根据(以前的工作)实现正确地检索数据。它们并没有丢失,它们仍然在这里和那里发送一些比特,但它不再是以前的样子了。

这张图表展示了事件的时间线,这些事件让我们得出结论,其中一方一定做错了。

为了便于阅读,下面的代码示例已经去掉了大部分数据处理代码,但它确实存在。

我们的 Fitness 客户端在每次初始化时(无论是在前台还是后台)都会针对下面提到的所有类型以及其他类型(取决于应用程序)请求 FitnessOptions.ACCESS_READ,确保我们只请求用户接受的类型。

我们可以确认下一个数据类型在请求每日总计或本地设备每日总计时不再返回任何值,但在非聚合读取中请求时确实返回同一时期的数据块:

DataType.TYPE_STEP_COUNT_DELTA
DataType.TYPE_CALORIES_EXPENDED
DataType.TYPE_HEART_RATE_BPM

我们还尝试将那些可能的更改为它们的聚合对应物,但无济于事:

DataType.AGGREGATE_CALORIES_EXPENDED
DataType.AGGREGATE_STEP_COUNT_DELTA

这是我们当前的 getDailyTotal 实现,在更新之前工作,and is written straight out as the examples on the developer site show

    Fitness.getHistoryClient(context, account)
                .readDailyTotal(type)
                .addOnSuccessListener {
                    Logger.i("${type.name}::DailyTotal::Success")
                    onResponse(it)
                }

无论在一天中的什么时间询问,这当前都返回 0。

然后我们有我们的补充代码,它模拟了 getDailyTotal 在内部所做的事情,也根据开发人员网站示例: 来自:从 00:00:00 开始,UTC+1 至:23:59:59 结束,UTC+1 类型:任何数据类型。

    val readRequest = DataReadRequest.Builder()
                    .enableServerQueries()
                    .aggregate(type)
                    .bucketByTime(1, TimeUnit.DAYS)
                    .setTimeRange(from.time, to.time, TimeUnit.MILLISECONDS)
                    .build()
            val account = GoogleSignIn
                    .getAccountForExtension(context, fitnessOptions!!)
            GFitClient.request(context, account, readRequest) {
                if (it == null) {
                    aggregatedRequestError(type)
                } else {
                    Logger.i(TAG, "Aggregated ${type.name} received.")
                }
            }

这里的常见结果是 1) 一个 null 或空结果,2) 实际得到结果(在 DataType.TYPE_STEP_COUNT_DELTA 的情况下 有时 它发生)或3)一个APIException code 5012, this datatype can't be aggregated.

我们使用单聚合,因为可以由 (type, type.aggregate) 调用的双聚合已被弃用,因为已经有几个版本,尽管一些开发人员网站示例仍在使用它。

.enableServerQueries() 的使用(或不使用)不会修改最终结果。

最后,我们假设最坏的情况,无论如何我们都要求那天的任何东西,然后我们手动汇总。这通常会报告结果,而其他人则不会。遗憾的是,这些结果永远不足以让人感到舒服。

    val readRequest = DataReadRequest.Builder()
                        .enableServerQueries()
                        .read(type)
                        .bucketByTime(1, TimeUnit.DAYS)
                        .setTimeRange(from.time, to.time, TimeUnit.MILLISECONDS)
                        .build()
                val account = GoogleSignIn
                        .getAccountForExtension(context, fitnessOptions!!)

这往往可行,但鉴于数据集、存储桶和整体数据集结构的复杂嵌套性质,数据的手动处理很复杂。

我们还注意到在获取在 fit 应用上清晰可见但未出现在 SDK 上的数据时出现的问题,例如,华为健康活动出现在应用上,而 SDK 仅返回其中的子集,以及反过来,SDK 向我们返回数据(例如,一整晚的睡眠会话(轻、rem、深...),而 fit 应用程序显示与没有任何会话的单个睡眠块相同的睡眠。

第三方应用程序中显示的睡眠会话,SDK 返回给我们的数据相同:

Google 健身应用中显示的相同睡眠时段:

据文档所述:

对于 Android API,按数据类型读取,Fit 平台将 默认返回合并的流。这会自动包括所有 您的应用程序可用的数据,包括其他应用程序写入的数据。你 将无法查看数据来自哪些应用或设备的列表 来自 Android API。

我们认为合并流的行为不正常,不是实时的(这可能是由于应用程序直接从后端显示数据与 SDK 尚未写入数据之间存在延迟),但也不是在几分钟或几小时的差异中,有时永远不会出现。

为了了解我们如何检索这些数据,我们有一个背景WorkerManager CouroutineJob,每隔一段时间(当系统允许时,给予打盹模式权限,但我们更喜欢(并通过 WorkerManager 配置询问)是每小时或几个小时一次,以使数据与健身应用程序中显示的数据保持最新),我们请求从上次更新到最后一天的数据或/并且我们请求今天的每日总数(或直到当前时间,取决于我们走多远的“不起作用”漏斗,以及最后一次更新的日期)。

  • 我们的实现有什么问题吗?
  • Google 健身是否改变了向连接的应用报告数据的方式?
  • 我们能否以某种方式获得更真实的数据?
  • 有什么方法可以更有效地以不同方式请求相同的数据?我们最感兴趣的是获取每日摘要、总计和平均值,而不是时间段/会话。我们要求两者,但它们会进入不同的数据渠道,涵盖不同的用例。

【问题讨论】:

  • 你能解释一下第一张图显示的是什么吗?
  • "这里的常见结果是 1) null 或空结果" 如果您得到一个空结果,您能描述一下为什么会出乎意料吗?您是在 Fit 应用中还是通过 REST API 查看特定用户的数据?
  • @GraemeMorgan 第一张图显示了应用程序用户从 fit SDK 传递的数据量。如果你得到一个空的结果,你能描述一下为什么会出乎意料吗?您是在 Fit 应用程序中还是通过 REST API 查看特定用户的数据?是的,在第 1 种情况下,SDK 不会返回应用程序上的每日总数据。例如,requestDailyTotal(STEPS_COUNT_DELTA) 大多数时间返回一个没有任何数据点的数据集,而步骤存在并且在最后一次尝试中实际检索到,“最后我们假设最坏的情况......”
  • @GraemeMorgan 我想补充一点,第一张图显示了一个长期运行、未更改的应用程序,在 SDK 20.0 更新之前我们没有任何更新。部署新的 Fit 应用后,这种下降就开始了。
  • 图表额外细节:它是对每 6 小时内新交付的非累积数据的度量,仅与 SDK 相关。

标签: java android kotlin google-fit google-fit-sdk


【解决方案1】:

还没有答案。

我们的解决方案最终对数据进行了一系列繁琐的检查,每次失败时我们都会尝试不同的方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多