不可作弊 Google 适配计步器

Not cheatable Google fit step counter

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

所以我需要一种方法来只读取 "device created" 数据而不是手动添加数据。有什么好的方法吗? 从 SDK 文档来看,这里并不清楚如何进行。

So i need to have a way to only read "device created" data and not manually added data. Is there a nice way to to this?

您需要使用 Private Custom Data Types 来实现。了解您可以上传到 Google Fit here.

的不同类型的健身数据

1. Public data types

Standard data types provided by the platform, like com.google.step_count.delta. Any app can read and write data of these types. For more information, see Public Data Types.

2. Private custom data types

Custom data types defined by an specific app. Only the app that defines the data type can read and write data of this type. For more information, see Custom Data Types.

3. Shareable data types

Custom data types submitted to the platform by an app developer. Once approved, any app can read data of a shareable type, but only whitelisted apps as specified by the developer can write data of that shareable type. For more information, see Shareable Data Types.

我能够在这个算法的帮助下做到这一点。但请记住,由于 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()

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

我按照 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() 将有不同每个设备的值,因为该函数只负责返回设备特定数据。