目录

DataController Development

After integrating Health Kit, the app is able to call ten methods in DataController to perform operations on the fitness and health data. The methods include:

The 10 methods are encapsulated in the DataController object. Therefore, before any of the methods can be called, a DataController object must first be initialized. Subsequent service API calling is implemented by calling the related methods in the DataController object. The sample code for initializing a DataController object is as follows:

HiHealthOptions hiHealthOptions = HiHealthOptions.builder()
	.addDataType(DataType.DT_CONTINUOUS_STEPS_DELTA, HiHealthOptions.ACCESS_READ)
	.addDataType(DataType.DT_CONTINUOUS_STEPS_DELTA, HiHealthOptions.ACCESS_WRITE)
        .addDataType(DataType.DT_INSTANTANEOUS_HEIGHT, HiHealthOptions.ACCESS_READ)
        .addDataType(DataType.DT_INSTANTANEOUS_HEIGHT, HiHealthOptions.ACCESS_WRITE)
	.build();
AuthHuaweiId signInHuaweiId = HuaweiIdAuthManager.getExtendedAuthResult(hiHealthOptions);
DataController dataController = HuaweiHiHealth.getDataController(context, signInHuaweiId);

In this development guide, data types DataType.DT_CONTINUOUS_STEPS_DELTA (number of steps taken since the last reading) and DataType.DT_INSTANTANEOUS_HEIGHT (height) are used as examples. Only the read & write permissions of these two data types are obtained for the initialized DataController object.

Inserting the User's Fitness and Health Data

Insert the user's fitness and health data into the Health platform.

  1. Build a DataCollector object.
    DataCollector dataCollector = new DataCollector.Builder().setPackageName(context)
    	.setDataType(DataType.DT_CONTINUOUS_STEPS_DELTA)
    	.setDataStreamName("STEPS_DELTA")
    	.setDataGenerateType(DataCollector.DATA_TYPE_RAW)
    	.build();
  1. Create a sampling dataset based on the data collector.
    final SampleSet sampleSet = SampleSet.create(dataCollector);
  1. Build the start time, end time, and incremental step count for a DT_CONTINUOUS_STEPS_DELTA sampling point.
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
    Date startDate = dateFormat.parse("2020-03-17 09:00:00");
    Date endDate = dateFormat.parse("2020-03-17 09:05:00");
    int stepsDelta = 1000;
  1. Build a DT_CONTINUOUS_STEPS_DELTA sampling point.
    SamplePoint samplePoint = sampleSet.createSamplePoint()
    	.setTimeInterval(startDate.getTime(), endDate.getTime(), TimeUnit.MILLISECONDS);
    samplePoint.getFieldValue(Field.FIELD_STEPS_DELTA).setIntValue(stepsDelta);
  1. Save a DT_CONTINUOUS_STEPS_DELTA sampling point to the sampling dataset. You can repeat steps 3 through 5 to add more sampling points to the sampling dataset.
    sampleSet.addSample(samplePoint);
  1. Call the data controller to insert the sampling dataset into the Health platform.
    Task<Void> insertTask = dataController.insert(sampleSet);
  1. Calling the data controller to insert the sampling dataset is an asynchronous operation. Therefore, a listener needs to be registered to monitor whether the data insertion is successful or not.
    insertTask.addOnSuccessListener(new OnSuccessListener<Void>() {
    	@Override
    	public void onSuccess(Void result) {
    		logger("Success insert a SampleSet into HMS core");
    		showSampleSet(sampleSet);
    	}
    }).addOnFailureListener(new OnFailureListener() {
    	@Override
    	public void onFailure(Exception e) {
    		String errorCode = e.getMessage();
    		String errorMsg = HiHealthStatusCodes.getStatusCodeMessage(Integer.parseInt(errorCode));
    		logger(errorCode + ": " + errorMsg);
    	}
    });

In the preceding code snippet, two helper functions are used: showSampleSet (SampleSet sampleSet) and logger(String string). The former is used to display data returned by the Health platform, and the latter is a TextView function used to save the results to the log as an output and display the results on the UI. The sample code for these two functions is as follows:

/**
 * Print the SamplePoint in the SampleSet object as an output.
 *
 * @param sampleSet Sampling dataset.
 */
private void showSampleSet(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));
		}
	}
}

/**
 * TextView to send the operation result logs to the logcat and to the UI
 *
 * @param string Log string.
 */
private void logger(String string) {
	Log.i(TAG, string);
	logInfoView.append(string + System.lineSeparator());
	int offset = logInfoView.getLineCount() * logInfoView.getLineHeight();
	if (offset > logInfoView.getHeight()) {
		logInfoView.scrollTo(0, offset - logInfoView.getHeight());
	}
}

Deleting the User's Fitness and Health Data

Only historical data that has been inserted by the app can be deleted from the Health platform. If the deletion is targeted at data not inserted by the app, the request will fail.

  1. Build the condition for data deletion: a DataCollector object.
    DataCollector dataCollector = new DataCollector.Builder().setPackageName(context)
    	.setDataType(DataType.DT_CONTINUOUS_STEPS_DELTA)
    	.setDataStreamName("STEPS_DELTA")
    	.setDataGenerateType(DataCollector.DATA_TYPE_RAW)
    	.build();
  1. Build the time range for the deletion: start time and end time.
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
    Date startDate = dateFormat.parse("2020-03-17 09:00:00");
    Date endDate = dateFormat.parse("2020-03-17 09:05:00");
  1. Build a parameter object as the conditions for the deletion.
    DeleteOptions deleteOptions = new DeleteOptions.Builder().addDataCollector(dataCollector)
    	.setTimeInterval(startDate.getTime(), endDate.getTime(), TimeUnit.MILLISECONDS)
    	.build();
  1. Use the specified condition deletion object to call the data controller to delete the sampling dataset.
    Task<Void> deleteTask = dataController.delete(deleteOptions);
  1. Calling the data controller to delete the sampling dataset is an asynchronous operation. Therefore, a listener needs to be registered to monitor whether the data deletion is successful or not.
    deleteTask.addOnSuccessListener(new OnSuccessListener<Void>() {
    	@Override
    	public void onSuccess(Void result) {
    		logger("Success delete sample data from HMS core");
    	}
    }).addOnFailureListener(new OnFailureListener() {
    	@Override
    	public void onFailure(Exception e) {
    		String errorCode = e.getMessage();
    		String errorMsg = HiHealthStatusCodes.getStatusCodeMessage(Integer.parseInt(errorCode));
    		logger(errorCode + ": " + errorMsg);
    	}
    });

In the preceding code snippet, a helper function is used: logger(String string). This is a TextView function used to save the results to the log as an output and display the results on the UI. The sample code for the function is as follows:

/**
 * TextView to send the operation result logs to the logcat and to the UI
 *
 * @param string Log string.
 */
private void logger(String string) {
	Log.i(TAG, string);
	logInfoView.append(string + System.lineSeparator());
	int offset = logInfoView.getLineCount() * logInfoView.getLineHeight();
	if (offset > logInfoView.getHeight()) {
		logInfoView.scrollTo(0, offset - logInfoView.getHeight());
	}
}

Updating the User's Fitness and Health Data

  1. Build the condition for data update: a DataCollector object.
    DataCollector dataCollector = new DataCollector.Builder().setPackageName(context)
    	.setDataType(DataType.DT_CONTINUOUS_STEPS_DELTA)
    	.setDataStreamName("STEPS_DELTA")
    	.setDataGenerateType(DataCollector.DATA_TYPE_RAW)
    	.build();
  1. Build the sampling dataset for the update: create a sampling dataset for the update based on the data collector.
    SampleSet sampleSet = SampleSet.create(dataCollector);
  1. Build the start time, end time, and incremental step count for a DT_CONTINUOUS_STEPS_DELTA sampling point for the update.
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
    Date startDate = dateFormat.parse("2020-03-17 09:00:00");
    Date endDate = dateFormat.parse("2020-03-17 09:05:00");
    int stepsDelta = 2000;
  1. Build a DT_CONTINUOUS_STEPS_DELTA sampling point for the update.
    SamplePoint samplePoint = sampleSet.createSamplePoint()
    	.setTimeInterval(startDate.getTime(), endDate.getTime(), TimeUnit.MILLISECONDS);
    samplePoint.getFieldValue(Field.FIELD_STEPS_DELTA).setIntValue(stepsDelta);
  1. Add an updated DT_CONTINUOUS_STEPS_DELTA sampling point to the sampling dataset for the update. You can repeat steps 3 through 5 to add more updated sampling points to the sampling dataset for the update.
    sampleSet.addSample(samplePoint);
  1. Build a parameter object for the update.
    UpdateOptions updateRequest = new UpdateOptions.Builder()
    	.setTimeInterval(startDate.getTime(), endDate.getTime(), TimeUnit.MILLISECONDS)
    	.setSampleSet(sampleSet)
    	.build();
  1. Use the specified parameter object for the update to call the data controller to modify the sampling dataset.
    Task<Void> updateTask = dataController.update(updateRequest);
  1. Calling the data controller to modify the sampling dataset is an asynchronous operation. Therefore, a listener needs to be registered to monitor whether the data update is successful or not.
    updateTask.addOnSuccessListener(new OnSuccessListener<Void>() {
    	@Override
    	public void onSuccess(Void result) {
    		logger("Success update sample data from HMS core");
    	}
    }).addOnFailureListener(new OnFailureListener() {
    	@Override
    	public void onFailure(Exception e) {
    		String errorCode = e.getMessage();
    		String errorMsg = HiHealthStatusCodes.getStatusCodeMessage(Integer.parseInt(errorCode));
    		logger(errorCode + ": " + errorMsg);
    	}
    });

In the preceding code snippet, a helper function is used: logger(String string). This is a TextView function used to save the results to the log as an output and display the results on the UI. The sample code for the function is as follows:

/**
 * TextView to send the operation result logs to the logcat and to the UI
 *
 * @param string Log string.
 */
private void logger(String string) {
	Log.i(TAG, string);
	logInfoView.append(string + System.lineSeparator());
	int offset = logInfoView.getLineCount() * logInfoView.getLineHeight();
	if (offset > logInfoView.getHeight()) {
		logInfoView.scrollTo(0, offset - logInfoView.getHeight());
	}
}

Querying the User's Fitness and Health Data

To read historical data from the Health platform, for example, to read the number of steps taken within a period of time, you can specify the read conditions in ReadOptions. For example, you can specify the data collector, data type, and detailed data. If data is read, the dataset will be returned.

  1. Build the condition for data query: a DataCollector object.
    DataCollector dataCollector = new DataCollector.Builder().setPackageName(context)
    	.setDataType(DataType.DT_CONTINUOUS_STEPS_DELTA)
    	.setDataStreamName("STEPS_DELTA")
    	.setDataGenerateType(DataCollector.DATA_TYPE_RAW)
    	.build();
  1. Build the time range for the query: start time and end time.
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
    Date startDate = dateFormat.parse("2020-03-17 09:00:00");
    Date endDate = dateFormat.parse("2020-03-17 09:05:00");
  1. Build the condition-based query object.
    ReadOptions readOptions = new ReadOptions.Builder().read(dataCollector)
    	.setTimeRange(startDate.getTime(), endDate.getTime(), TimeUnit.MILLISECONDS)
    	.build();
  1. Use the specified condition query object to call the data controller to query the sampling dataset.
    Task<ReadReply> readReplyTask = dataController.read(readOptions);
  1. Calling the data controller to query the sampling dataset is an asynchronous operation. Therefore, a listener needs to be registered to monitor whether the data query is successful or not.
    readReplyTask.addOnSuccessListener(new OnSuccessListener<ReadReply>() {
    	@Override
    	public void onSuccess(ReadReply readReply) {
    		logger("Success read a SampleSets from HMS core");
    		for (SampleSet sampleSet : readReply.getSampleSets()) {
    			showSampleSet(sampleSet);
    		}
    	}
    }).addOnFailureListener(new OnFailureListener() {
    	@Override
    	public void onFailure(Exception e) {
    		String errorCode = e.getMessage();
    		String errorMsg = HiHealthStatusCodes.getStatusCodeMessage(Integer.parseInt(errorCode));
    		logger(errorCode + ": " + errorMsg);
    	}
    });

In the preceding code snippet, two helper functions are used: showSampleSet (SampleSet sampleSet) and logger(String string). The former is used to display data returned by the Health platform, and the latter is a TextView function used to save the results to the log as an output and display the results on the UI. The sample code for these two functions is as follows:

/**
 * Print the SamplePoint in the SampleSet object as an output.
 *
 * @param sampleSet Sampling dataset.
 */
private void showSampleSet(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));
		}
	}
}

/**
 * TextView to send the operation result logs to the logcat and to the UI
 *
 * @param string Log string.
 */
private void logger(String string) {
	Log.i(TAG, string);
	logInfoView.append(string + System.lineSeparator());
	int offset = logInfoView.getLineCount() * logInfoView.getLineHeight();
	if (offset > logInfoView.getHeight()) {
		logInfoView.scrollTo(0, offset - logInfoView.getHeight());
	}
}

Querying the summary fitness and health data of the user of the current day

  1. Use the specified data type (DT_CONTINUOUS_STEPS_DELTA) to call the data controller to query the summary data of this data type of the current day.
    Task<SampleSet> todaySummationTask = dataController.readTodaySummation(DataType.DT_CONTINUOUS_STEPS_DELTA);
  1. Calling the data controller to query the summary data of the current day is an asynchronous operation. Therefore, a listener needs to be registered to monitor whether the data query is successful or not.

    Note: In this example, the inserted data time is fixed at 2020-03-17 09:05:00. You need to change the inserted data time to the current date for data to be queried.

    todaySummationTask.addOnSuccessListener(new OnSuccessListener<SampleSet>() {
    	@Override
    	public void onSuccess(SampleSet sampleSet) {
    		logger("Success read today summation from HMS core");
    		if (sampleSet != null) {
    			showSampleSet(sampleSet);
    		}
    	}
    });
    todaySummationTask.addOnFailureListener(new OnFailureListener() {
    	@Override
    	public void onFailure(Exception e) {
    		String errorCode = e.getMessage();
    		String errorMsg = HiHealthStatusCodes.getStatusCodeMessage(Integer.parseInt(errorCode));
    		logger(errorCode + ": " + errorMsg);
    	}
    });

In the preceding code snippet, two helper functions are used: showSampleSet (SampleSet sampleSet) and logger(String string). The former is used to display data returned by the Health platform, and the latter is a TextView function used to save the results to the log as an output and display the results on the UI. The sample code for these two functions is as follows:

/**
 * Print the SamplePoint in the SampleSet object as an output.
 *
 * @param sampleSet Sampling dataset.
 */
private void showSampleSet(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));
		}
	}
}

/**
 * TextView to send the operation result logs to the logcat and to the UI
 *
 * @param string Log string.
 */
private void logger(String string) {
	Log.i(TAG, string);
	logInfoView.append(string + System.lineSeparator());
	int offset = logInfoView.getLineCount() * logInfoView.getLineHeight();
	if (offset > logInfoView.getHeight()) {
		logInfoView.scrollTo(0, offset - logInfoView.getHeight());
	}
}

Querying the Summary Fitness and Health Data of the User on the Local Device of the Current Day

  1. Use the specified data type (DT_CONTINUOUS_STEPS_DELTA) to call the data controller to query the summary data of this data type of the current day.
    Task<SampleSet> todaySummationTask = dataController.readTodaySummationFromDevice(DataType.DT_CONTINUOUS_STEPS_DELTA);
  1. Calling the data controller to query the summary data of the current day is an asynchronous operation. Therefore, a listener needs to be registered to monitor whether the data query is successful or not.
    todaySummationTask.addOnSuccessListener(new OnSuccessListener<SampleSet>() {
    	@Override
    	public void onSuccess(SampleSet sampleSet) {
    		logger("Success read today device summation from HMS core");
    		if (sampleSet != null) {
    			showSampleSet(sampleSet);
    		}
    	}
    });
    todaySummationTask.addOnFailureListener(new OnFailureListener() {
    	@Override
    	public void onFailure(Exception e) {
    		String errorCode = e.getMessage();
    		String errorMsg = HiHealthStatusCodes.getStatusCodeMessage(Integer.parseInt(errorCode));
    		logger(errorCode + ": " + errorMsg);
    	}
    });

In the preceding code snippet, two helper functions are used: showSampleSet (SampleSet sampleSet) and logger(String string). The former is used to display data returned by the Health platform, and the latter is a TextView function used to save the results to the log as an output and display the results on the UI. The sample code for these two functions is as follows:

/**
 * Print the SamplePoint in the SampleSet object as an output.
 *
 * @param sampleSet Sampling dataset.
 */
private void showSampleSet(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));
		}
	}
}

/**
 * TextView to send the operation result logs to the logcat and to the UI
 *
 * @param string Log string.
 */
private void logger(String string) {
	Log.i(TAG, string);
	logInfoView.append(string + System.lineSeparator());
	int offset = logInfoView.getLineCount() * logInfoView.getLineHeight();
	if (offset > logInfoView.getHeight()) {
		logInfoView.scrollTo(0, offset - logInfoView.getHeight());
	}
}

Registering a Listener for Updates of the User's Fitness and Health Data

  1. Build a DataController object. Listeners can be registered for updates of the following six data types.
    • Basic metabolic rate per day (unit: kcal): DataType.DT_INSTANTANEOUS_CALORIES_BMR
    • Body fat rate: DataType.DT_INSTANTANEOUS_BODY_FAT_RATE
    • Height (unit: meter): DataType.DT_INSTANTANEOUS_HEIGHT
    • Water taken over a single drink (unit: liter): DataType.DT_INSTANTANEOUS_HYDRATE
    • Nutrient intake over a meal: DataType.DT_INSTANTANEOUS_NUTRITION_FACTS
    • Weight (unit: kg): DataType.DT_INSTANTANEOUS_BODY_WEIGHT
    DataCollector dataCollector = new DataCollector.Builder().setPackageName(context)
    	.setDataType(DataType.DT_INSTANTANEOUS_HEIGHT)
    	.setDataStreamName("STEPS_DELTA")
    	.setDataGenerateType(DataCollector.DATA_TYPE_RAW)
    	.build();
  1. Build a listening object for data changes: PendingIntent.
    PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, new Intent(this, DataRegisterReceiver.class),
    	PendingIntent.FLAG_UPDATE_CURRENT);
  1. Build a parameter object for registering a listener for data changes.
    ModifyDataMonitorOptions dataMonitorOptions =
    	new ModifyDataMonitorOptions.Builder().setModifyDataType(DataType.DT_INSTANTANEOUS_HEIGHT)
    		.setModifyDataCollector(dataCollector)
    		.setModifyDataIntent(pendingIntent)
    		.build();
  1. Use the specified parameter object for registering a listener for data changes to call the data controller to add the listener.
    Task<Void> registerTask = dataController.registerModifyDataMonitor(dataMonitorOptions);
  1. Calling the data controller to register a listener is an asynchronous operation. Therefore, a listener needs to be registered to monitor whether the registration is successful or not.
    registerTask.addOnSuccessListener(new OnSuccessListener<Void>() {
    	@Override
    	public void onSuccess(Void result) {
    		logger("Register Data Update Listener Success");
    	}
    }).addOnFailureListener(new OnFailureListener() {
    	@Override
    	public void onFailure(Exception e) {
    		String errorCode = e.getMessage();
    		String errorMsg = HiHealthStatusCodes.getStatusCodeMessage(Integer.parseInt(errorCode));
    		logger("Register Data Update Listener Failure: " + errorCode + ": " + errorMsg);
    		pendingIntent = null;
    	}
    });
  1. Call the following code to insert a data entry to trigger the created listener.
    DataCollector dataCollector = new DataCollector.Builder().setPackageName(context)
    	.setDataType(DataType.DT_INSTANTANEOUS_HEIGHT)
    	.setDataStreamName("STEPS_DELTA")
    	.setDataGenerateType(DataCollector.DATA_TYPE_RAW)
    	.build();
    SampleSet sampleSet = SampleSet.create(dataCollector);
    SamplePoint samplePoint = sampleSet.createSamplePoint()
    	.setTimeInterval(System.currentTimeMillis(), System.currentTimeMillis(), TimeUnit.MILLISECONDS);
    samplePoint.getFieldValue(Field.FIELD_HEIGHT).setFloatValue(1.56f);
    sampleSet.addSample(samplePoint);
    dataController.insert(sampleSet);

In the preceding code snippet, a helper function is used: logger(String string).

This is a TextView function used to save the results to the log as an output and display the results on the UI. The sample code for the function is as follows:

/**
 * TextView to send the operation result logs to the logcat and to the UI
 *
 * @param string Log string.
 */
private void logger(String string) {
	Log.i(TAG, string);
	logInfoView.append(string + System.lineSeparator());
	int offset = logInfoView.getLineCount() * logInfoView.getLineHeight();
	if (offset > logInfoView.getHeight()) {
		logInfoView.scrollTo(0, offset - logInfoView.getHeight());
	}
}

Unregistering a Listener for Updates of the User's Fitness and Health Data

  1. Build a listening object for data changes: PendingIntent.
    PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, new Intent(this, DataRegisterReceiver.class),
    	PendingIntent.FLAG_UPDATE_CURRENT);
  1. Use the specified parameter object for unregistering a listener for data changes to call the data controller to cancel the listener.
    Task<Void> task = dataController.unregisterModifyDataMonitor(pendingIntent);
  1. Calling the data controller to unregister a listener is an asynchronous operation. Therefore, a listener needs to be registered to monitor whether the unregistration is successful or not.
    task.addOnSuccessListener(new OnSuccessListener<Void>() {
    	@Override
    	public void onSuccess(Void result) {
    		logger("Unregister Data Update Listener Success: ");
    		pendingIntent = null;
    	}
    });
    task.addOnFailureListener(new OnFailureListener() {
    	@Override
    	public void onFailure(Exception e) {
    		String errorCode = e.getMessage();
    		String errorMsg = HiHealthStatusCodes.getStatusCodeMessage(Integer.parseInt(errorCode));
    		logger("Unregister Data Update Listener Failure: " + errorCode + ":" + errorMsg);
    	}
    });

In the preceding code snippet, a helper function is used: logger(String string). This is a TextView function used to save the results to the log as an output and display the results on the UI. The sample code for the function is as follows:

/**
 * TextView to send the operation result logs to the logcat and to the UI
 *
 * @param string Log string.
 */
private void logger(String string) {
	Log.i(TAG, string);
	logInfoView.append(string + System.lineSeparator());
	int offset = logInfoView.getLineCount() * logInfoView.getLineHeight();
	if (offset > logInfoView.getHeight()) {
		logInfoView.scrollTo(0, offset - logInfoView.getHeight());
	}
}

Syncing the User's Fitness and Health Data Between the Device and Cloud

  1. Call the syncAll method of DataController to sync data.
    Task<Void> syncTask = dataController.syncAll();
  1. Calling the data controller to sync data between the device and cloud is an asynchronous operation. Therefore, a listener needs to be registered to monitor whether the syncing is successful or not.
    syncTask.addOnSuccessListener(new OnSuccessListener<Void>() {
    	@Override
    	public void onSuccess(Void result) {
    		logger("synAll success");
    	}
    }).addOnFailureListener(new OnFailureListener() {
    	@Override
    	public void onFailure(Exception e) {
    		String errorCode = e.getMessage();
    		String errorMsg = HiHealthStatusCodes.getStatusCodeMessage(Integer.parseInt(errorCode));
    		logger("synAll failure" + errorCode + ":" + errorMsg);
    	}
    });

In the preceding code snippet, a helper function is used: logger(String string). This is a TextView function used to save the results to the log as an output and display the results on the UI. The sample code for the function is as follows:

/**
 * TextView to send the operation result logs to the logcat and to the UI
 *
 * @param string Log string.
 */
private void logger(String string) {
	Log.i(TAG, string);
	logInfoView.append(string + System.lineSeparator());
	int offset = logInfoView.getLineCount() * logInfoView.getLineHeight();
	if (offset > logInfoView.getHeight()) {
		logInfoView.scrollTo(0, offset - logInfoView.getHeight());
	}
}

Clearing the User's Fitness and Health Data from the Device and Cloud

  1. Call the clearAll method of the DataController to delete data inserted by the current app from the device and cloud.
    Task<Void> syncTask = dataController.clearAll();
  1. Calling the data controller to clear user data from the device and cloud is an asynchronous operation. Therefore, a listener needs to be registered to monitor whether the clearance is successful or not.
    syncTask.addOnSuccessListener(new OnSuccessListener<Void>() {
    	@Override
    	public void onSuccess(Void result) {
    		logger("clearAll success");
    	}
    }).addOnFailureListener(new OnFailureListener() {
    	@Override
    	public void onFailure(Exception e) {
    		String errorCode = e.getMessage();
    		String errorMsg = HiHealthStatusCodes.getStatusCodeMessage(Integer.parseInt(errorCode));
    		logger("clearAll failure" + errorCode + ":" + errorMsg);
    	}
    });

    In the preceding code snippet, a helper function is used: logger(String string). This is a TextView function used to save the results to the log as an output and display the results on the UI. The sample code for the function is as follows:

    /**
     * TextView to send the operation result logs to the logcat and to the UI
     *
     * @param string Log string.
     */
    private void logger(String string) {
    	Log.i(TAG, string);
    	logInfoView.append(string + System.lineSeparator());
    	int offset = logInfoView.getLineCount() * logInfoView.getLineHeight();
    	if (offset > logInfoView.getHeight()) {
    		logInfoView.scrollTo(0, offset - logInfoView.getHeight());
    	}
    }