Search code examples
androidgoogle-play-servicesgoogle-fitgoogle-fit-sdk

DataSource.getAppPackageName() always returns "com.google.android.gms" in Google Fit


My app is reading weight data from Google Fit. The data were inserted by Withings and by my own app. But this doesn't make any difference when I call dataSet.getDataSource().getAppPackageName(), because it always returns com.google.android.gms. So I have no chance of knowing where the data came from. Google describes how to get information of the data source in this article: https://developers.google.com/fit/android/data-attribution Unfortunately this is completely useless to me.

I'm using Google Play Services 8.3.0, tested using Android 4.3, 4.4.2 and 6.0.1.

Can anyone confirm the same behavior? Or am I doing something wrong? Any feedback is appreciated.

public void connect(final Activity activity) {
    client = new GoogleApiClient.Builder(activity)
        .addApi(Fitness.HISTORY_API)
        .addApi(Fitness.CONFIG_API)
        .addScope(new Scope(Scopes.FITNESS_ACTIVITY_READ_WRITE))
        .addScope(new Scope(Scopes.FITNESS_BODY_READ_WRITE))
        .build();
    client.connect();
}

public DataReadResult readWeightValues(final Date startDate, final Date endDate) {
    final DataReadRequest readRequest = new DataReadRequest.Builder()
        .enableServerQueries()
        .setTimeRange(startDate.getTime(), endDate.getTime(), TimeUnit.MILLISECONDS)
        .read(DataType.TYPE_WEIGHT)
        .build();

    return Fitness.HistoryApi.readData(client, readRequest).await(1, TimeUnit.MINUTES);
}

public void examineWeightValues(final DataReadResult dataReadResult) {
    if ((dataReadResult != null) && dataReadResult.getStatus().isSuccess()) {
        if (!dataReadResult.getBuckets().isEmpty()) {
            for (final Bucket bucket : dataReadResult.getBuckets()) {
                final List<DataSet> dataSets = bucket.getDataSets();
                for (final DataSet dataSet : dataSets) {
                    Log.i("=====>", dataSet.getDataSource().getAppPackageName());
                }
            }
        }

        if (!dataReadResult.getDataSets().isEmpty()) {
            for (final DataSet dataSet : dataReadResult.getDataSets()) {
                Log.i("=====>", dataSet.getDataSource().getAppPackageName());
            }
        }
    }
}

public Status insertWeightValue(final Context context, final Date date, final float weightKg) {
    final DataSource dataSource = new DataSource.Builder()
        .setAppPackageName(context.getApplicationContext().getPackageName())
        // already tried setAppPackageName(context) too
        .setName("com.mycompany.myapp")
        .setDataType(DataType.TYPE_WEIGHT)
        .setType(DataSource.TYPE_RAW)
        .build();

    final DataSet dataSet = DataSet.create(dataSource);

    final DataPoint dataPoint = dataSet.createDataPoint();
    dataPoint.setTimestamp(date.getTime(), TimeUnit.MILLISECONDS);
    dataPoint.getValue(Field.FIELD_WEIGHT).setFloat(weightKg);
    dataSet.add(dataPoint);

    return Fitness.HistoryApi.insertData(client, dataSet).await(1, TimeUnit.MINUTES);
}

Solution

  • DataPoint.getOriginalDataSource().getAppPackageName() will do the trick. It returns com.withings.wiscale2 for my Withings scale.

    Note: There was an answer that suggested this solution yesterday evening, but this morning it's gone. I don't know what happened here, but unfortunately I have no idea of the author of the disappeared answer. Anyway, I want to say thank you for pointing me in the right direction!