应用集成Health Service kit后,通过调用ActivityRecordsController类中的接口来操作用户的锻炼记录。
请先确认应用是否已拥有锻炼记录数据的操作权限:
应用拥有以上权限后,可对用户数据进行如下操作:
用户可以将锻炼记录通过ActivityRecordsController写入到Health Service Kit,具体可执行以下操作:
插入的运动健康数据的锻炼记录数据的开始时间和结束时间均需大于2014年1月1号对应的UNIX时间戳。
将锻炼记录写入Health Service Kit示例代码如下:
// 请注意: // 1.此处的this为Activity对象 // 2.此处的ActivityRecordsController类的对象,请在每次接口调用前初始化,避免相关Activity或Context失效导致的数据读取失败的问题 final ActivityRecordsController activityRecordsController = HuaweiHiHealth.getActivityRecordsController(this); Context context = getApplicationContext(); // 构造请求对象的时间区间:开始和结束时间 // 请注意此处设置的开始时间和结束时间均需大于2014年1月1号对应的UNIX时间戳 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(); // 构造运动记录配速对象PaceSummary // ActivitySummary中的PaceSummary用来承载配速统计数据 ActivitySummary activitySummary = new ActivitySummary(); PaceSummary paceSummary = new PaceSummary(); paceSummary.setAvgPace(247.27626); paceSummary.setBestPace(212.0); paceSummary.setPartTimeMap((Map<String, Double>) new HashMap<>().put(1.0, 456)); paceSummary.setPaceMap((Map<String, Double>) new HashMap<>().put(1.0, 263)); activitySummary.setPaceSummary(paceSummary); // 根据统计数据采集器,构造统计数据样本点,并添加至DataSummary对象 // 创建距离统计数据采样点 SamplePoint samplePointDistance = new SamplePoint.Builder(DataType.DT_CONTINUOUS_DISTANCE_TOTAL).build(); samplePointDistance.setTimeInterval(startTime + 1L, startTime + 300000L, TimeUnit.MILLISECONDS); samplePointDistance.getFieldValue(Field.FIELD_DISTANCE).setDoubleValue(352.0d); // 创建速度统计数据采样点 SamplePoint samplePointSpeed = new SamplePoint.Builder(DataType.POLYMERIZE_CONTINUOUS_SPEED_STATISTICS).build(); samplePointSpeed.setTimeInterval(startTime + 1L, startTime + 300000L, TimeUnit.MILLISECONDS); samplePointSpeed.getFieldValue(Field.FIELD_AVG).setDoubleValue(6.0d); samplePointSpeed.getFieldValue(Field.FIELD_MIN).setDoubleValue(4.0d); samplePointSpeed.getFieldValue(Field.FIELD_MAX).setDoubleValue(8.0d); // ActivitySummary中的DataSummary用来承载统计数据 List<SamplePoint> dataSummary = new ArrayList<>(); dataSummary.add(samplePointDistance); dataSummary.add(samplePointSpeed); activitySummary.setDataSummary(dataSummary); // 构建SampleSection,并添加至SectionSummary SamplePoint samplePointSectionDistanceSamplePoint = new SamplePoint.Builder(DataType.DT_CONTINUOUS_DISTANCE_TOTAL).build(); samplePointSectionDistanceSamplePoint.getFieldValue(Field.FIELD_DISTANCE).setDoubleValue(400d); SamplePoint samplePointSectionSpeedSamplePoint = new SamplePoint.Builder(DataType.POLYMERIZE_CONTINUOUS_SPEED_STATISTICS).build(); samplePointSectionSpeedSamplePoint.getFieldValue(Field.FIELD_AVG).setDoubleValue(60.0d); samplePointSectionSpeedSamplePoint.getFieldValue(Field.FIELD_MIN).setDoubleValue(40.0d); samplePointSectionSpeedSamplePoint.getFieldValue(Field.FIELD_MAX).setDoubleValue(80.0d); SampleSection sampleSection = new SampleSection.Builder() .setSectionNum(1) .setSectionTime(60 * 5L, TimeUnit.SECONDS) .setStartTime(startTime + 1L, TimeUnit.MILLISECONDS) .setEndTime(startTime + 5 * 60 * 1000L, TimeUnit.MILLISECONDS) .setSectionDataList(Arrays.asList(samplePointSectionDistanceSamplePoint, samplePointSectionSpeedSamplePoint)) .build(); activitySummary.setSectionSummary(Collections.singletonList(sampleSection)); // 构造运动记录,设置统计数据ActivitySummary对象 ActivityRecord activityRecord = new ActivityRecord.Builder() .setName("AddActivityRecord") .setDesc("This is ActivityRecord add test!") .setId("MyAddActivityRecordId") .setActivityTypeId(HiHealthActivities.RUNNING) .setStartTime(startTime, TimeUnit.MILLISECONDS) .setEndTime(endTime, TimeUnit.MILLISECONDS) .setActivitySummary(activitySummary) .setTimeZone("+0800") .setMetadata("this is my test") .build(); // 创建一个明细数据采集器 DataCollector dataCollector = new com.huawei.hms.hihealth.data.DataCollector.Builder() .setDataType(DataType.DT_INSTANTANEOUS_STEPS_RATE) .setDataGenerateType(DataCollector.DATA_TYPE_RAW) .setPackageName(getApplicationContext()) .setDataCollectorName("AddActivityRecord") .build(); // 根据数据采集器,构造采样集 SampleSet sampleSet = SampleSet.create(dataCollector); // 构造步频增量明细(DT_INSTANTANEOUS_STEPS_RATE)采样点对象,添加到明细采样集 SamplePoint samplePointStepDelta = sampleSet.createSamplePoint().setTimeInterval(startTime, endTime, TimeUnit.MILLISECONDS); samplePointStepDelta.getFieldValue(Field.FIELD_STEP_RATE).setDoubleValue(100.0d); sampleSet.addSample(samplePointStepDelta); // 构造运动记录请求,设置运动记录activityRecord对象与其关联的明细采样集 ActivityRecordInsertOptions insertOption = new ActivityRecordInsertOptions.Builder().setActivityRecord(activityRecord).addSampleSet(sampleSet).build(); // 调用addActivityRecord接口添加运动记录 Task<Void> addActivityRecordTask = activityRecordsController.addActivityRecord(insertOption); addActivityRecordTask.addOnSuccessListener(new OnSuccessListener<Void>() { @Override public void onSuccess(Void aVoid) { Log.i("ActivityRecords","ActivityRecord was added successfully!"); } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(Exception e) { Log.i("ActivityRecord","Failed to add the ActivityRecord:" + e.getMessage()); } });
用户可以通过ActivityRecordsController删除锻炼记录,具体可执行以下操作:
删除Health Service Kit的锻炼记录示例代码如下:
// 请注意: // 1.此处的this为Activity对象 // 2.此处的ActivityRecordsController类的对象,请在每次接口调用前初始化,避免相关Activity或Context失效导致的数据读取失败的问题 final ActivityRecordsController activityRecordsController = HuaweiHiHealth.getActivityRecordsController(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(); // 构造请求对象的subDataTypeList List<DataType> subDataTypeList = Collections.singletonList(DataType.DT_CONTINUOUS_STEPS_DELTA); // 构造请求对象的activityRecordIds List<String> activityRecordIds = Collections.singletonList("MyAddActivityRecordId"); // 构造删除对象请求体 ActivityRecordDeleteOptions deleteRequest = new ActivityRecordDeleteOptions.Builder() .setSubDataTypeList(subDataTypeList) .setTimeInterval(startTime, endTime, TimeUnit.MILLISECONDS) .setActivityRecordIds(activityRecordIds) .build(); // 调用deleteActivityRecord接口删除运动记录 Task<Void> deleteTask = activityRecordsController.deleteActivityRecord(deleteRequest); deleteTask.addOnSuccessListener(new OnSuccessListener<Void>() { @Override public void onSuccess(Void aVoid) { Log.i("ActivityRecords","ActivityRecord was deleted successfully!"); } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(Exception e) { Log.i("ActivityRecord","Failed to delete the ActivityRecord:" + e.getMessage()); } });
用户可以从Health Service Kit中获取到满足条件的锻炼记录和关联数据信息。例如,可以读取特定时间段内包含的特定运动类型数据的所有锻炼记录,也可以读取感兴趣的其他应用创建的锻炼记录。ActivityRecord中的activitySummary可以让用户获取到对应锻炼记录的统计类型数据,明细数据展示在ActivityRecordReply的sampleSet中。
// 请注意: // 1.此处的this为Activity对象 // 2.此处的ActivityRecordsController类的对象,请在每次接口调用前初始化,避免相关Activity或Context失效导致的数据读取失败的问题 final ActivityRecordsController activityRecordsController = HuaweiHiHealth.getActivityRecordsController(this); // 1.构造请求对象的时间区间:开始和结束时间 // 请注意此处设置的开始时间和结束时间均需大于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, -1); long startTime = cal.getTimeInMillis(); // 2.构造读取运动记录请求体,设置请求时间范围 // 以下示例为读取给定时间段内的运动记录,同时附带读取运动期间的步频数据 // 如果需要读取其他类型的运动期间的详情数据,请开发者自行添加对应的数据类型 ActivityRecordReadOptions readOption = new ActivityRecordReadOptions.Builder().setTimeInterval(startTime, endTime, TimeUnit.MILLISECONDS) .readActivityRecordsFromAllApps() .read(DataType.DT_INSTANTANEOUS_STEPS_RATE) .build(); // 3.调用getActivityRecord接口,根据请求体条件获取Health Service Kit中的运动记录 Task<ActivityRecordReply> getTask = activityRecordsController.getActivityRecord(readOption); getTask.addOnSuccessListener(new OnSuccessListener<ActivityRecordReply>() { @Override public void onSuccess(ActivityRecordReply activityRecordReply) { Log.i("ActivityRecords","Obtaining activity records succeeded.!"); // 打印查询到的运动记录列表 List<ActivityRecord> activityRecordList = activityRecordReply.getActivityRecords(); for (ActivityRecord activityRecord : activityRecordList) { if (activityRecord == null) { continue; } DateFormat dateFormat = DateFormat.getDateInstance(); DateFormat timeFormat = DateFormat.getTimeInstance(); Log.i("ActivityRecordSample", "Returned for ActivityRecord: " + activityRecord.getName() + "\n\tActivityRecord Identifier is " + activityRecord.getId() + "\n\tActivityRecord created by app is " + activityRecord.getPackageName() + "\n\tDescription: " + activityRecord.getDesc() + "\n\tStart: " + dateFormat.format(activityRecord.getStartTime(TimeUnit.MILLISECONDS)) + " " + timeFormat.format(activityRecord.getStartTime(TimeUnit.MILLISECONDS)) + "\n\tEnd: " + dateFormat.format(activityRecord.getEndTime(TimeUnit.MILLISECONDS)) + "\n\tActivity:" + activityRecord.getActivityType() + "\n\tTimeZone:" + activityRecord.getTimeZone() + "\n\tmetadata:" + activityRecord.getMetadata()); // 打印每个运动记录里的ActivitySummary,printActivitySummary为自定义的输出函数 if (activityRecord.getActivitySummary() != null) { printActivitySummary(activityRecord.getActivitySummary()); } // 打印每个运动记录对应的明细数据点 for (SampleSet sampleSet : activityRecordReply.getSampleSet(activityRecord)) { Log.i("ActivityRecordSample", "Returned for SamplePoint and Data type: " + sampleSet.getDataType().getName()); for (SamplePoint dp : sampleSet.getSamplePoints()) { Log.i("ActivityRecordSample", "SamplePoint:"); Log.i("ActivityRecordSample", "DataCollector:" + dp.getDataCollector().toString()); Log.i("ActivityRecordSample", "\tType: " + dp.getDataType().getName()); Log.i("ActivityRecordSample", "\tStart: " + dateFormat.format(dp.getStartTime(TimeUnit.MILLISECONDS))); Log.i("ActivityRecordSample", "\tEnd: " + dateFormat.format(dp.getEndTime(TimeUnit.MILLISECONDS))); for (Field field : dp.getDataType().getFields()) { Log.i("ActivityRecordSample", "\tField: " + field.toString() + " Value: " + dp.getFieldValue(field)); } } } } } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(Exception e) { Log.i("ActivityRecord","Failed to read the ActivityRecord:" + e.getMessage()); } });
上面的代码片段中用到辅助函数:
// 自定义ActivitySummary输出函数
public void printActivitySummary(ActivitySummary activitySummary) {
List<SamplePoint> dataSummary = activitySummary.getDataSummary();
Log.i("ActivityRecordSample", "\n打印统计数据: ");
Log.i("ActivityRecordSample", "\nActivitySummary\n\t DataSummary: ");
// 打印统计数据点
for (SamplePoint samplePoint : dataSummary) {
Log.i("ActivityRecordSample", "\n\t samplePoint: \n\t DataCollector" + samplePoint.getDataCollector() + "\n\t DataType"
+ samplePoint.getDataType() + "\n\t StartTime" + samplePoint.getStartTime(TimeUnit.MILLISECONDS) + "\n\t EndTime"
+ samplePoint.getEndTime(TimeUnit.MILLISECONDS) + "\n\t SamplingTime" + samplePoint.getSamplingTime(TimeUnit.MILLISECONDS)
+ "\n\t FieldValues" + samplePoint.getFieldValues());
}
// 打印配速信息
PaceSummary paceSummary = activitySummary.getPaceSummary();
Log.i("ActivityRecordSample", "\n\t PaceSummary: \n\t AvgPace" + paceSummary.getAvgPace() + "\n\t BestPace"
+ paceSummary.getBestPace() + "\n\t PaceMap" + paceSummary.getPaceMap() + "\n\t PartTimeMap"
+ paceSummary.getPartTimeMap() + "\n\t SportHealthPaceMap" + paceSummary.getSportHealthPaceMap());
printSectionSummary(activitySummary.getSectionSummary());
}// 自定义返回数据的显示函数
private void printSectionSummary(List<SampleSection> sectionSummary) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
for (SampleSection sampleSection : sectionSummary) {
Log.i("ActivityRecordSample", "SampleSection.SectionNum: " + sampleSection.getSectionNum());
Log.i("ActivityRecordSample", "SampleSection.sectionTime: " + sampleSection.getSectionTime(TimeUnit.SECONDS));
Log.i("ActivityRecordSample", "SampleSection.startTime: " + dateFormat.format(new Date(sampleSection.getStartTime(TimeUnit.MILLISECONDS))));
Log.i("ActivityRecordSample", "SampleSection.endTime: " + dateFormat.format(new Date(sampleSection.getEndTime(TimeUnit.MILLISECONDS))));
Log.i("ActivityRecordSample", "SampleSection.sectionDataList:");
for (SamplePoint samplePoint : sampleSection.getSectionDataList()) {
for (Field field : samplePoint.getDataType().getFields()) {
Log.i("ActivityRecordSample", "Field: " + field.getName() + " Value: " + samplePoint.getFieldValue(field));
}
}
}
}对正在进行的活动创建ActivityRecord,活动过程中的运动数据在Health Service Kit中与ActivityRecord隐式关联。
应用使用ActivityRecordsController.beginActivityRecord方法启动一个锻炼记录,示例如下:
// 请注意: // 1.此处的this为Activity对象 // 2.此处的ActivityRecordsController类的对象,请在每次接口调用前初始化,避免相关Activity或Context失效导致的数据读取失败的问题 final ActivityRecordsController activityRecordsController = HuaweiHiHealth.getActivityRecordsController(this); // 构造运动记录开始时间 long startTime = Calendar.getInstance().getTimeInMillis(); // 构造ActivityRecord对象,设置运动记录开始时间 ActivityRecord activityRecord = new ActivityRecord.Builder() .setId("MyBeginActivityRecordId") .setName("BeginActivityRecord") .setDesc("This is ActivityRecord begin test!") .setActivityTypeId(HiHealthActivities.RUNNING) .setStartTime(startTime, TimeUnit.MILLISECONDS) .build(); // 调用启动新运动记录API接口beginActivityRecord Task<Void> task1 = activityRecordsController.beginActivityRecord(activityRecord); // 添加启动ActivityRecord成功 task1.addOnSuccessListener(new OnSuccessListener<Void>() { @Override public void onSuccess(Void aVoid) { Log.i("ActivityRecords","MyActivityRecord started successfully."); } // 添加启动ActivityRecord失败 }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(Exception e) { Log.i("ActivityRecords","Failed to begin MyActivityRecord:" + e.getMessage()); } });
应用中使用ActivityRecordsController.endActivityRecord方法停止指定的锻炼记录,示例如下:
// 请注意此处的this为Activity对象
final ActivityRecordsController activityRecordsController = HuaweiHiHealth.getActivityRecordsController(this);
// 调用endActivityRecord接口停止运动记录,入参为ActivityRecord的ID字符串或者null
// 入参为ID字符串时,停止当前应用指定ID的运动记录
// 入参为null时,停止该应用当前所有的未停止运动记录
Task<List<ActivityRecord>> endTask = activityRecordsController.endActivityRecord("MyBeginActivityRecordId");
endTask.addOnSuccessListener(new OnSuccessListener<List<ActivityRecord>>() {
@Override
public void onSuccess(List<ActivityRecord> activityRecords) {
Log.i("ActivityRecords","MyActivityRecord End success");
// 返回停止成功的运动记录列表
if (activityRecords.size() > 0) {
for (ActivityRecord activityRecord : activityRecords) {
DateFormat dateFormat = DateFormat.getDateInstance();
DateFormat timeFormat = DateFormat.getTimeInstance();
Log.i("ActivityRecords", "Returned for ActivityRecord: " + activityRecord.getName() + "\n\tActivityRecord Identifier is "
+ activityRecord.getId() + "\n\tActivityRecord created by app is " + activityRecord.getPackageName()
+ "\n\tDescription: " + activityRecord.getDesc() + "\n\tStart: "
+ dateFormat.format(activityRecord.getStartTime(TimeUnit.MILLISECONDS)) + " "
+ timeFormat.format(activityRecord.getStartTime(TimeUnit.MILLISECONDS)) + "\n\tEnd: "
+ dateFormat.format(activityRecord.getEndTime(TimeUnit.MILLISECONDS)) + " "
+ timeFormat.format(activityRecord.getEndTime(TimeUnit.MILLISECONDS)) + "\n\tActivity:"
+ activityRecord.getActivityType());
}
} else {
// 没有停止成功返回null
Log.i("ActivityRecords","MyActivityRecord End response is null");
}
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
Log.i("ActivityRecords","MyActivityRecord End fail:" + e.getMessage());
}
});