[Huawei Developers] Freemind R:
More information like this, you can visit HUAWEI Developer Forum​

Original link: https://forums.developer.huawei.com/forumPortal/en/topicview?tid=0201345979826040147&fid=0101187876626530001

In this article we will learn to use Huawei Health Kit in a workout app.

Huawei Health Kit

Health Kit based on users Huawei Id and authorization, provide best service by accessing their health and fitness data. Using this service, developers do not need to worry about capturing their user’s data from any Bluetooth device like fitness tracker watch or Fitbit and record them. It helps developers to create a hassle-free, effective and productive application to their users.

HMS Health Kit Services

1) DataController: Developers can use this API to insert, delete, update, and read data, as well as listen to data updates by registering a listener.

2) SensorsController: Developers can use this API to receiving data reported by the sensor like steps count.

3) AutoRecordController: Developers can use this API to automatically record sensor data, stop recording sensor data, and obtain the record information.

4) ActivityRecordsController: Developers can use this API to create and manage user activities.

Here in this article we will use two services provided by HMS Health Kit and that is SensorsController and ActivityRecordsController.

Use case

To lose weight, you can walk or run. When you walk or run will lose some calories from our body. So better to track our daily steps, if you track daily steps, then you can be active and also to avoid health problems like heart attacks or broken bones, a new study suggests.

Increasing our walking and maintaining the steps can reduce our risk of heart attacks, strokes and fractures over the next few years. Pedometers can be helpful for us to use, as they give us a clear idea of how much we are doing (self-monitoring) and can be used to set realistic goals for increasing our walking gradually.

HMS Health Kit works as a pedometer, count our steps and provide the information directly to us. We can also record our steps using HMS Health Kit and use it for self-monitoring.

Demo

[IMG="https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/001/647/156/2640091000001647156.20200904095805.16369381233017674587646408715807:50510916013330:2800:5C94A976000AB55A5F101C9D5277D7C614CA375363EAD0A735209D225AEB93CC.gif"]https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/001/647/156/2640091000001647156.20200904095805.16369381233017674587646408715807:50510916013330:2800:5C94A976000AB55A5F101C9D5277D7C614CA375363EAD0A735209D225AEB93CC.gif[/IMG]

Prerequisite

1) Must have a Huawei Developer Account.

2) Must have a Huawei phone with HMS 4.0.0.300 or later.

3) Must have a laptop or desktop with Android Studio, Jdk 1.8, SDK platform 26 and Gradle 4.6 installed.

Things need to be done

1) Create a project in android studio.

2) Get the SHA Key. For getting the SHA key, refer this article.

3) Create an app in the Huawei AppGallery connect.

4) Click on Health kit in console.

[IMG="https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/001/647/156/2640091000001647156.20200904095901.81961036381245346805731896860510:50510916013330:2800:B4BC8C1ED42676FA98D237E53FE0E7C9DC797049F069A20C4DA00B2FE88C7040.png"]https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/001/647/156/2640091000001647156.20200904095901.81961036381245346805731896860510:50510916013330:2800:B4BC8C1ED42676FA98D237E53FE0E7C9DC797049F069A20C4DA00B2FE88C7040.png[/IMG]

5) Apply for Health Kit

[IMG="https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/001/647/156/2640091000001647156.20200904095950.74297416630295089426821315683199:50510916013330:2800:2ED9BE71C8BB2B9EFD50E8EC96059D3239A3F3A209F6CA55FE5F4F57150D59F3.png"]https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/001/647/156/2640091000001647156.20200904095950.74297416630295089426821315683199:50510916013330:2800:2ED9BE71C8BB2B9EFD50E8EC96059D3239A3F3A209F6CA55FE5F4F57150D59F3.png[/IMG]

6) Select Product Type as Mobile App, APK Name as your project package name and check the required permission required for your application to work, as shown below:

[IMG="https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/001/647/156/2640091000001647156.20200904100019.75370710432205735182470953564653:50510916013330:2800:7120E79AF3157B702823F42FAC89D4C5BDBE794182DA3508DB01951CDF515B85.png"]https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/001/647/156/2640091000001647156.20200904100019.75370710432205735182470953564653:50510916013330:2800:7120E79AF3157B702823F42FAC89D4C5BDBE794182DA3508DB01951CDF515B85.png[/IMG]

Finally click on submit button to apply for health kit.

7) Provide the SHA Key in App Information Section.

8) Provide storage location.

9) Add the app ID generated when the creating the app on HUAWEI Developers to the application section

<meta-data
android:name="com.huawei.hms.client.appid"
android:value="YOUR_APP_ID" />

10) After completing all the above points we need to download the agconnect-services.json from App Information Section. Copy and paste the Json file in the app folder of the android project.

11) Enter the below maven url inside the repositories of buildscript and allprojects (project build.gradle file):

maven { url ‘http://developer.huawei.com/repo/’ }

12) Enter the below plugin in the app build.gradle file:

apply plugin: ‘com.huawei.agconnect’

13) Enter the below Health Kit, account kit and auth service dependencies in the dependencies section:

implementation 'com.huawei.agconnect:agconnect-core:1.4.0.300'
implementation 'com.huawei.agconnect:agconnect-auth:1.4.0.300'
implementation 'com.huawei.hms:hwid:4.0.4.300'

implementation 'com.huawei.hms:hihealth-base:5.0.0.300'

14) Enter the below permission in android manifest file

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
<uses-permission android:name="android.permission.BODY_SENSORS" />

15) Now Sync the gradle.

Huawei ID authentication

Sign in with Huawei ID authentication and apply for the scope to obtain the permissions to access the Health Kit APIs. Different scopes correspond to different permissions. Developers can apply for permissions based on service requirements.

public void doLogin(View view) {
Log.i(TAG, "begin sign in");
List<Scope> scopeList = new ArrayList<>();
scopeList.add(new Scope(Scopes.HEALTHKIT_STEP_BOTH));
scopeList.add(new Scope(Scopes.HEALTHKIT_HEIGHTWEIGHT_BOTH));
scopeList.add(new Scope(Scopes.HEALTHKIT_ACTIVITY_BOTH));
HuaweiIdAuthParamsHelper authParamsHelper = new HuaweiIdAuthParamsHelper(
HuaweiIdAuthParams.DEFAULT_AUTH_REQUEST_PARAM);
mHuaweiIdAuthParams = authParamsHelper.setIdToken()
.setAccessToken()
.setScopeList(scopeList)
.createParams();
mHuaweiIdAuthService = HuaweiIdAuthManager.getService(SplashActivity.this, mHuaweiIdAuthParams);
startActivityForResult(mHuaweiIdAuthService.getSignInIntent(), REQUEST_SIGN_IN_LOGIN);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_SIGN_IN_LOGIN) {
Task<AuthHuaweiId> authHuaweiIdTask = HuaweiIdAuthManager.parseAuthResultFromIntent(data);
if (authHuaweiIdTask.isSuccessful()) {
AuthHuaweiId huaweiAccount = authHuaweiIdTask.getResult();
Log.i("TAG", "accessToken:" + huaweiAccount.getAccessToken());
AGConnectAuthCredential credential = HwIdAuthProvider.credentialWithToken(huaweiAccount.getAccessToken());
AGConnectAuth.getInstance().signIn(credential).addOnSuccessListener(new OnSuccessListener<SignInResult>() {
@Override
public void onSuccess(SignInResult signInResult) {
mUser = AGConnectAuth.getInstance().getCurrentUser();
Intent intent = new Intent(SplashActivity.this,InstructionActivity.class);
startActivity(intent);
finish();
}
});
} else {
Log.e("TAG", "sign in failed : " + ((ApiException) authHuaweiIdTask.getException()).getStatusCode());
}
}
}

Below is the link to know more about the mapping between scopes and permissions:

https://developer.huawei.com/consumer/en/doc/HMSCore-References-V5/scopes-0000001050092713-V5

SensorController

As the name suggested it will gather information using sensor of android mobile device. Using SensorController of HMS Health Kit:

1) We can connect to a built-in sensor of the phone such as a pedometer to obtain data.

2) We can connect to an external BLE device such as heart rate strap to obtain data.

Here we will use SensorController to count the number of steps taken by our users. In order to that we need to directly call the register method of SensorsController to register a listener to obtain the data reported by the built-in sensor.

Obtain SensorController object

HiHealthOptions options = HiHealthOptions.builder().build();
AuthHuaweiId signInHuaweiId = HuaweiIdAuthManager.getExtendedAuthResult(options);
sensorsController = HuaweiHiHealth.getSensorsController(this, signInHuaweiId);

Register a listener to listen to the step count

private OnSamplePointListener onStepPointListener = new OnSamplePointListener() {
@Override
public void onSamplePoint(SamplePoint samplePoint) {
// The step count, time, and type data reported by the pedometer is called back to the app through
// samplePoint.
showSamplePoint();

mCurrentSamplePoint = samplePoint;

if (mLastSamplePoint == null) {
mLastSamplePoint = samplePoint;
}
}
};

public void registerSteps() {
if (sensorsController == null) {
Toast.makeText(StepsTrackerActivity.this, "SensorsController is null", Toast.LENGTH_LONG).show();
return;
}
DataCollector dataCollector = new DataCollector.Builder()
.setDataType(DataType.DT_CONTINUOUS_STEPS_TOTAL)
.setDataGenerateType(DataCollector.DATA_TYPE_RAW)
.setPackageName(StepsTrackerActivity.this)
.setDeviceInfo(new DeviceInfo("hw", "hw", "hw", 0))
.build();
SensorOptions.Builder builder = new SensorOptions.Builder();
builder.setDataType(DataType.DT_CONTINUOUS_STEPS_TOTAL);
builder.setDataCollector(dataCollector);
sensorsController.register(builder.build(), onStepPointListener)
.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
Toast.makeText(StepsTrackerActivity.this, "Register Success", Toast.LENGTH_LONG).show();

}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
Toast.makeText(StepsTrackerActivity.this, "Register Failed", Toast.LENGTH_LONG).show();
}
});
}

Show SamplePoint data

private void showSamplePoint() {

if (mLastSamplePoint != null && mCurrentSamplePoint != null) {
SamplePoint samplePoint = mCurrentSamplePoint;
System.out.println("STEPS >>>" + (samplePoint.getFieldValue(Field.FIELD_STEPS).asIntValue()
- mLastSamplePoint.getFieldValue(Field.FIELD_STEPS).asIntValue()));
runOnUiThread(new Runnable() {
@Override
public void run() {
txtSteps.setText(String.valueOf(Integer.parseInt(txtSteps.getText().toString()) + samplePoint.getFieldValue(Field.FIELD_STEPS).asIntValue()
- mLastSamplePoint.getFieldValue(Field.FIELD_STEPS).asIntValue()));
if(selectedWeight.equalsIgnoreCase("Kg")) {
txtCalorie.setText(String.format("%.2f", Integer.parseInt(weight.getText().toString()) * Long.parseLong(txtSteps.getText().toString()) * 0.4 * 0.001 * 1.036) + " Kcal");
}else{
txtCalorie.setText(String.format("%.2f", Integer.parseInt(weight.getText().toString()) * 2.2046226218 * Long.parseLong(txtSteps.getText().toString()) * 0.4 * 0.001 * 1.036) + " Kcal");
}
mLastSamplePoint = samplePoint;
}
});

}
}

Un-Register a listener to stop the step count

public void unregisterSteps() {
if (sensorsController == null) {
Toast.makeText(StepsTrackerActivity.this, "SensorsController is null", Toast.LENGTH_LONG).show();
return;
}

// Unregister the listener for the step count.
sensorsController.unregister(onStepPointListener).addOnSuccessListener(new OnSuccessListener<Boolean>() {
@Override
public void onSuccess(Boolean aBoolean) {
Toast.makeText(StepsTrackerActivity.this, "UnregisterSteps Succeed ...", Toast.LENGTH_LONG).show();
mLastSamplePoint = null;
mCurrentSamplePoint = null;
txtSteps.setText("0");
txtCalorie.setText("0");
btnStartStop.setText("Start Tracking");
isStartStop = true;

}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
Toast.makeText(StepsTrackerActivity.this, "UnregisterSteps Failed ...", Toast.LENGTH_LONG).show();
}
});
}

Result

[IMG="https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/001/647/156/2640091000001647156.20200904101510.32918630268109826482680114049362:50510916013330:2800:88D912702E7D8CA4B953FC0A36BD9C8CBAF616618A2C39481FA02486CC642A1B.jpg"]https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/001/647/156/2640091000001647156.20200904101510.32918630268109826482680114049362:50510916013330:2800:88D912702E7D8CA4B953FC0A36BD9C8CBAF616618A2C39481FA02486CC642A1B.jpg[/IMG]

ActivityRecordsController

As the name suggested it will record / insert the activity data of user. Here we will insert the steps count taken by user.

Start time and end time for ActivityRecords

We need start and end time to insert the user steps data as show below:

public static long getEndTime() {
Calendar cal = Calendar.getInstance();
Date now = new Date();
cal.setTime(now);
long endTime = cal.getTimeInMillis();
return endTime;
}

public static long getStartTime() {
Calendar cal = Calendar.getInstance();
cal.add(Calendar.HOUR_OF_DAY, -1);
long startTime = cal.getTimeInMillis();
return startTime;
}

Insert ActivityRecords

Using SamplePoint of HMS Health Kit we will insert the step count of user as shown below:

private void insertActivityRecords(){
HiHealthOptions hihealthOptions = HiHealthOptions.builder().build();
AuthHuaweiId signInHuaweiId = HuaweiIdAuthManager.getExtendedAuthResult(hihealthOptions);
ActivityRecordsController activityRecordsController = HuaweiHiHealth.getActivityRecordsController(StepsTrackerActivity.this, signInHuaweiId);
ActivityRecord activityRecord = new ActivityRecord.Builder()
.setName("AddStepsRecord")
.setDesc("This is Steps record")
.setId("StepId")
.setActivityTypeId(HiHealthActivities.ON_FOOT)
.setStartTime(startTime, TimeUnit.MILLISECONDS)
.setEndTime(endTime, TimeUnit.MILLISECONDS)
.build();
DataCollector dataCollector = new DataCollector.Builder()
.setDataType(DataType.DT_CONTINUOUS_STEPS_DELTA)
.setDataGenerateType(DataCollector.DATA_TYPE_RAW)
.setPackageName(getApplicationContext())
.setDataCollectorName("AddStepsRecord")
.build();
SampleSet sampleSet = SampleSet.create(dataCollector);
SamplePoint samplePoint = sampleSet.createSamplePoint().setTimeInterval(startTime, endTime, TimeUnit.MILLISECONDS);
samplePoint.getFieldValue(Field.FIELD_STEPS_DELTA).setIntValue(Integer.parseInt(txtSteps.getText().toString()));
sampleSet.addSample(samplePoint);
ActivityRecordInsertOptions insertOption =
new ActivityRecordInsertOptions.Builder().setActivityRecord(activityRecord).addSampleSet(sampleSet).build();
Task<Void> addTask = activityRecordsController.addActivityRecord(insertOption);
addTask.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
unregisterSteps();
Log.i("ActivityRecords","ActivityRecord add was successful!");
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
String errorCode = e.getMessage();
String errorMsg = HiHealthStatusCodes.getStatusCodeMessage(Integer.parseInt(errorCode));
Log.i("ActivityRecords",errorCode + ": " + errorMsg);
}
});

}

DatePicker

private void getDatePicker(EditText edtVal){
final Calendar c = Calendar.getInstance();
mYear = c.get(Calendar.YEAR);
mMonth = c.get(Calendar.MONTH);
mDay = c.get(Calendar.DAY_OF_MONTH);

datePickerVal = "";
DatePickerDialog datePickerDialog = new DatePickerDialog(GetRecords.this,
new DatePickerDialog.OnDateSetListener() {

@Override
public void onDateSet(DatePicker view, int year,
int monthOfYear, int dayOfMonth) {
// edtVal.setText(dayOfMonth + "-" + (monthOfYear + 1) + "-" + year);
edtVal.setText(year + "-" + (monthOfYear + 1) + "-" + dayOfMonth);
// datePickerVal = dayOfMonth + "-" + (monthOfYear + 1) + "-" + year;

}
}, mYear, mMonth, mDay);
datePickerDialog.show();

}

TimePicker

private void getTimePicker(EditText edtVal){
final Calendar c = Calendar.getInstance();
mHour = c.get(Calendar.HOUR_OF_DAY);
mMinute = c.get(Calendar.MINUTE);

// Launch Time Picker Dialog
TimePickerDialog timePickerDialog = new TimePickerDialog(GetRecords.this,
new TimePickerDialog.OnTimeSetListener() {

@Override
public void onTimeSet(TimePicker view, int hourOfDay,
int minute) {

edtVal.setText(hourOfDay + ":" + minute);
}
}, mHour, mMinute, false);
timePickerDialog.show();

}

Start & End Time milliseconds conversion

private long getDateTime(String dateval,String timeval) {
String dateStr = dateval+" "+timeval+":00";
long milliseconds = 0;
try {
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");

Date date = dateFormat.parse(dateStr);
System.out.println("DATE TIME >>>"+date.getTime());
milliseconds = date.getTime();
} catch (ParseException e) {
e.printStackTrace();
}
return milliseconds;
}

Reading ActivityRecords and Associated Data

Here we can obtain all ActivityRecords within a specific period of time for particular data, or obtain a specific ActivityRecord by name or ID as shown below:

private void readActivityRecords(){
HiHealthOptions hihealthOptions = HiHealthOptions.builder().build();
AuthHuaweiId signInHuaweiId = HuaweiIdAuthManager.getExtendedAuthResult(hihealthOptions);
ActivityRecordsController activityRecordsController = HuaweiHiHealth.getActivityRecordsController(getApplicationContext(), signInHuaweiId);
ActivityRecordReadOptions readOption =
new ActivityRecordReadOptions.Builder().setTimeInterval(startTime, endTime, TimeUnit.MILLISECONDS)
.readActivityRecordsFromAllApps()
.read(DataType.DT_CONTINUOUS_STEPS_DELTA)
.build();
Task<ActivityRecordReply> getTask = activityRecordsController.getActivityRecord(readOption);
getTask.addOnSuccessListener(new OnSuccessListener<ActivityRecordReply>() {
@Override
public void onSuccess(ActivityRecordReply activityRecordReply) {
Log.i("ActivityRecords","Get ActivityRecord was successful!");
//Print ActivityRecord and corresponding activity data in the result.
List<ActivityRecord> activityRecordList = activityRecordReply.getActivityRecords();
for (ActivityRecord activityRecord : activityRecordList) {
DateFormat dateFormat = DateFormat.getDateInstance();
DateFormat timeFormat = DateFormat.getTimeInstance();
for (SampleSet sampleSet : activityRecordReply.getSampleSet(activityRecord)) {
for (SamplePoint dp : sampleSet.getSamplePoints()) {
String values = "Start: " + dateFormat.format(dp.getStartTime(TimeUnit.MILLISECONDS)) + " " + timeFormat.format(dp.getStartTime(TimeUnit.MILLISECONDS))+"\n"+
"End: " + dateFormat.format(dp.getEndTime(TimeUnit.MILLISECONDS))+ " " + timeFormat.format(dp.getEndTime(TimeUnit.MILLISECONDS));
for (Field field : dp.getDataType().getFields()) {
/*Log.i("ActivityRecordSample",
"\tField: " + field.toString() + " Value: " + dp.getFieldValue(field));*/
values = values +"\n"+"Step Taken: " + dp.getFieldValue(field);
}
samplePointList.add(values);
}
}
}
showTheList();
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
String errorCode = e.getMessage();
String errorMsg = HiHealthStatusCodes.getStatusCodeMessage(Integer.parseInt(errorCode));
Log.i("ActivityRecords",errorCode + ": " + errorMsg);
}
});
}

Result

[IMG="https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/001/647/156/2640091000001647156.20200904102135.38547263006156102100949245307117:50510916013330:2800:1E84C876E7F30B641F85402F201618181F9C4F438760CD79460E49A57579E775.jpg"]https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/001/647/156/2640091000001647156.20200904102135.38547263006156102100949245307117:50510916013330:2800:1E84C876E7F30B641F85402F201618181F9C4F438760CD79460E49A57579E775.jpg[/IMG]

What we learn?

We learn how to make the usage of two beautiful services provided by HMS Health Kit and also situation where we need the most, in this case fetching user steps and inserting/fetching the data when we need to show in the app.

GitHub

Very soon I am going to post the entire code on GitHub. So come back again to check it out.

For more reference

https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides-V5/service-introduction-0000001050071661-V5

https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides-V5/sensorscontroller-develop-0000001050069728-V5

https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides-V5/activityrecord-develop-0000001050069730-V5