Skip to content

Commit

Permalink
fixes #113
Browse files Browse the repository at this point in the history
  • Loading branch information
Dario Salvi committed Aug 20, 2018
1 parent 0c3671f commit 22fbde9
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 41 deletions.
6 changes: 4 additions & 2 deletions README.md
Expand Up @@ -264,19 +264,21 @@ Gets all the data points of a certain data type within a certain time window.
navigator.health.query({
startDate: new Date(new Date().getTime() - 3 * 24 * 60 * 60 * 1000), // three days ago
endDate: new Date(), // now
dataType: 'height'
dataType: 'height',
limit: 1000
}, successCallback, errorCallback)
```

- startDate: {type: Date}, start date from which to get data
- endDate: {type: Date}, end data to which to get the data
- dataType: {type: String}, the data type to be queried (see above)
- limit: {type: integer}, optional, sets a maximum number of returned values
- successCallback: {type: function(data) }, called if all OK, data contains the result of the query in the form of an array of: { startDate: Date, endDate: Date, value: xxx, unit: 'xxx', sourceName: 'aaaa', sourceBundleId: 'bbbb' }
- errorCallback: {type: function(err)}, called if something went wrong, err contains a textual description of the problem

#### iOS quirks

- The amount of datapoints is limited to 1000 by default. You can override this by adding a `limit: xxx` to your query object.
- Limit is set to 1000 by default.
- Datapoints are ordered in an descending fashion (from newer to older). You can revert this behaviour by adding `ascending: true` to your query object.
- HealthKit does not calculate active and basal calories - these must be inputted from an app
- HealthKit does not detect specific activities - these must be inputted from an app
Expand Down
84 changes: 45 additions & 39 deletions src/android/HealthPlugin.java
Expand Up @@ -518,9 +518,9 @@ private void checkAuthorization(final JSONArray args, final CallbackContext call
locationscope = READ_PERMS;
if (nutritiondatatypes.get(readType) != null)
nutritionscope = READ_PERMS;
if(healthdatatypes.get(readType) == HealthDataTypes.TYPE_BLOOD_GLUCOSE)
if (healthdatatypes.get(readType) == HealthDataTypes.TYPE_BLOOD_GLUCOSE)
bloodgucosescope = READ_PERMS;
if(healthdatatypes.get(readType) == HealthDataTypes.TYPE_BLOOD_PRESSURE)
if (healthdatatypes.get(readType) == HealthDataTypes.TYPE_BLOOD_PRESSURE)
bloodpressurescope = READ_PERMS;
}

Expand All @@ -533,9 +533,9 @@ private void checkAuthorization(final JSONArray args, final CallbackContext call
locationscope = READ_WRITE_PERMS;
if (nutritiondatatypes.get(readWriteType) != null)
nutritionscope = READ_WRITE_PERMS;
if(healthdatatypes.get(readWriteType) == HealthDataTypes.TYPE_BLOOD_GLUCOSE)
if (healthdatatypes.get(readWriteType) == HealthDataTypes.TYPE_BLOOD_GLUCOSE)
bloodgucosescope = READ_WRITE_PERMS;
if(healthdatatypes.get(readWriteType) == HealthDataTypes.TYPE_BLOOD_PRESSURE)
if (healthdatatypes.get(readWriteType) == HealthDataTypes.TYPE_BLOOD_PRESSURE)
bloodpressurescope = READ_WRITE_PERMS;
}

Expand Down Expand Up @@ -703,7 +703,9 @@ private void query(final JSONArray args, final CallbackContext callbackContext)
}
}

DataReadRequest readRequest = null;
DataReadRequest.Builder readRequestBuilder = new DataReadRequest.Builder();
readRequestBuilder.setTimeRange(st, et, TimeUnit.MILLISECONDS);

if (DT.equals(DataType.TYPE_STEP_COUNT_DELTA) && args.getJSONObject(0).has("filtered") && args.getJSONObject(0).getBoolean("filtered")) {
// exceptional case for filtered steps
DataSource filteredStepsSource = new DataSource.Builder()
Expand All @@ -713,19 +715,19 @@ private void query(final JSONArray args, final CallbackContext callbackContext)
.setAppPackageName("com.google.android.gms")
.build();

readRequest = new DataReadRequest.Builder()
.setTimeRange(st, et, TimeUnit.MILLISECONDS)
.read(filteredStepsSource)
.build();
readRequestBuilder.read(filteredStepsSource);
} else {
readRequest = new DataReadRequest.Builder()
.setTimeRange(st, et, TimeUnit.MILLISECONDS)
.read(dt)
.build();
readRequestBuilder.read(dt);
}

Integer limit = null;
if (args.getJSONObject(0).has("limit")) {
limit = args.getJSONObject(0).getInt("limit");
readRequestBuilder.setLimit(limit);
}

DataReadResult dataReadResult = Fitness.HistoryApi.readData(mClient, readRequest).await();

DataReadResult dataReadResult = Fitness.HistoryApi.readData(mClient, readRequestBuilder.build()).await();

if (dataReadResult.getStatus().isSuccess()) {
JSONArray resultset = new JSONArray();
Expand Down Expand Up @@ -784,12 +786,12 @@ else if (mealt == Field.MEAL_TYPE_SNACK)
Value nutrients = datapoint.getValue(Field.FIELD_NUTRIENTS);
NutrientFieldInfo fieldInfo = nutrientFields.get(datatype);
if (fieldInfo != null) {
if (nutrients.getKeyValue(fieldInfo.field) != null) {
obj.put("value", (float) nutrients.getKeyValue(fieldInfo.field));
} else {
obj.put("value", 0f);
}
obj.put("unit", fieldInfo.unit);
if (nutrients.getKeyValue(fieldInfo.field) != null) {
obj.put("value", (float) nutrients.getKeyValue(fieldInfo.field));
} else {
obj.put("value", 0f);
}
obj.put("unit", fieldInfo.unit);
}
}
} else if (DT.equals(DataType.TYPE_CALORIES_EXPENDED)) {
Expand Down Expand Up @@ -822,13 +824,16 @@ else if (mealt == Field.MEAL_TYPE_SNACK)
obj.put("unit", "activityType");

//extra queries to get calorie and distance records related to the activity times
DataReadRequest readActivityRequest = new DataReadRequest.Builder()
.setTimeRange(datapoint.getStartTime(TimeUnit.MILLISECONDS), datapoint.getEndTime(TimeUnit.MILLISECONDS), TimeUnit.MILLISECONDS)
DataReadRequest.Builder readActivityRequestBuilder = new DataReadRequest.Builder();
readActivityRequestBuilder.setTimeRange(datapoint.getStartTime(TimeUnit.MILLISECONDS), datapoint.getEndTime(TimeUnit.MILLISECONDS), TimeUnit.MILLISECONDS)
.read(DataType.TYPE_DISTANCE_DELTA)
.read(DataType.TYPE_CALORIES_EXPENDED)
.build();
.read(DataType.TYPE_CALORIES_EXPENDED);

if (limit != null) {
readActivityRequestBuilder.setLimit(limit);
}

DataReadResult dataReadActivityResult = Fitness.HistoryApi.readData(mClient, readActivityRequest).await();
DataReadResult dataReadActivityResult = Fitness.HistoryApi.readData(mClient, readActivityRequestBuilder.build()).await();

if (dataReadActivityResult.getStatus().isSuccess()) {
JSONArray distanceDataPoints = new JSONArray();
Expand All @@ -845,13 +850,14 @@ else if (mealt == Field.MEAL_TYPE_SNACK)
DataSource dataActivitySource = dataActivityPoint.getOriginalDataSource();
if (dataSource != null) {
String sourceName = dataActivitySource.getName();
if (sourceName != null) activityObj.put("sourceName", sourceName);
if (sourceName != null)
activityObj.put("sourceName", sourceName);
String sourceBundleId = dataSource.getAppPackageName();
if (sourceBundleId != null) activityObj.put("sourceBundleId", sourceBundleId);
if (sourceBundleId != null)
activityObj.put("sourceBundleId", sourceBundleId);
}

if (dataActivitySet.getDataType().equals(DataType.TYPE_DISTANCE_DELTA))
{
if (dataActivitySet.getDataType().equals(DataType.TYPE_DISTANCE_DELTA)) {
float distance = dataActivityPoint.getValue(Field.FIELD_DISTANCE).asFloat();
activityObj.put("value", distance);
activityObj.put("unit", "m");
Expand Down Expand Up @@ -965,11 +971,11 @@ else if (mealt == Field.MEAL_TYPE_SNACK)
obj.put("unit", "mmol/L");
} else if (DT.equals(HealthDataTypes.TYPE_BLOOD_PRESSURE)) {
JSONObject bpobj = new JSONObject();
if (datapoint.getValue(HealthFields.FIELD_BLOOD_PRESSURE_SYSTOLIC).isSet()){
if (datapoint.getValue(HealthFields.FIELD_BLOOD_PRESSURE_SYSTOLIC).isSet()) {
float systolic = datapoint.getValue(HealthFields.FIELD_BLOOD_PRESSURE_SYSTOLIC).asFloat();
bpobj.put("systolic", systolic);
}
if (datapoint.getValue(HealthFields.FIELD_BLOOD_PRESSURE_DIASTOLIC).isSet()){
if (datapoint.getValue(HealthFields.FIELD_BLOOD_PRESSURE_DIASTOLIC).isSet()) {
float diastolic = datapoint.getValue(HealthFields.FIELD_BLOOD_PRESSURE_DIASTOLIC).asFloat();
bpobj.put("diastolic", diastolic);
}
Expand Down Expand Up @@ -1219,7 +1225,7 @@ private void queryAggregated(final JSONArray args, final CallbackContext callbac
} else if (datatype.equalsIgnoreCase("activity")) {
retBucket.put("unit", "activitySummary");
// query per bucket time to get distance and calories per activity
JSONObject actobj = getAggregatedActivityDistanceCalories (st, et);
JSONObject actobj = getAggregatedActivityDistanceCalories(st, et);
retBucket.put("value", actobj);
} else if (datatype.equalsIgnoreCase("nutrition.water")) {
retBucket.put("unit", "ml");
Expand Down Expand Up @@ -1263,7 +1269,7 @@ private void queryAggregated(final JSONArray args, final CallbackContext callbac
} else if (datatype.equalsIgnoreCase("activity")) {
retBucket.put("unit", "activitySummary");
// query per bucket time to get distance and calories per activity
JSONObject actobj = getAggregatedActivityDistanceCalories (bucket.getStartTime(TimeUnit.MILLISECONDS), bucket.getEndTime(TimeUnit.MILLISECONDS));
JSONObject actobj = getAggregatedActivityDistanceCalories(bucket.getStartTime(TimeUnit.MILLISECONDS), bucket.getEndTime(TimeUnit.MILLISECONDS));
retBucket.put("value", actobj);
} else if (datatype.equalsIgnoreCase("nutrition.water")) {
retBucket.put("unit", "ml");
Expand Down Expand Up @@ -1359,15 +1365,15 @@ private void queryAggregated(final JSONArray args, final CallbackContext callbac
}
}

private JSONObject getAggregatedActivityDistanceCalories (long st, long et) throws JSONException {
private JSONObject getAggregatedActivityDistanceCalories(long st, long et) throws JSONException {
JSONObject actobj = new JSONObject();

DataReadRequest readActivityDistCalRequest = new DataReadRequest.Builder()
.aggregate(DataType.TYPE_DISTANCE_DELTA, DataType.AGGREGATE_DISTANCE_DELTA)
.aggregate(DataType.TYPE_CALORIES_EXPENDED, DataType.AGGREGATE_CALORIES_EXPENDED)
.bucketByActivityType(1, TimeUnit.SECONDS)
.setTimeRange(st, et, TimeUnit.MILLISECONDS)
.build();
.aggregate(DataType.TYPE_DISTANCE_DELTA, DataType.AGGREGATE_DISTANCE_DELTA)
.aggregate(DataType.TYPE_CALORIES_EXPENDED, DataType.AGGREGATE_CALORIES_EXPENDED)
.bucketByActivityType(1, TimeUnit.SECONDS)
.setTimeRange(st, et, TimeUnit.MILLISECONDS)
.build();

DataReadResult dataActivityDistCalReadResult = Fitness.HistoryApi.readData(mClient, readActivityDistCalRequest).await();

Expand Down

0 comments on commit 22fbde9

Please sign in to comment.