We use essential cookies for the website to function, as well as analytics cookies for analyzing and creating statistics of the website performance. To agree to the use of analytics cookies, click "Accept All". You can manage your preferences at any time by clicking "Cookie Settings" on the footer. More Information.

Only Essential Cookies
Accept All

Managing Health Records

After integrating Health Service Kit, you can manage users' health records by calling APIs in the HealthRecordController class.

NOTE
  1. Before calling APIs provided by the Health Service Kit SDK for Android, make sure that the phone screen is unlocked and remains on. Otherwise, API calling may fail with the error code DISABLE_DATA_OPERATION. For details, please refer to error codes.
  2. Before calling APIs provided by the Health Service Kit SDK, make sure that your app runs in the foreground, or is bound with a foreground app. Otherwise, API calling may fail with the error code APPLICATION_NOT_FORGROUND. For details, please refer to error codes.
  3. If the Activity object (called in scenarios where app UIs are included) is passed when HuaweiHiHealth.getHealthRecordController is used to obtain the HealthRecordController object, the HMS Core version can be updated forcibly. If the Context object (called in scenarios where app UIs are not included) is passed, the HMS Core version cannot be updated forcibly.
  4. Learn how to call APIs provided by the Health Service Kit SDK for Android by referring to Example of Calling APIs of the Health Service Kit SDK for Android before API calling.

Writing Health Records to Health Service Kit

You can use HealthRecordController to write health records to Health Service Kit as follows:

  1. Check whether your app has the scope to operate on the health record data. For details about the data types, please refer to health record data types.
  2. Create a HealthRecord object and specify the collector, time range, health data statistics, health data details, and other required information.
  3. Create a HealthRecordInsertOptions object using HealthRecord.
  4. Insert HealthRecordInsertOptions into Health Service Kit using the HealthRecordController.addHealthRecord method.

    Keep HealthRecordId in the callback of addHealthRecord properly, so that you can use it for later Service updates of health records in Health Service Kit.
    NOTE

    The start time and end time passed for inserting health records must be later than the UNIX timestamp corresponding to January 1, 2014.

The following is the sample code for inserting the health record of a supported data type, the bradycardia data type.

Collapse
Word wrap
Dark theme
Copy code
  1. // Note:
  2. // 1. this refers to an Activity object.
  3. // 2. Initialize objects of the HealthRecordController class each time before API calling. Otherwise, data reading may fail due to expired Activity or Context.
  4. HealthRecordController healthRecordController = HuaweiHiHealth.getHealthRecordController(this);
  5. // Set the start time and end time of the request body.
  6. Calendar cal = Calendar.getInstance();
  7. Date now = new Date();
  8. cal.setTime(now);
  9. long endTime = cal.getTimeInMillis();
  10. cal.add(Calendar.HOUR_OF_DAY, -1);
  11. long startTime = cal.getTimeInMillis();
  12. // 1. Create a collector that carries heart rate details and sampleSetList that stores heart rate details.
  13. DataCollector dataCollector =
  14. new com.huawei.hms.hihealth.data.DataCollector.Builder().setDataType(DataType.DT_INSTANTANEOUS_HEART_RATE)
  15. .setDataGenerateType(DataCollector.DATA_TYPE_RAW)
  16. .setPackageName(context)
  17. .setDataStreamName("such as step count")
  18. .build();
  19. SampleSet sampleSet = SampleSet.create(dataCollector);
  20. // Set the preset time span to 5 minutes, and the heart rate value of the sampling point to 88.
  21. SamplePoint samplePoint =
  22. sampleSet.createSamplePoint().setTimeInterval(startTime , startTime + 300000L, TimeUnit.MILLISECONDS);
  23. samplePoint.getFieldValue(Field.FIELD_BPM).setDoubleValue(88);
  24. sampleSet.addSample(samplePoint);
  25. // Set sampleSetList for storing health details.
  26. List<SampleSet> sampleSetList = new ArrayList<>();
  27. sampleSetList.add(sampleSet);
  28. // Set samplePointList for storing statistical data points.
  29. List<SamplePoint> samplePointList = new ArrayList<>();
  30. // 2. Build a statistical data point for heart rate.
  31. SamplePoint samplePoint1 = new SamplePoint.Builder(DataType.POLYMERIZE_CONTINUOUS_HEART_RATE_STATISTICS).build();
  32. samplePoint1.getFieldValue(Field.FIELD_AVG).setDoubleValue(90);
  33. samplePoint1.getFieldValue(Field.FIELD_MAX).setDoubleValue(100);
  34. samplePoint1.getFieldValue(Field.FIELD_MIN).setDoubleValue(80);
  35. samplePoint1.getFieldValue(Field.FIELD_LAST).setDoubleValue(80);
  36. samplePoint1.setTimeInterval(startTime + 1L, startTime + 300000L, TimeUnit.MILLISECONDS);
  37. samplePointList.add(samplePoint1);
  38. // 3. Build a health record collector (using the bradycardia data type as an example) and a health record structure.
  39. DataCollector dataCollector2 = new com.huawei.hms.hihealth.data.DataCollector.Builder()
  40. .setDataType(HealthDataTypes.DT_HEALTH_RECORD_BRADYCARDIA)
  41. .setDataGenerateType(DataCollector.DATA_TYPE_RAW)
  42. .setPackageName(context)
  43. .setDataStreamName("such as step count")
  44. .build();
  45. HealthRecord.Builder healthRecordBuilder =
  46. new HealthRecord.Builder(dataCollector2).setSubDataSummary(samplePointList)
  47. .setSubDataDetails(sampleSetList)
  48. .setStartTime(startTime, TimeUnit.MILLISECONDS)
  49. .setEndTime(endTime, TimeUnit.MILLISECONDS);
  50. // Set a value for each field of the bradycardia data type.
  51. healthRecordBuilder.setFieldValue(HealthFields.FIELD_THRESHOLD, 40d);
  52. healthRecordBuilder.setFieldValue(HealthFields.FIELD_AVG_HEART_RATE, 44d);
  53. healthRecordBuilder.setFieldValue(HealthFields.FIELD_MAX_HEART_RATE, 48d);
  54. healthRecordBuilder.setFieldValue(HealthFields.FIELD_MIN_HEART_RATE, 40d);
  55. HealthRecord healthRecord = healthRecordBuilder.build();
  56. HealthRecordInsertOptions insertOptions =
  57. new HealthRecordInsertOptions.Builder().setHealthRecord(healthRecord).build();
  58. healthRecordController.addHealthRecord(insertOptions).addOnSuccessListener(new OnSuccessListener<String>() {
  59. @Override
  60. public void onSuccess(String healthRecordId) {
  61. // Save the returned healthRecordId, which is used for modification.
  62. healthRecordIdFromInsertResult = healthRecordId;
  63. logger("The health record is added successfully,please save the healthRecordId! " + healthRecordId);
  64. }
  65. }).addOnFailureListener(new OnFailureListener() {
  66. @Override
  67. public void onFailure(Exception e) {
  68. logger(e.toString());
  69. }
  70. });
NOTE

If you directly copy and use the preceding sample code, the following errors will be reported. The related solutions are provided as follows:

  1. The helper function logger is not defined.
    Solution: Define the logger function and do not perform any operation. For details, please refer to the following sample code.
    Collapse
    Word wrap
    Dark theme
    Copy code
    1. private static final String TAG = "HealthRecordController";
    2. /**
    3. * Also send operation result logs to the logcat.
    4. *
    5. * @param string Log string
    6. */
    7. private void logger(String string) {
    8. Log.i(TAG, string);
    9. }
  2. The character string variable healthRecordIdFromInsertResult is not defined.

    Solution: healthRecordIdFromInsertResult is used as the parameter for calling updateHealthRecord. The definition is as follows. Assign a value to healthRecordIdFromInsertResult after addHealthRecord is successfully called.

    Collapse
    Word wrap
    Dark theme
    Copy code
    1. private String healthRecordIdFromInsertResult = "";

Deleting Health Records from Health Service Kit

You can delete health records through HealthRecordController as follows:

  1. Create a HealthRecordDeleteOptions object based on healthRecordIds, data type, or the start time and end time.
  2. Call HealthRecordController.deleteHealthRecord to delete HealthRecordDeleteOptions from Health Service Kit.
    NOTE
    1. The start time and end time passed for deleting health records must be later than the UNIX timestamp corresponding to January 1, 2014.
    2. If healthRecordIds is not empty, it will be used to delete health records. Otherwise, health records will be deleted based on the data type or the start and end times.

Sample code for deleting health records from Health Service Kit:

Collapse
Word wrap
Dark theme
Copy code
  1. // Note:
  2. // 1. this refers to an Activity object.
  3. // 2. Initialize objects of the HealthRecordController class each time before API calling. Otherwise, data reading may fail due to expired Activity or Context.
  4. HealthRecordController healthRecordController = HuaweiHiHealth.getHealthRecordController(this);
  5. // Build the time range of the request object: start time and end time.
  6. // Note that the start time and end time must be later than the UNIX timestamp corresponding to January 1, 2014.
  7. Calendar cal = Calendar.getInstance();
  8. Date now = new Date();
  9. cal.setTime(now);
  10. long endTime = cal.getTimeInMillis();
  11. cal.add(Calendar.DAY_OF_YEAR, -2);
  12. long startTime = cal.getTimeInMillis();
  13. // Build dataType for the request object.
  14. DataType dataType = HealthDataTypes.DT_HEALTH_RECORD_BRADYCARDIA;
  15. // Build subDataTypeList for the request object.
  16. List<DataType> subDataTypeList = Collections.singletonList(DataType.DT_INSTANTANEOUS_HEART_RATE);
  17. // Build healthRecordIds for the request object.
  18. List<String> healthRecordIds = Collections.singletonList("healthRecordIdFromInsertResult");
  19. // Build the request body with the deletion object.
  20. HealthRecordDeleteOptions deleteRequest = new HealthRecordDeleteOptions.Builder()
  21. .setHealthRecordIds(healthRecordIds)
  22. .isDeleteSubData(true)
  23. .setDataType(dataType)
  24. .setSubDataTypeList(subDataTypeList)
  25. .setTimeInterval(startTime, endTime, TimeUnit.MILLISECONDS).build();
  26. // Call deleteHealthRecord to delete the health record.
  27. Task<Void> deleteTask = healthRecordController.deleteHealthRecord(deleteRequest);
  28. deleteTask.addOnSuccessListener(new OnSuccessListener<Void>() {
  29. @Override
  30. public void onSuccess(Void aVoid) {
  31. Log.i("HealthRecords","HealthRecord deleted successfully.!");
  32. }
  33. }).addOnFailureListener(new OnFailureListener() {
  34. @Override
  35. public void onFailure(Exception e) {
  36. Log.i("HealthRecords","Failed to delete data" + e.getMessage());
  37. }
  38. });

Updating Health Records in Health Service Kit

You can use HealthRecordController to update health records that have been written to Health Service Kit as follows:

  1. Check whether your app has the scope to operate on the health record data. For details about the data types, please refer to health record data types.
  2. Create a HealthRecord object and specify the collector, time range, health data statistics, health data details, and other required information.
  3. Create a HealthRecordUpdateOptions object using HealthRecord and HealthRecordId that is used in the callback for writing health records to Health Service Kit.
  4. Update health records and related data in Health Service Kit using the HealthRecordController.updateHealthRecord method.

    NOTE

    1. The start time and end time passed for inserting health records must be later than the UNIX timestamp corresponding to January 1, 2014.

    2. If no health record matching HealthRecordId is found, an error code will be thrown.

The following is the sample code for updating the health record of a supported data type, the bradycardia data type.

Collapse
Word wrap
Dark theme
Copy code
  1. // Note:
  2. // 1. this refers to an Activity object.
  3. // 2. Initialize objects of the HealthRecordController class each time before API calling. Otherwise, data reading may fail due to expired Activity or Context.
  4. HealthRecordController healthRecordController = HuaweiHiHealth.getHealthRecordController(this);
  5. // Set the start time and end time of the request body.
  6. Calendar cal = Calendar.getInstance();
  7. Date now = new Date();
  8. cal.setTime(now);
  9. long endTime = cal.getTimeInMillis();
  10. cal.add(Calendar.HOUR_OF_DAY, -1);
  11. long startTime = cal.getTimeInMillis();
  12. // 1. Create a collector that carries heart rate details and sampleSetList that stores heart rate details.
  13. DataCollector dataCollector =
  14. new com.huawei.hms.hihealth.data.DataCollector.Builder().setDataType(DataType.DT_INSTANTANEOUS_HEART_RATE)
  15. .setDataGenerateType(DataCollector.DATA_TYPE_RAW)
  16. .setPackageName(context)
  17. .setDataStreamName("such as step count")
  18. .build();
  19. SampleSet sampleSet = SampleSet.create(dataCollector);
  20. // Set the preset time span to 5 minutes, and the heart rate value of the sampling point to 90.
  21. SamplePoint samplePoint =
  22. sampleSet.createSamplePoint().setTimeInterval(startTime , startTime + 300000L, TimeUnit.MILLISECONDS);
  23. samplePoint.getFieldValue(Field.FIELD_BPM).setDoubleValue(90);
  24. sampleSet.addSample(samplePoint);
  25. // Set sampleSetList for storing health details.
  26. List<SampleSet> sampleSetList = new ArrayList<>();
  27. sampleSetList.add(sampleSet);
  28. // Set samplePointList for storing statistical data points.
  29. List<SamplePoint> samplePointList = new ArrayList<>();
  30. // 2. Build a statistical data point for heart rate.
  31. SamplePoint samplePoint1 = new SamplePoint.Builder(DataType.POLYMERIZE_CONTINUOUS_HEART_RATE_STATISTICS).build();
  32. samplePoint1.getFieldValue(Field.FIELD_AVG).setDoubleValue(90);
  33. samplePoint1.getFieldValue(Field.FIELD_MAX).setDoubleValue(100);
  34. samplePoint1.getFieldValue(Field.FIELD_MIN).setDoubleValue(80);
  35. samplePoint1.getFieldValue(Field.FIELD_LAST).setDoubleValue(80);
  36. samplePoint1.setTimeInterval(startTime + 1L, startTime + 300000L, TimeUnit.MILLISECONDS);
  37. samplePointList.add(samplePoint1);
  38. // 3. Build a health record collector (using the bradycardia data type as an example) and a health record structure.
  39. DataCollector dataCollector2 = new com.huawei.hms.hihealth.data.DataCollector.Builder()
  40. .setDataType(HealthDataTypes.DT_HEALTH_RECORD_BRADYCARDIA)
  41. .setDataGenerateType(DataCollector.DATA_TYPE_RAW)
  42. .setPackageName(context)
  43. .setDataStreamName("such as step count")
  44. .build();
  45. HealthRecord.Builder healthRecordBuilder =
  46. new HealthRecord.Builder(dataCollector2).setSubDataSummary(samplePointList)
  47. .setSubDataDetails(sampleSetList)
  48. .setStartTime(startTime, TimeUnit.MILLISECONDS)
  49. .setEndTime(endTime, TimeUnit.MILLISECONDS);
  50. // Set a value for each field of the bradycardia data type.
  51. healthRecordBuilder.setFieldValue(HealthFields.FIELD_THRESHOLD, 42d);
  52. healthRecordBuilder.setFieldValue(HealthFields.FIELD_AVG_HEART_RATE, 45d);
  53. healthRecordBuilder.setFieldValue(HealthFields.FIELD_MAX_HEART_RATE, 48d);
  54. healthRecordBuilder.setFieldValue(HealthFields.FIELD_MIN_HEART_RATE, 42d);
  55. HealthRecord healthRecord = healthRecordBuilder.build();
  56. // 4. Build updateOptions to be updated. Remember to carry healthRecordId, which will be returned after the insertion is successful.
  57. HealthRecordUpdateOptions updateOptions = new HealthRecordUpdateOptions.Builder().setHealthRecord(healthRecord)
  58. .setHealthRecordId(healthRecordIdFromInsertResult)
  59. .build();
  60. healthRecordController.updateHealthRecord(updateOptions).addOnSuccessListener(new OnSuccessListener<Void>() {
  61. @Override
  62. public void onSuccess(Void aVoid) {
  63. logger("Health record updated successfully.");
  64. }
  65. }).addOnFailureListener(new OnFailureListener() {
  66. @Override
  67. public void onFailure(Exception e) {
  68. logger(e.toString());
  69. }
  70. });
NOTE

If you directly copy and use the preceding sample code, the following errors will be reported. The related solutions are provided as follows:

  1. healthRecordIdFromInsertResult is not defined.

    Solution: Define the string variable using the value of HealthRecordId that is used in the callback for writing health records to Health Service Kit.

  2. The helper function logger is not defined.
    Solution: Define the logger function as follows:
    Collapse
    Word wrap
    Dark theme
    Copy code
    1. private static final String TAG = "HealthRecordController";
    2. /**
    3. * Also send operation result logs to the logcat.
    4. *
    5. * @param string Log string
    6. */
    7. private void logger(String string) {
    8. Log.i(TAG, string);
    9. }

Querying Health Records in Health Service Kit

You can use HealthRecordController to query health records that have been written to Health Service Kit as follows:

  • Check whether your app has the scope to operate on the health record data. For details about the data types, please refer to health record data types.
  • Create a HealthRecordReadOptions object based on the query time and related conditions.
  • Uses the HealthRecordController.getHealthRecord method to query health records in Health Service Kit.
    NOTE
    1. The start time and end time for querying health records must be later than the UNIX timestamp corresponding to January 1, 2014.
    2. The start time and end time for querying cannot span over 31 days.

The following is the sample code for querying the health record of a supported data type, the bradycardia data type.

Collapse
Word wrap
Dark theme
Copy code
  1. // Note:
  2. // 1. this refers to an Activity object.
  3. // 2. Initialize objects of the HealthRecordController class each time before API calling. Otherwise, data reading may fail due to expired Activity or Context.
  4. HealthRecordController healthRecordController = HuaweiHiHealth.getHealthRecordController(this);
  5. // Set the start time and end time of the request body.
  6. Calendar cal = Calendar.getInstance();
  7. Date now = new Date();
  8. cal.setTime(now);
  9. long endTime = cal.getTimeInMillis();
  10. cal.add(Calendar.DAY_OF_YEAR, -1);
  11. long startTime = cal.getTimeInMillis();
  12. // Build the HealthRecordReadOptions parameter for reading health records.
  13. List<DataType> subDataTypeList = new ArrayList<>();
  14. subDataTypeList.add(DataType.DT_INSTANTANEOUS_HEART_RATE);
  15. HealthRecordReadOptions healthRecordReadOptions =
  16. new HealthRecordReadOptions.Builder().setTimeInterval(startTime, endTime, TimeUnit.MILLISECONDS)
  17. .readHealthRecordsFromAllApps()
  18. .readByDataType(HealthDataTypes.DT_HEALTH_RECORD_BRADYCARDIA)
  19. .setSubDataTypeList(subDataTypeList)
  20. .build();
  21. // Pass the HealthRecordReadOptions parameter to query the health record.
  22. Task<HealthRecordReply> task = healthRecordController.getHealthRecord(healthRecordReadOptions);
  23. task.addOnSuccessListener(new OnSuccessListener<HealthRecordReply>() {
  24. @Override
  25. public void onSuccess(HealthRecordReply readResponse) {
  26. logger("Get HealthRecord was successful!");
  27. // Print the obtained health records.
  28. List<HealthRecord> recordList = readResponse.getHealthRecords();
  29. for (HealthRecord record : recordList) {
  30. if (record == null) {
  31. continue;
  32. }
  33. dumpHealthRecord(record);
  34. logger("Print detailed data points associated with health records");
  35. for (SampleSet dataSet : record.getSubDataDetails()) {
  36. dumpDataSet(dataSet);
  37. }
  38. }
  39. }
  40. });
  41. task.addOnFailureListener(new OnFailureListener() {
  42. @Override
  43. public void onFailure(Exception e) {
  44. logger(e.toString());
  45. }
  46. });
NOTE

If you directly copy and use the preceding sample code, the following errors will be reported. The related solutions are provided as follows:

  1. The helper function logger is not defined.
    Solution: Define the logger function as follows:
    Collapse
    Word wrap
    Dark theme
    Copy code
    1. private static final String TAG = "HealthRecordController";
    2. /**
    3. * Also send operation result logs to the logcat.
    4. *
    5. * @param string Log string
    6. */
    7. private void logger(String string) {
    8. Log.i(TAG, string);
    9. }
  2. The helper function dumpHealthRecord is not defined.

    Solution: Define the dumpHealthRecord function as follows:

    Collapse
    Word wrap
    Dark theme
    Copy code
    1. /**
    2. * Print the information in the HealthRecord object.
    3. *
    4. * @param healthRecord Health record object
    5. */
    6. private void dumpHealthRecord(HealthRecord healthRecord) {
    7. logger("Print health record summary information!");
    8. DateFormat dateFormat = DateFormat.getDateInstance();
    9. DateFormat timeFormat = DateFormat.getTimeInstance();
    10. if (healthRecord != null) {
    11. logger("\tHealthRecordIdentifier: " + healthRecord.getHealthRecordId() + "\n\tpackageName: "
    12. + healthRecord.getDataCollector().getPackageName() + "\n\tStartTime: "
    13. + dateFormat.format(healthRecord.getStartTime(TimeUnit.MILLISECONDS)) + " "
    14. + timeFormat.format(healthRecord.getStartTime(TimeUnit.MILLISECONDS)) + "\n\tEndTime: "
    15. + dateFormat.format(healthRecord.getEndTime(TimeUnit.MILLISECONDS)) + " "
    16. + timeFormat.format(healthRecord.getEndTime(TimeUnit.MILLISECONDS)) + "\n\tHealthRecordDataType: "
    17. + healthRecord.getDataCollector().getDataType().getName() + "\n\tHealthRecordDataCollectorId: "
    18. + healthRecord.getDataCollector().getDataStreamId() + "\n\tmetaData: " + healthRecord.getMetadata()
    19. + "\n\tFileValueMap: " + healthRecord.getFieldValues());
    20. if (healthRecord.getSubDataSummary() != null && !healthRecord.getSubDataSummary().isEmpty()) {
    21. SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
    22. for (SamplePoint samplePoint : healthRecord.getSubDataSummary()) {
    23. logger("Sample point type: " + samplePoint.getDataType().getName());
    24. logger("Start: " + sDateFormat.format(new Date(samplePoint.getStartTime(TimeUnit.MILLISECONDS))));
    25. logger("End: " + sDateFormat.format(new Date(samplePoint.getEndTime(TimeUnit.MILLISECONDS))));
    26. for (Field field : samplePoint.getDataType().getFields()) {
    27. logger("Field: " + field.getName() + " Value: " + samplePoint.getFieldValue(field));
    28. }
    29. logger(System.lineSeparator());
    30. }
    31. }
    32. }
    33. }
  3. The helper function dumpDataSet is not defined.
    Solution: Define the dumpDataSet function as follows:
    Collapse
    Word wrap
    Dark theme
    Copy code
    1. /**
    2. * Print SamplePoint in the SampleSet object as an output.
    3. *
    4. * @param sampleSet Sampling dataset
    5. */
    6. private void dumpDataSet(SampleSet sampleSet) {
    7. SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    8. for (SamplePoint samplePoint : sampleSet.getSamplePoints()) {
    9. logger("Sample point type: " + samplePoint.getDataType().getName());
    10. logger("Start: " + dateFormat.format(new Date(samplePoint.getStartTime(TimeUnit.MILLISECONDS))));
    11. logger("End: " + dateFormat.format(new Date(samplePoint.getEndTime(TimeUnit.MILLISECONDS))));
    12. for (Field field : samplePoint.getDataType().getFields()) {
    13. logger("Field: " + field.getName() + " Value: " + samplePoint.getFieldValue(field));
    14. }
    15. }
    16. }
Search in Guides
Enter a keyword.