Not cheatable Google fit step counter

拥有回忆 提交于 2019-12-03 21:58:30

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?

You will want to use Private Custom Data Types to achieve that. Read about the different types of Fitness data you can upload to 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.

I was able to do this with the help of this alogrithm. But remember due to Android fragmentation this code still removes some of the user's data and count it as penalty

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;
}

----- UPDATE -----

You can also call

DataPoint.getOriginalDataSource().getAppPackageName()

to filter out smartwatches and other apps.

I tried as suggested by Ali Shah lakhani but

DataPoint.getOriginalDataSource().getAppPackageName();

/*I also tried but could not achieve what I wanted*/

DataPoint.getOriginalDataSource().getStreamName();
DataPoint.getOriginalDataSource().getStreamIdentifier();

did not work at least for me while retrieving data. I ended up using readDailyTotalFromLocalDevice() as shown below in order to capture steps captured by device only.

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

I cross checked the same with some of the apps that avoids manual entries in their app and the count provided by the function above is exactly the same.

Note: If a user is having multiple devices and is using the app on all of them, readDailyTotalFromLocalDevice() will have different value for each and every device since the function is responsible for returning device specific data only.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!