文档管理中心

管理健康记录

应用集成Health Service kit后,通过调用HealthRecordController类中的接口来操作用户的健康记录, 如下:

说明
  1. 在调用Health Service Kit Android SDK接口时,请确保手机处于亮屏且解锁状态,否则可能会导致接口调用失败,具体误参见错误码:DISABLE_DATA_OPERATION。
  2. 在调用Health Service Kit SDK接口时,请确保您的应用为前台应用或者与前台应用绑定,否则可能会导致接口调用失败,具体错误参见错误码:APPLICATION_NOT_FORGROUND。
  3. 通过HuaweiHiHealth.getHealthRecordController方法获取HealthRecordController时,若传入Activity对象(用于应用包含界面的场景调用),支持触发HMS Core版本强制升级,若传入Context对象(用于应用无界面的场景调用),不支持触发HMS Core版本强制升级。
  4. 在开始调用Health Service Kit接口之前,请阅读Health Service Kit Android SDK接口调用示例章节,了解Health Service Kit Android SDK接口调用流程。

将健康记录写入Health Service Kit

用户可以将健康记录相关数据通过HealthRecordController写入到Health Service Kit,具体可执行以下操作:

  1. 应用需先确认是否已拥有健康记录数据操作权限,数据类型详见健康记录数据类型。
  2. 创建一个指定采集器、时间段、健康数据统计信息、健康数据明细信息和其他必要信息的HealthRecord。
  3. 使用HealthRecord创建一个HealthRecordInsertOptions。
  4. 使用HealthRecordController.addHealthRecord方法将HealthRecordInsertOptions插入Health Service Kit。

    addHealthRecord方法的回调中的HealthRecordId需要被妥善保存,以便后期修改Health Service Kit中的健康记录使用。
    说明

    插入的健康记录的开始时间和结束时间均需大于2014年1月1号对应的UNIX时间戳。

以健康记录支持的心率过缓数据类型为例,插入HealthRecord示例代码如下:

// 请注意:
// 1.此处的this为Activity对象
// 2.此处的HealthRecordController类的对象,请在每次接口调用前初始化,避免相关Activity或Context失效导致的数据读取失败的问题
HealthRecordController healthRecordController = HuaweiHiHealth.getHealthRecordController(this);

// 设置请求体的开始时间和结束时间
Calendar cal = Calendar.getInstance();
Date now = new Date();
cal.setTime(now);
long endTime = cal.getTimeInMillis();
cal.add(Calendar.HOUR_OF_DAY, -1);
long startTime = cal.getTimeInMillis();

// 1.创建用来承载心率明细数据类型的采集器与存放明细数据的sampleSetList
DataCollector dataCollector =
    new com.huawei.hms.hihealth.data.DataCollector.Builder().setDataType(DataType.DT_INSTANTANEOUS_HEART_RATE)
        .setDataGenerateType(DataCollector.DATA_TYPE_RAW)
        .setPackageName(context)
        .setDataStreamName("such as step count")
        .build();
SampleSet sampleSet = SampleSet.create(dataCollector);
// 预置时间跨度5分钟,设置心率明细点值88
SamplePoint samplePoint =
    sampleSet.createSamplePoint().setTimeInterval(startTime , startTime + 300000L, TimeUnit.MILLISECONDS);
samplePoint.getFieldValue(Field.FIELD_BPM).setDoubleValue(88);
sampleSet.addSample(samplePoint);
// sampleSetList 用来存放健康明细数据
List<SampleSet> sampleSetList = new ArrayList<>();
sampleSetList.add(sampleSet);

// samplePointList 用来存放统计数据点
List<SamplePoint> samplePointList = new ArrayList<>();
// 2.构造心率统计数据点
SamplePoint samplePoint1 = new SamplePoint.Builder(DataType.POLYMERIZE_CONTINUOUS_HEART_RATE_STATISTICS).build();
samplePoint1.getFieldValue(Field.FIELD_AVG).setDoubleValue(90);
samplePoint1.getFieldValue(Field.FIELD_MAX).setDoubleValue(100);
samplePoint1.getFieldValue(Field.FIELD_MIN).setDoubleValue(80);
samplePoint1.getFieldValue(Field.FIELD_LAST).setDoubleValue(80);
samplePoint1.setTimeInterval(startTime + 1L, startTime + 300000L, TimeUnit.MILLISECONDS);
samplePointList.add(samplePoint1);

// 3.构造健康记录的采集器(以心率过缓健康数据类型为例),以及构造健康记录结构体
DataCollector dataCollector2 = new com.huawei.hms.hihealth.data.DataCollector.Builder()
    .setDataType(HealthDataTypes.DT_HEALTH_RECORD_BRADYCARDIA)
    .setDataGenerateType(DataCollector.DATA_TYPE_RAW)
    .setPackageName(context)
    .setDataStreamName("such as step count")
    .build();

HealthRecord.Builder healthRecordBuilder =
    new HealthRecord.Builder(dataCollector2).setSubDataSummary(samplePointList)
        .setSubDataDetails(sampleSetList)
        .setStartTime(startTime, TimeUnit.MILLISECONDS)
        .setEndTime(endTime, TimeUnit.MILLISECONDS);
// 给心率过缓健康数据类型的每个Field设置值
healthRecordBuilder.setFieldValue(HealthFields.FIELD_THRESHOLD, 40d);
healthRecordBuilder.setFieldValue(HealthFields.FIELD_AVG_HEART_RATE, 44d);
healthRecordBuilder.setFieldValue(HealthFields.FIELD_MAX_HEART_RATE, 48d);
healthRecordBuilder.setFieldValue(HealthFields.FIELD_MIN_HEART_RATE, 40d);
HealthRecord healthRecord = healthRecordBuilder.build();

HealthRecordInsertOptions insertOptions =
    new HealthRecordInsertOptions.Builder().setHealthRecord(healthRecord).build();

healthRecordController.addHealthRecord(insertOptions).addOnSuccessListener(new OnSuccessListener<String>() {
    @Override
    public void onSuccess(String healthRecordId) {
        // 请保存好插入成功后返回的healthRecordId,这个healthRecordId用于修改场景
        healthRecordIdFromInsertResult = healthRecordId;
        logger("The health record is added successfully,please save the healthRecordId! " + healthRecordId);
    }
}).addOnFailureListener(new OnFailureListener() {
    @Override
    public void onFailure(Exception e) {
        logger(e.toString());
    }
});
说明

直接拷贝使用上述示例代码,会有下面多处报错,错误点和解决办法如下:

  1. 辅助函数logger没有定义。
    解决办法:定义logger函数,不进行任何操作,参考下面的示例代码。
    private static final String TAG = "HealthRecordController";
    
    /** 
     * 同时输出操作结果日志到logcat 
     * 
     * @param string日志字符串
     */ 
    private void logger(String string) { 
        Log.i(TAG, string); 
    }
  2. 字符串变量healthRecordIdFromInsertResult未定义。

    解决办法:healthRecordIdFromInsertResult字符串用来作为updateHealthRecord接口调用的参数,具体的定义参考如下,需在调用addHealthRecord成功后予以赋值。

    private String healthRecordIdFromInsertResult  = "";

删除Health Service Kit中的健康记录

用户可以通过HealthRecordController删除健康记录,具体可执行以下操作:

  1. 根据healthRecordIds或起止时间、数据类型创建一个HealthRecordDeleteOptions。
  2. 使用HealthRecordController.deleteHealthRecord方法将HealthRecordDeleteOptions从Health Service Kit中删除 。
    说明
    1. 删除的运动健康数据的健康记录数据的开始时间和结束时间均需大于2014年1月1号对应的UNIX时间戳。
    2. 删除健康记录数据时,若healthRecordIds不为空则根据healthRecordIds删除,否则根据健康记录数据类型及起止时间删除。

删除Health Service Kit的健康记录示例代码如下:

// 请注意:
// 1.此处的this为Activity对象
// 2.此处的HealthRecordController类的对象,请在每次接口调用前初始化,避免相关Activity或Context失效导致的数据读取失败的问题
HealthRecordController healthRecordController = HuaweiHiHealth.getHealthRecordController(this);

// 构造请求对象的时间区间:开始和结束时间
// 请注意此处设置的开始时间和结束时间均需大于2014年1月1号对应的UNIX时间戳
Calendar cal = Calendar.getInstance();
Date now = new Date();
cal.setTime(now);
long endTime = cal.getTimeInMillis();
cal.add(Calendar.DAY_OF_YEAR, -2);
long startTime = cal.getTimeInMillis();
// 构造请求对象的dataType
DataType dataType = HealthDataTypes.DT_HEALTH_RECORD_BRADYCARDIA;
// 构造请求对象的subDataTypeList
List<DataType> subDataTypeList = Collections.singletonList(DataType.DT_INSTANTANEOUS_HEART_RATE);
// 构造请求对象的healthRecordIds
List<String> healthRecordIds = Collections.singletonList("healthRecordIdFromInsertResult");

// 构造删除对象请求体
HealthRecordDeleteOptions deleteRequest = new HealthRecordDeleteOptions.Builder()
    .setHealthRecordIds(healthRecordIds)
    .isDeleteSubData(true)
    .setDataType(dataType)
    .setSubDataTypeList(subDataTypeList)
    .setTimeInterval(startTime, endTime, TimeUnit.MILLISECONDS).build();

// 调用deleteHealthRecord接口删除健康记录
Task<Void> deleteTask = healthRecordController.deleteHealthRecord(deleteRequest);
deleteTask.addOnSuccessListener(new OnSuccessListener<Void>() {
    @Override
    public void onSuccess(Void aVoid) {
        Log.i("HealthRecords","HealthRecord deleted successfully.!");
    }
}).addOnFailureListener(new OnFailureListener() {
    @Override
    public void onFailure(Exception e) {
        Log.i("HealthRecords","Failed to delete data" + e.getMessage());
    }
});

修改Health Service Kit中的健康记录

用户可以通过HealthRecordController修改已经写入到Health Service Kit的健康记录相关数据,具体可执行以下操作:

  1. 应用需先确认是否已拥有健康记录数据操作权限,数据类型详见健康记录数据类型。
  2. 创建一个指定采集器、时间段、健康数据统计信息、健康数据明细信息和其他必要信息的HealthRecord。
  3. 使用HealthRecord和将健康记录写入Health Service Kit回调中的HealthRecordId,创建一个HealthRecordUpdateOptions。
  4. 使用HealthRecordController.updateHealthRecord方法修改Health Service Kit中的健康记录及相关数据。

    说明

    1. 插入的健康记录的开始时间和结束时间均需大于2014年1月1号对应的UNIX时间戳。

    2. 如果想要通过HealthRecordId修改的健康记录不存在,会抛出错误码。

以健康记录支持的心率过缓数据类型为例,修改HealthRecord示例代码如下:

// 请注意:
// 1.此处的this为Activity对象
// 2.此处的HealthRecordController类的对象,请在每次接口调用前初始化,避免相关Activity或Context失效导致的数据读取失败的问题
HealthRecordController healthRecordController = HuaweiHiHealth.getHealthRecordController(this);

// 设置请求体的开始时间和结束时间
Calendar cal = Calendar.getInstance();
Date now = new Date();
cal.setTime(now);
long endTime = cal.getTimeInMillis();
cal.add(Calendar.HOUR_OF_DAY, -1);
long startTime = cal.getTimeInMillis();

// 1.创建用来承载心率明细数据类型的采集器与存放明细数据的sampleSetList
DataCollector dataCollector =
    new com.huawei.hms.hihealth.data.DataCollector.Builder().setDataType(DataType.DT_INSTANTANEOUS_HEART_RATE)
        .setDataGenerateType(DataCollector.DATA_TYPE_RAW)
        .setPackageName(context)
        .setDataStreamName("such as step count")
        .build();
SampleSet sampleSet = SampleSet.create(dataCollector);
// 预置时间跨度5分钟,设置心率明细点值90
SamplePoint samplePoint =
    sampleSet.createSamplePoint().setTimeInterval(startTime , startTime + 300000L, TimeUnit.MILLISECONDS);
samplePoint.getFieldValue(Field.FIELD_BPM).setDoubleValue(90);
sampleSet.addSample(samplePoint);
// sampleSetList 用来存放健康明细数据
List<SampleSet> sampleSetList = new ArrayList<>();
sampleSetList.add(sampleSet);

// samplePointList 用来存放统计数据点
List<SamplePoint> samplePointList = new ArrayList<>();
// 2.构造心率统计数据点
SamplePoint samplePoint1 = new SamplePoint.Builder(DataType.POLYMERIZE_CONTINUOUS_HEART_RATE_STATISTICS).build();
samplePoint1.getFieldValue(Field.FIELD_AVG).setDoubleValue(90);
samplePoint1.getFieldValue(Field.FIELD_MAX).setDoubleValue(100);
samplePoint1.getFieldValue(Field.FIELD_MIN).setDoubleValue(80);
samplePoint1.getFieldValue(Field.FIELD_LAST).setDoubleValue(80);
samplePoint1.setTimeInterval(startTime + 1L, startTime + 300000L, TimeUnit.MILLISECONDS);
samplePointList.add(samplePoint1);

// 3.构造健康记录的采集器(以心率过缓健康数据类型为例),以及构造健康记录结构体
DataCollector dataCollector2 = new com.huawei.hms.hihealth.data.DataCollector.Builder()
    .setDataType(HealthDataTypes.DT_HEALTH_RECORD_BRADYCARDIA)
    .setDataGenerateType(DataCollector.DATA_TYPE_RAW)
    .setPackageName(context)
    .setDataStreamName("such as step count")
    .build();

HealthRecord.Builder healthRecordBuilder =
    new HealthRecord.Builder(dataCollector2).setSubDataSummary(samplePointList)
        .setSubDataDetails(sampleSetList)
        .setStartTime(startTime, TimeUnit.MILLISECONDS)
        .setEndTime(endTime, TimeUnit.MILLISECONDS);
// 给心率过缓健康数据类型的每个Field设置值
healthRecordBuilder.setFieldValue(HealthFields.FIELD_THRESHOLD, 42d);
healthRecordBuilder.setFieldValue(HealthFields.FIELD_AVG_HEART_RATE, 45d);
healthRecordBuilder.setFieldValue(HealthFields.FIELD_MAX_HEART_RATE, 48d);
healthRecordBuilder.setFieldValue(HealthFields.FIELD_MIN_HEART_RATE, 42d);
HealthRecord healthRecord = healthRecordBuilder.build();

// 4.构造待修改的updateOptions,记得携带插入成功后返回的healthRecordId
HealthRecordUpdateOptions updateOptions = new HealthRecordUpdateOptions.Builder().setHealthRecord(healthRecord)
    .setHealthRecordId(healthRecordIdFromInsertResult)
    .build();

healthRecordController.updateHealthRecord(updateOptions).addOnSuccessListener(new OnSuccessListener<Void>() {
    @Override
    public void onSuccess(Void aVoid) {
        logger("Health record updated successfully.");
    }
}).addOnFailureListener(new OnFailureListener() {
    @Override
    public void onFailure(Exception e) {
        logger(e.toString());
    }
});
说明

直接拷贝使用上述示例代码,会有下面多处报错,错误点和解决办法如下:

  1. healthRecordIdFromInsertResult未定义

    解决办法:请使用将健康记录写入Health Service Kit回调中的HealthRecordId的值定义该字符串变量。

  2. 辅助函数logger没有定义
    解决办法:定义logger函数,参考下面的示例代码。
    private static final String TAG = "HealthRecordController";
    
    /** 
     * 同时输出操作结果日志到logcat 
     * 
     * @param string日志字符串
     */ 
    private void logger(String string) { 
        Log.i(TAG, string); 
    }

查询Health Service Kit中的健康记录

用户可以通过HealthRecordController查询已经写入到Health Service Kit的健康记录相关数据,具体可执行以下操作:

  • 应用需先确认是否已拥有健康记录数据操作权限,数据类型详见健康记录数据类型。
  • 根据查询时间和相关条件,创建一个HealthRecordReadOptions。
  • 使用HealthRecordController.getHealthRecord方法查询Health Service Kit中存储的健康记录相关数据。
    说明
    1. 调用查询运动健康数据的健康记录接口,接口参数中的开始时间和结束时间均需大于2014年1月1号对应的UNIX时间戳。
    2. 调用查询运动健康数据的健康记录接口,接口参数中的开始时间和结束时间之间的时间跨度不允许超过31天。

以健康记录支持的心率过缓数据类型为例,查询HealthRecord示例代码如下:

// 请注意:
// 1.此处的this为Activity对象
// 2.此处的HealthRecordController类的对象,请在每次接口调用前初始化,避免相关Activity或Context失效导致的数据读取失败的问题
HealthRecordController healthRecordController = HuaweiHiHealth.getHealthRecordController(this);

// 设置请求体的开始时间和结束时间 
Calendar cal = Calendar.getInstance();
Date now = new Date();
cal.setTime(now);
long endTime = cal.getTimeInMillis();
cal.add(Calendar.DAY_OF_YEAR, -1);
long startTime = cal.getTimeInMillis();

// 构建读取运动记录的参数HealthRecordReadOptions 
List<DataType> subDataTypeList = new ArrayList<>();
subDataTypeList.add(DataType.DT_INSTANTANEOUS_HEART_RATE);
HealthRecordReadOptions healthRecordReadOptions =
    new HealthRecordReadOptions.Builder().setTimeInterval(startTime, endTime, TimeUnit.MILLISECONDS)
        .readHealthRecordsFromAllApps()
        .readByDataType(HealthDataTypes.DT_HEALTH_RECORD_BRADYCARDIA)
        .setSubDataTypeList(subDataTypeList)
        .build();

// 通过构造的HealthRecordReadOptions参数传入查询healthRecord
Task<HealthRecordReply> task = healthRecordController.getHealthRecord(healthRecordReadOptions);
task.addOnSuccessListener(new OnSuccessListener<HealthRecordReply>() {
    @Override
    public void onSuccess(HealthRecordReply readResponse) {
        logger("Get HealthRecord was successful!");
        // 打印调用接口获取的运动记录列表
        List<HealthRecord> recordList = readResponse.getHealthRecords();
        for (HealthRecord record : recordList) {
            if (record == null) {
                continue;
            }
            dumpHealthRecord(record);
            logger("Print detailed data points associated with health records");
            for (SampleSet dataSet : record.getSubDataDetails()) {
                dumpDataSet(dataSet);
            }
        }
    }
});
task.addOnFailureListener(new OnFailureListener() {
    @Override
    public void onFailure(Exception e) {
        logger(e.toString());
    }
});
说明

直接拷贝使用上述示例代码,会有下面多处报错,错误点和解决办法如下:

  1. 辅助函数logger没有定义
    解决办法:定义logger函数,参考下面的示例代码。
    private static final String TAG = "HealthRecordController";
    
    /** 
     * 同时输出操作结果日志到logcat 
     * 
     * @param string日志字符串
     */ 
    private void logger(String string) { 
        Log.i(TAG, string); 
    }
  2. 辅助函数dumpHealthRecord没有定义

    解决办法:定义dumpHealthRecord函数,参考下面的示例代码。

    /** 
     * 将HealthRecord对象中的信息打印输出
     * 
     * @param healthRecord 健康记录对象
     */ 
    private void dumpHealthRecord(HealthRecord healthRecord) { 
        logger("Print health record summary information!");
        DateFormat dateFormat = DateFormat.getDateInstance();
        DateFormat timeFormat = DateFormat.getTimeInstance();
        if (healthRecord != null) {
            logger("\tHealthRecordIdentifier: " + healthRecord.getHealthRecordId() + "\n\tpackageName: "
                + healthRecord.getDataCollector().getPackageName() + "\n\tStartTime: "
                + dateFormat.format(healthRecord.getStartTime(TimeUnit.MILLISECONDS)) + " "
                + timeFormat.format(healthRecord.getStartTime(TimeUnit.MILLISECONDS)) + "\n\tEndTime: "
                + dateFormat.format(healthRecord.getEndTime(TimeUnit.MILLISECONDS)) + " "
                + timeFormat.format(healthRecord.getEndTime(TimeUnit.MILLISECONDS)) + "\n\tHealthRecordDataType: "
                + healthRecord.getDataCollector().getDataType().getName() + "\n\tHealthRecordDataCollectorId: "
                + healthRecord.getDataCollector().getDataStreamId() + "\n\tmetaData: " + healthRecord.getMetadata()
                + "\n\tFileValueMap: " + healthRecord.getFieldValues());
    
            if (healthRecord.getSubDataSummary() != null && !healthRecord.getSubDataSummary().isEmpty()) {
                SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
    
                for (SamplePoint samplePoint : healthRecord.getSubDataSummary()) {
                    logger("Sample point type: " + samplePoint.getDataType().getName());
                    logger("Start: " + sDateFormat.format(new Date(samplePoint.getStartTime(TimeUnit.MILLISECONDS))));
                    logger("End: " + sDateFormat.format(new Date(samplePoint.getEndTime(TimeUnit.MILLISECONDS))));
                    for (Field field : samplePoint.getDataType().getFields()) {
                        logger("Field: " + field.getName() + " Value: " + samplePoint.getFieldValue(field));
                    }
                    logger(System.lineSeparator());
                }
            }
        }
    }
  3. 辅助函数dumpDataSet没有定义
    解决办法:定义dumpDataSet函数,参考下面的示例代码。
    /** 
      * 将SampleSet对象中的SamplePoint打印输出
      * 
      * @param sampleSet 采样集
      */ 
    private void dumpDataSet(SampleSet sampleSet) { 
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
    
        for (SamplePoint samplePoint : sampleSet.getSamplePoints()) { 
            logger("Sample point type: " + samplePoint.getDataType().getName()); 
            logger("Start: " + dateFormat.format(new Date(samplePoint.getStartTime(TimeUnit.MILLISECONDS)))); 
            logger("End: " + dateFormat.format(new Date(samplePoint.getEndTime(TimeUnit.MILLISECONDS)))); 
            for (Field field : samplePoint.getDataType().getFields()) { 
                logger("Field: " + field.getName() + " Value: " + samplePoint.getFieldValue(field)); 
            } 
        } 
    }
搜索
请输入您想要搜索的关键词