【问题标题】:Not cheatable Google fit step counter不可作弊的 Google Fit 计步器
【发布时间】:2019-07-23 19:07:20
【问题描述】:

我有一个关于 Google 健身的问题。 我正在创建一个计步器(哦不知道 g)。到目前为止,我已经做到了这一点,而且并不难。 但是现在我们来解决我的问题。我只阅读传感器 API 的步骤。问题是,我可以通过例如 Google Fit 应用程序添加新数据,它也将计入我的应用程序。这引入了作弊,我不希望这样。

所以我需要有一种方法来只读取“设备创建”数据而不是手动添加的数据。有什么好的方法吗? 从 SDK 文档来看,这里并不清楚如何继续。

【问题讨论】:

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


    【解决方案1】:

    所以我需要有一种方法来只读取“设备创建”数据而不是 手动添加数据。有什么好的方法吗?

    您将需要使用Private Custom Data Types 来实现这一目标。了解您可以上传到 Google Fit here 的不同类型的健身数据。

    1.公共数据类型

    平台提供的标准数据类型,如 com.google.step_count.delta。任何应用程序都可以读取和写入数据 这些类型。有关详细信息,请参阅公共数据类型。

    2。私有自定义数据类型

    由特定应用定义的自定义数据类型。 只有定义了数据类型的应用才能读写数据 这种类型的。有关详细信息,请参阅自定义数据类型。

    3。可共享的数据类型

    应用开发者提交给平台的自定义数据类型。一旦获得批准,任何应用程序都可以读取 可共享类型,但仅限于由 开发人员可以写入该可共享类型的数据。了解更多信息, 请参阅可共享的数据类型。

    【讨论】:

      【解决方案2】:

      在这个算法的帮助下,我能够做到这一点。但请记住,由于 Android 碎片化,此代码仍会删除一些用户数据并将其计为惩罚

      private String dumpDataSet(DataSet dataSet, int x) {
          List<String> days = new ArrayList<>();
          days.add("Monday");
          days.add("Tuesday");
          days.add("Wednesday");
          days.add("Thursday");
          days.add("Friday");
          days.add("Saturday");
          days.add("Sunday");
      
          String day = days.get(Math.round(x / 24));
          Log.d(TAG, "\tDay: " + day);
          Log.i(TAG, "Data returned for Data type: " + dataSet.getDataType().getName());
          DateFormat dateFormat = getTimeInstance();
      
          String text = "";
          try {
              for (DataPoint dp : dataSet.getDataPoints()) {
                  Log.i(TAG, "\tStepCount getStreamName: " + dp.getOriginalDataSource().getStreamName());
                  Log.i(TAG, "\tStepCount getStreamIdentifier: " + dp.getOriginalDataSource().getStreamIdentifier());
                  Log.i(TAG, "\tStepCount App Type: " + dp.getDataType().getName());
                  Log.i(TAG, "\tStepCount Type: " + dp.getOriginalDataSource().getType());
      
                  for (Field field : dp.getDataType().getFields()) {
                      Log.i(TAG, "\tField: " + field.getName() + " Value: " + dp.getValue(field));
                      text += dp.getValue(field);
                      String si[] = dp.getOriginalDataSource().getStreamIdentifier().toLowerCase().split(":");
                      if ((((si[si.length - 1].contains("soft")) || (si[si.length - 1].contains("step"))) && si[si.length - 1].contains("counter"))) {
                          totalSteps += Integer.parseInt(dp.getValue(field).toString());
                          Log.d(TAG, "\tStepCount" + " Added Steps -> " + dp.getValue(field) + " steps");
                          text += "\n\n";
                      } else {
                          Log.e(TAG, "\tStepCount PENALTY ---------------------------------------------------------------");
                          Log.e(TAG, "\tDay = " + day + " | Hour Number = " + x + " | StepCount" + " PENALTY DEDUCTED -> " + dp.getValue(field) + " steps");
                          Log.e(TAG, "\tStepCount PENALTY getStreamIdentifier: " + dp.getOriginalDataSource().getStreamIdentifier());
                          Log.e(TAG, "\tStepCount PENALTY getStreamName: " + dp.getOriginalDataSource().getStreamName());
                          Log.e(TAG, "\tStepCount PENALTY App Type: " + dp.getDataType().getName());
                          Log.e(TAG, "\tStepCount PENALTY Type: " + dp.getOriginalDataSource().getType());
                          Log.e(TAG, "\tStepCount PENALTY ---------------------------------------------------------------");
                      }
                  }
              }
      
          } catch (Exception ex) {
              ex.getStackTrace();
          }
      
          return text;
      }
      

      ----- 更新 -----

      你也可以调用

      DataPoint.getOriginalDataSource().getAppPackageName()

      过滤掉智能手表和其他应用程序。

      【讨论】:

      • 已尝试 DataPoint.getOriginalDataSource().getAppPackageName() 并返回“null”。也尝试过 DataPoint.getOriginalDataSource().getStreamIdentifier() 并且它有一些不可读的值。
      【解决方案3】:

      我按照 Ali Shah lakhani 的建议尝试了,但是

      DataPoint.getOriginalDataSource().getAppPackageName();
      
      /*I also tried but could not achieve what I wanted*/
      
      DataPoint.getOriginalDataSource().getStreamName();
      DataPoint.getOriginalDataSource().getStreamIdentifier();
      
      

      在检索数据时至少对我不起作用。我最终使用如下所示的 readDailyTotalFromLocalDevice() 来捕获仅由设备捕获的步骤。

      Fitness.HistoryApi.readDailyTotalFromLocalDevice(mApiClient, DataType.TYPE_STEP_COUNT_DELTA).await(1, TimeUnit.MINUTES)
      

      我对一些避免在其应用程序中手动输入的应用程序进行了相同的检查,并且上述函数提供的计数完全相同。

      注意:如果用户拥有多台设备并在所有设备上使用该应用,则 readDailyTotalFromLocalDevice() 将为每台设备提供不同的值,因为函数只负责返回设备特定的数据。

      【讨论】:

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