{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Hello everyone,
Especially recently when we realized how important the “health” issue is for us, we learned how important it is to act in order to lead a healthy life. For the days when we worked in the home office and forgot to act like as a human, we can follow our daily steps, how many steps we have taken in 3 months and how many calories we have burned. We develop sample app to use this properties. We used these features with the help of Health Kit.
Before step into development progress, let’s examine what is Huawei Health Kit and what are the main functions.
Huawei Health Kit :
HUAWEI Health Kit allows ecosystem apps to access fitness and health data of users based on their HUAWEI ID and authorization. For consumers, Health Kit provides a mechanism for fitness and health data storage and sharing based on flexible authorization. For developers and partners, Health Kit provides a data platform and fitness and health open capabilities, so that they can build related apps and services based on a multitude of data types. Health Kit connects the hardware devices and ecosystem apps to provide consumers with health care, workout guidance, and ultimate service experience.
Main Functions :
· Data storage
Provides a data platform for developers to store fitness and health data.
· Data openness
Provides a wide range of fitness and health APIs and supports sharing of the various fitness and health data, including step count, weight, and heart rate.
· Data access authorization management
Provides settings for users and developers so users can manage developers’ access to their health and fitness data, guaranteeing users’ data privacy and legal rights.
· Device access
Provides hardware devices (including fitness and health devices) with APIs for measuring and uploading data through the standard Bluetooth protocol.
You can browse this page to examine it in more detail.
https://developer.huawei.com/consumer/en/hms/huaweihealth/
Development Process
We learned about Huawei Health Kit and its main functions. Now, we can move on development part. Primarily, we should create a project on App Gallery Connect. You can follow the steps from the link below.
https://medium.com/huawei-developers/android-integrating-your-apps-with-huawei-hms-core-1f1e2a090e98
After all these steps, we need to apply for Health Kit.
Then, we need to select data and their permissions.
!!! To access health data we need to authenticate the user with Huawei ID.
Let’s continue by coding Data Controller to get our users’ step data.
Code:
private fun initDataController() {
val hiHealthOptions = HiHealthOptions.builder()
.addDataType(DataType.DT_CONTINUOUS_STEPS_DELTA, HiHealthOptions.ACCESS_READ)
.build()
val signInHuaweiId =
HuaweiIdAuthManager.getExtendedAuthResult(hiHealthOptions)
dataController = HuaweiHiHealth.getDataController(context!!, signInHuaweiId)
}
}
After creating the Data Controller, we write the read Daily function to get daily steps data of our users.
Code:
fun readDaily(startTime: Int, endTime: Int) {
val daliySummationTask =
dataController!!.readDailySummation(
DataType.DT_CONTINUOUS_STEPS_DELTA,
startTime,
endTime
)
daliySummationTask.addOnSuccessListener { sampleSet ->
sampleSet?.let { showSampleSet(it) }
}
daliySummationTask.addOnFailureListener { e ->
val errorCode: String? = e.message
val pattern: Pattern = Pattern.compile("[0-9]*")
val isNum: Matcher = pattern.matcher(errorCode)
when {
e is ApiException -> {
val eCode = e.statusCode
val errorMsg = HiHealthStatusCodes.getStatusCodeMessage(eCode)
}
isNum.matches() -> {
val errorMsg =
errorCode?.toInt()?.let { HiHealthStatusCodes.getStatusCodeMessage(it) }
}
else -> {
}
}
}
}
Let’s build the request body for reading activity records. We call the read method of the Data Controller to obtain activity records from the Health platform based on the conditions in the request body. Also, we should set time format. The daily hours reading format should be like this:
” yyyy-MM-dd hh: mm: ss “
Code:
fun getActivityRecord() {
val dateFormat = SimpleDateFormat("yyyy-MM-dd hh:mm:ss", Locale.getDefault())
val startDate: Date = dateFormat.parse("yyyy-MM-dd hh:mm:ss")!!
val endDate: Date = dateFormat.parse("yyyy-MM-dd hh:mm:ss")!!
val readOptions = ReadOptions.Builder()
.read(DataType.DT_CONTINUOUS_STEPS_DELTA)
.setTimeRange(
startDate.time,
endDate.time,
TimeUnit.MILLISECONDS
)
.build()
val readReplyTask = dataController!!.read(readOptions)
readReplyTask.addOnSuccessListener { readReply ->
Log.i("TAG", "Success read an SampleSets from HMS core")
for (sampleSet in readReply.getSampleSets()) {
showSampleSet(sampleSet)
}
}.addOnFailureListener { e ->
val errorCode: String? = e.message
val pattern: Pattern = Pattern.compile("[0-9]*")
val isNum: Matcher = pattern.matcher(errorCode)
when {
e is ApiException -> {
val eCode = e.statusCode
val errorMsg = HiHealthStatusCodes.getStatusCodeMessage(eCode)
}
isNum.matches() -> {
val errorMsg =
errorCode?.toInt()?.let { HiHealthStatusCodes.getStatusCodeMessage(it) }
}
else -> {
}
}
}
}
Bonus : I used pagination to displaying step data for better user experience and resource management.
Code:
var count = 0
var today = Calendar.getInstance()
var nextDay = Calendar.getInstance()
nextDay.add(Calendar.DATE, -20)
var dateFormat = SimpleDateFormat("yyyyMMdd", Locale.getDefault())
println("Today : " + dateFormat.format(Date(today.timeInMillis)))
stepViewModel.readToday()
stepViewModel.readDaily(dateFormat.format(Date(nextDay.timeInMillis)).toInt(), dateFormat.format(Date(today.timeInMillis)).toInt()-1)
binding.stepList.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
if (!binding.stepList.canScrollVertically(1) && count<5) {
count++
var otherDay = Calendar.getInstance()
var nextDay = Calendar.getInstance()
otherDay.add(Calendar.DATE, -(20*count))
nextDay.add(Calendar.DATE, -((20*(count + 1)-1)))
stepViewModel.readDaily(dateFormat.format(Date(nextDay.timeInMillis)).toInt(), dateFormat.format(Date(otherDay.timeInMillis)).toInt())
}
}
})
Finally, we completed our development process. Let’s see how it looks in our project.
Conclusion
We have created an application where we can track our daily step count by taking advantage of the features provided by the Health Kit. I think it is necessary for all of us to face this reality. I hope it has been useful article for you. Your questions and opinions are very important to me.
References :
https://developer.huawei.com/consumer/en/hms/huaweihealth/
Related
This article is originally from HUAWEI Developer Forum
Forum link: https://forums.developer.huawei.com/forumPortal/en/home
In this post, we will learn Kotlin with data binding in Android. It gives you the ability to communicate between your view and model. It keeps the code clean and sorted.
Note: Configuration part check previous article
How to Use Data Binding Library with Kotlin – A Step By Step Guide
It’s a library that allows you to bind the data of your models directly to the xml views in a very flexible way.
Kotlin was recently introduced as a secondary ‘official’ Java language. It is similar to Java in many ways but is a little easier to learn and get to grips with. Some of the biggest companies have adopted Kotlin and seen amazing results.
If you want to use data binding and Kotlin, here are a few things to keep in mind:
· Data binding is a support library, so it can be used with all Android platform versions all the way back to Android 2.1 (API level 7+).
· To use data binding, you need Android Plugin for Gradle 1.5.0-alpha1 or higher. You can see here how to update the Android Plugin for Gradle.
· Android Studio 3.0 fully supports kotlin
First of all, create an Android Studio project and add a dependency for Kotlin and few changes for your App level build.gradle
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
· Add below line into Root level build.gradle
Code:
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
Data Binding:
· Android offers support to write declarative layouts using data binding.
· This minimizes the necessary code in your application logic to connect to the user interface elements.
· The usage of data binding requires changes in your layout files. Such layout files starts with a layout root tag followed by a data element and a view root element.
· The data elements describe data which is available for binding. This view element contains your root hierarchy similar to layout files which are not used with data binding.
· References to the data elements or expressions within the layout are written in the attribute properties using the @{} or @={}
1. The user variable within data describes a property that may be used within this layout
2. Normal view hierarchy.
3. Binding Input data.
Code Implementation:
1.SignInActivity.kt
Code:
class SignInActivity : AppCompatActivity() {
private var mInstance: HiAnalyticsInstance? = null
private lateinit var mDataBinding: ActivitySigninBinding
var viewmodel: SignInViewModel? = null
var customeProgressDialog: CustomeProgressDialog? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mDataBinding = DataBindingUtil.setContentView(this, R.layout.activity_signin)
viewmodel = ViewModelProviders.of(this).get(SignInViewModel::class.java)
mDataBinding.setLifecycleOwner(this);
mDataBinding?.viewmodel = viewmodel
customeProgressDialog = CustomeProgressDialog(this)
initObservables()
init();
}
private fun initObservables() {
viewmodel?.userLogin?.observe(this, Observer { userInfo ->
Toast.makeText(this, "welcome, ${userInfo?.email}", Toast.LENGTH_LONG).show()
val bundle = Bundle()
bundle.putString("email", userInfo?.email)
bundle.putString("password", userInfo?.password)
mInstance!!.onEvent(HAEventType.SIGNIN, bundle)
val intent = Intent(this, ProfileScreen::class.java)
startActivity(intent)
})
viewmodel?.progressDialog?.observe(this, Observer {
if (it!!) customeProgressDialog?.show() else customeProgressDialog?.dismiss()
})
}
private fun init() {
HiAnalyticsTools.enableLog()
mInstance = HiAnalytics.getInstance(this)
mInstance?.setAnalyticsEnabled(true)
mInstance?.regHmsSvcEvent()
}
}
Viewmodel Class:
· The view model coordinates the view's interaction with the model.
· It may convert or manipulate data so that it can be easily consumed by the view and may implement additional properties that may not be present on the model.
· The view model may define logical states that the view can represent visually to the user.
Code:
class SignInViewModel(application: Application) : AndroidViewModel(application) {
var btnSelected: ObservableBoolean? = null
var email: ObservableField<String>? = null
var password: ObservableField<String>? = null
var userLogin: MutableLiveData<UserInfo>? = null
var progressDialog: SingleLiveEvent<Boolean>? = null
init {
btnSelected = ObservableBoolean(false)
email = ObservableField("")
password = ObservableField("")
userLogin = MutableLiveData()
progressDialog = SingleLiveEvent<Boolean>()
}
fun onEmailChanged(s: CharSequence, start: Int, befor: Int, count: Int) {
btnSelected?.set(password?.get()!!.length != 0)
}
fun onPasswordChanged(s: CharSequence, start: Int, befor: Int, count: Int) {
btnSelected?.set(s.toString().length >= 8)
}
fun onLoginClick() {
progressDialog?.value = false
val userInfo = UserInfo(email?.get(), password?.get())
userLogin?.value = userInfo
}
}
Result:
Overview of application:
Event Analysis:
· Event Analysis to collect data about interactions with your content.
· An Event hit includes a value of each component and these values are displayed in report.
Any questions about this, you can acquire answers from HUAWEI Developer Forum.
More articles like this, you can visit HUAWEI Developer Forum
Want to retrieve health or fitness data of users based on their HUAWEI ID and show in your app?
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Health Kit provide main three feature:
Data storage
Provides a data platform for developers to store fitness and health data.
Data openness
Provides a wide range of fitness and health APIs and supports sharing of the various fitness and health data, including step count, weight, and heart rate.
Data access authorization management
Provides settings for users and developers so users can manage developer's access to their health and fitness data, guaranteeing users' data privacy and legal rights.
Developement
1.Register HUAWEI ID and apply for Account Service*
https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides/apply-id-0000001050069756
2. Applying for Health Kit in developer console*
https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides/apply-kitservice-0000001050071707
3. Integrate HMS Health Kit
In Build.gradle file,add the implementation.
Code:
implementation 'com.huawei.hms:hihealth-base:{5.0.0.300}
In AndroidManifest.xml file, add the app ID generated when the creating the app on HUAWEI Developers to the application section.
Code:
<meta-data
android:name="com.huawei.hms.client.appid"
android:value="APP ID"/>
4.Call the related APIs to display HUAWEI ID sign-in screen and authorization screen. The app can only access data upon user authorization.
Sign in via HMS Core SDK and apply for the scope to obtain the permissions to access the HUAWEI Health Kit APIs.
Code:
private void signInn() {
Log.i(TAG, "begin sign in");
List<Scope> scopeList = new ArrayList<>();
// Add scopes to apply for. The following only shows an example.
// Developers need to add scopes according to their specific needs.
// View and save steps in HUAWEI Health Kit.
scopeList.add(new Scope( Scopes.HEALTHKIT_STEP_BOTH));
// View and save height and weight in HUAWEI Health Kit.
scopeList.add(new Scope(Scopes.HEALTHKIT_CALORIES_BOTH));
// View and save the heart rate data in HUAWEI Health Kit.
scopeList.add(new Scope(Scopes.HEALTHKIT_DISTANCE_BOTH));
// Configure authorization parameters.
HuaweiIdAuthParamsHelper authParamsHelper =
new HuaweiIdAuthParamsHelper(HuaweiIdAuthParams.DEFAULT_AUTH_REQUEST_PARAM);
HuaweiIdAuthParams authParams =
authParamsHelper.setIdToken().setAccessToken().setScopeList(scopeList).createParams();
// Initialize the HuaweiIdAuthService object.
final HuaweiIdAuthService authService =
HuaweiIdAuthManager.getService(this.getContext(), authParams);
// Silent sign-in. If authorization has been granted by the current account,
// the authorization screen will not display. This is an asynchronous method.
Task<AuthHuaweiId> authHuaweiIdTask = authService.silentSignIn();
final Context context = this.getContext();
// Add the callback for the call result.
authHuaweiIdTask.addOnSuccessListener(new OnSuccessListener<AuthHuaweiId>() {
@Override
public void onSuccess(AuthHuaweiId huaweiId) {
// The silent sign-in is successful.
Log.i(TAG, "silentSignIn success");
try {
readData();
} catch (ParseException e) {
e.printStackTrace();
}
Toast.makeText(context, "silentSignIn success", Toast.LENGTH_LONG).show();
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception exception) {
// The silent sign-in fails.
// This indicates that the authorization has not been granted by the current account.
if (exception instanceof ApiException) {
ApiException apiException = (ApiException) exception;
Log.i(TAG, "sign failed status:" + apiException.getStatusCode());
Log.i(TAG, "begin sign in by intent");
// Call the sign-in API using the getSignInIntent() method.
Intent signInIntent = authService.getSignInIntent();
MeFragment.this.startActivityForResult(signInIntent, REQUEST_SIGN_IN_LOGIN);
}
}
});
}
5.Build the condition for data query: a DataCollector object
Code:
DataCollector dataCollector = new DataCollector.Builder().setPackageName(context)
.setDataType(DataType.DT_CONTINUOUS_STEPS_DELTA)
.setDataStreamName("STEPS_DELTA")
.setDataGenerateType(DataCollector.DATA_TYPE_RAW)
.build();
6.Build time range and build condition-based query object.
Use the specified condition query object(call read Option) to call the data controller to query the sampling dataset.
Code:
public void readData() throws ParseException {
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-07-17 09:05:00");
ReadOptions readOptions = new ReadOptions.Builder()
.read(DataType.DT_CONTINUOUS_STEPS_DELTA)
.read(DataType.DT_CONTINUOUS_CALORIES_BURNT)
.read(DataType.DT_CONTINUOUS_DISTANCE_DELTA)
.setTimeRange(startDate.getTime(), endDate.getTime(), TimeUnit.MILLISECONDS)
.build();
Task<ReadReply> readReplyTask = dataController.read(readOptions);
readReplyTask.addOnSuccessListener(new OnSuccessListener<ReadReply>() {
@Override
public void onSuccess(ReadReply readReply) {
for (SampleSet sampleSet : readReply.getSampleSets()) {
showSampleSet(sampleSet);
Log.i(TAG,"*****************"+sampleSet);
}
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
checkData.setText(e.toString()+"read");
}
});
}
7.the calories,distance and step are succesfully show in app.
Reference:
https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides/overview-dev-android-0000001050071671
More information like this, you can visit HUAWEI Developer Forum
In this article we’re going to take a look at the Huawei Health Kit features so we can easily put these features to our apps.
Health app industry have shown an important increase in recent years.The software and healthcare industry are working together to find the latest technology products for the needs of patients and families.Huawei offers high technology service for the health and fitness app ecosystem with HealthKit and HiHealth Kit service. Huawei and third-party partner capabilities track and customize all aspects of better living.
Data storage : Provides a platform for users to store their fitness and health data.
Data openness : Provides a wide range of APIs for writing and reading speed, positioning, blood sugar level, and other data.
Data interaction : Enables you and your users to agree on data access, guaranteeing proper use and security of personal data.
HiHealth:
https://developer.huawei.com/consumer/en/hms/huawei-healthkit
HealthKit:
https://developer.huawei.com/consumer/en/hms/huawei-healthkit
We will examine the differences between HealthKit and HiHealth in our next articles.I created a sample app which I’ve open-sourced on GitHub for enthusiasts who want to use this service.
https://github.com/tualdev/hms-health-kit-demo
Setting up the Health Kit
You’ll need to do setup before you can use the Health Kit.You can follow the official documentation on how to prepare app and enable Health Kit on App Gallery Connect.
Also you can follow this blog post to integrate your apps with Huawei HMS Core:
https://medium.com/huawei-developers/android-integrating-your-apps-with-huawei-hms-core-1f1e2a090e98
I’ll show you how to implement Sensors Controller features in this article for your android projects.Let’s get started!
Add the required dependencies to the build.gradle file under app folder.We need some dependencies.
Code:
implementation 'com.huawei.hms:hwid:4.0.1.300'
implementation 'com.huawei.agconnect:agconnect-core:1.3.1.300'
implementation 'com.huawei.hms:hihealth-base:5.0.0.300'
Add the required permissions to the AndroidManifest.xml file under app/src/main folder.
Code:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH" />
You need to give some permissions after applying for HealthKit in service cards area.The applied permissions will be displayed on the user authorization page.
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Let’s continue by coding Sensors Controller functionalities in our project.
Sensors Controller
We can achieve success in the two different scenarios with the sensor controller.The first of these scenarios is to be able to access the built-in sensor that the phone contains like pedometer.You can directly call the register method of SensorsController to register a listener to obtain the data reported by the built-in sensor.
NOTE : Currently, Health Kit does not support the access of devices. If you request the access of fitness and health devices to help users collect data, use HiHealth Kit (for the integration of the HUAWEI Health app) instead.
HiHealth Kit is also applicable if you would like to obtain the fitness and health data collected by Huawei wearables or Huawei ecosystem partners for your services offered to customers.
Using the Built-in Sensor Data of the Phone
Let’s give an example about that how to obtain the incremental step count from a phone.
Firstly, we need to sign in to your HUAWEI ID and obtain the SensorsController object.
Code:
val options = HiHealthOptions.builder().build()
// Sign in to the HUAWEI ID.
val signInHuaweiId = HuaweiIdAuthManager.getExtendedAuthResult(options)
// Obtain the SensorsController
sensorsController = HuaweiHiHealth.getSensorsController(this, signInHuaweiId)
After that, we will register a listener to listen to the step count.To register a listener for receiving raw data reported by a specified data collector, use the SensorsController.register method.
Code:
private val onSamplePointListener =
OnSamplePointListener { samplePoint ->
showSamplePoint(samplePoint)
}
val builder = SensorOptions.Builder()
builder.setDataType(DataType.DT_CONTINUOUS_STEPS_TOTAL)
sensorsController!!.register(builder.build(), onSamplePointListener)
.addOnSuccessListener {
Toast.makeText(this, "registerSteps successed... ", Toast.LENGTH_SHORT).show()
}
.addOnFailureListener {
Toast.makeText(this, "registerSteps failed... ", Toast.LENGTH_SHORT).show()
}
When we no longer need step data, we can use the SensorsController.unregister method to unregister the listener.
Code:
sensorsController!!.unregister(onSamplePointListener).addOnSuccessListener {
Toast.makeText(this, "unregisterSteps successed ...", Toast.LENGTH_SHORT).show()
}.addOnFailureListener { e ->
Toast.makeText(this, "unregisterSteps failed ...", Toast.LENGTH_SHORT).show()
}
Using an External Bluetooth Device
In the second scenario, we will examine how data can be obtained from external bluetooth devices.Note that : Health Kit currently supports only standard Bluetooth BLE heart rate device.
Currently, Health Kit does not support reading data generated by Huawei wearables and the HUAWEI Health app. It is scheduled that the HUAWEI Health app data, including step count, sleep data, workout records, heart rate, and body fat, will be opened up in the future.
Let’s give an example about that how to obtain the heart rate data from the Bluetooth device.
Firstly, we need to sign in to your HUAWEI ID and obtain the BleController and SensorsController objects.
Code:
val options = HiHealthOptions.builder().build()
val signInHuaweiId = HuaweiIdAuthManager.getExtendedAuthResult(options)
sensorsController = HuaweiHiHealth.getSensorsController(this, signInHuaweiId)
bleController = HuaweiHiHealth.getBleController(this, signInHuaweiId)
After that, we need to create a bluetooth scanning callback object by using BleScanCallback.BLE devices detected during the scanning will automatically be called back to the bleDeviceInfo object.
Code:
private val mBleCallback: BleScanCallback = object : BleScanCallback() {
override fun onDeviceDiscover(bleDeviceInfo: BleDeviceInfo) {
// Bluetooth devices detected during the scanning will be called back to the bleDeviceInfo object
Toast.makeText([email protected], "onDeviceDiscover : " + bleDeviceInfo.deviceName, Toast.LENGTH_SHORT).show()
// Save the scanned heart rate devices to the variables for later use.
[email protected] = bleDeviceInfo
}
override fun onScanEnd() {
Toast.makeText([email protected], "onScanEnd Scan called", Toast.LENGTH_SHORT).show()
}
}
For now, we can start scan for available BLE devices.We need to use the BleController.beginScan method to scan for nearby BLE devices.
Code:
bleController!!.beginScan(listOf(DataType.DT_INSTANTANEOUS_HEART_RATE), 15, mBleCallback)
We can stop scanning for Bluetooth devices.We need to use the BleController.endScan method to stop scanning.
Code:
bleController!!.endScan(mBleCallback)
We can save the device to be used by SensorsController.We need to use the BleController.saveDevice method to save the device.After successfully saving the device, you can obtain the data collector objects of the device via SensorsController, for example, using the SensorsController.getDataCollectors method.
Code:
bleController!!.saveDevice(bleDeviceInfo).addOnSuccessListener {
Toast.makeText(this, "saveHeartRateDevice successed... ", Toast.LENGTH_SHORT).show()
}.addOnFailureListener {
Toast.makeText(this, "saveHeartRateDevice failed... ", Toast.LENGTH_SHORT).show()
}
We can delete a device if a BLE device is no longer used.We need to use the BleController.deleteDevice method to delete it.
Code:
bleController!!.deleteDevice(bleDeviceInfo).addOnSuccessListener {
Toast.makeText(this, "removeHeartRateDevice successed... ", Toast.LENGTH_SHORT).show()
}.addOnFailureListener {
Toast.makeText(this, "removeHeartRateDevice failed... ", Toast.LENGTH_SHORT).show()
}
We can also list all external BLE devices that have been saved.
Code:
val bleDeviceInfoTask = bleController!!.savedDevices
bleDeviceInfoTask.addOnSuccessListener { bleDeviceInfos -> // bleDeviceInfos contains the list of the saved devices.
for (bleDeviceInfo in bleDeviceInfos) {
Toast.makeText(this, "Matched BLE devices:" + bleDeviceInfo.deviceName, Toast.LENGTH_SHORT).show()
}
}
We can obtain data collectors of the device.We need to use the SensorsController.getDataCollectors method to obtain all saved data collectors.
Code:
val dataCollectorsOptions = DataCollectorsOptions.Builder().setDataTypes(DataType.DT_INSTANTANEOUS_HEART_RATE).build()
sensorsController!!.getDataCollectors(dataCollectorsOptions)
.addOnSuccessListener { dataCollectors ->
// dataCollectors contains the returned available data collectors.
for (dataCollector in dataCollectors) {
Toast.makeText(this, "Available data collector:" + dataCollector.dataCollectorName, Toast.LENGTH_SHORT).show()
// Save the heart rate data collectors for later use when registering the listener.
[email protected] = dataCollector
}
}
.addOnFailureListener {
Toast.makeText(this, "findDataCollectors failed... ", Toast.LENGTH_SHORT).show()
}
We must use the SensorsController.register method to register a listener for receiving raw data reported by a specified data collector.We will create a listener object for heart rate data. The received heart rate data will be called back to onSamplePoint.
Code:
sensorsController!!.register(
SensorOptions.Builder()
.setDataType(DataType.DT_INSTANTANEOUS_HEART_RATE)
.setDataCollector(dataCollector)
.setCollectionRate(1, TimeUnit.SECONDS)
.build(),
heartrateListener
).addOnSuccessListener(OnSuccessListener<Void?> {
Toast.makeText(this, "registerHeartRate successed... ", Toast.LENGTH_SHORT).show()
}).addOnFailureListener(OnFailureListener {
Toast.makeText(this, "registerHeartRate failed... ", Toast.LENGTH_SHORT).show()
})
private val heartrateListener = OnSamplePointListener { samplePoint ->
Toast.makeText(this, "Heart rate received " + samplePoint.getFieldValue(Field.FIELD_BPM), Toast.LENGTH_SHORT).show()
}
If we do not need to receive real-time data, we can unregister a listener.We need to use the SensorsController.unregister method to unregister the listener.
Code:
sensorsController!!.unregister(heartrateListener).addOnSuccessListener {
Toast.makeText(this, "unregisterHeartRate successed... ", Toast.LENGTH_SHORT).show()
}.addOnFailureListener {
Toast.makeText(this, "unregisterHeartRate failed... ", Toast.LENGTH_SHORT).show()
}
References:
https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides/service-introduction-0000001050071661
https://forums.developer.huawei.com/forumPortal/en/home
Well explained, can we connect to Non-Huawei devices?
Introduction
To help understand the image content, the scene detection service can classify the scenario content of images and add labels, such as outdoor scenery, indoor places, and buildings.You can create more customised experiences for users based on the data detected from image. Currently Huawei supports detection of 102 scenarios. For details about the scenarios, refer to List of Scenario Identification Categories.
This service can be used to identify image sets by scenario and create intelligent album sets. You can also select various camera parameters based on the scene in your app, to help users to take better-looking photos.
Prerequisite
The scene detection service supports integration with Android 6.0 and later versions.
The scene detection needs READ_EXTERNAL_STORAGE and CAMERA in AndroidManifest.xml.
Implementation of dynamic permission for camera and storage is not covered in this article. Please make sure to integrate dynamic permission feature.
Development
1. Register as a developer account in AppGallery Connect.
2. Create an application and enable ML kit from AppGallery connect.
3. Refer to Service Enabling. Integrate AppGallery connect SDK. Refer to AppGallery Connect Service Getting Started.
4. Add Huawei Scene detection dependencies in app-level build.gradle.
Code:
// ML Scene Detection SDK
implementation 'com.huawei.hms:ml-computer-vision-scenedetection:2.0.3.300'
// Import the scene detection model package.
implementation 'com.huawei.hms:ml-computer-vision-scenedetection-model:2.0.3.300'
implementation 'com.huawei.hms:ml-computer-vision-cloud:2.0.3.300'
5. Sync the gradle.
We have an Activity (MainActivity.java) which has floating buttons to select static scene detection and live scene detection.
Static scene detection is used to detect scene in static images. When we select a photo, the scene detection service returns the results.
Camera stream (Live) scene detection can process camera streams, convert video frames into an MLFrame object, and detect scenarios using the static image detection method.
Implementation of Static scene detection
Code:
private void sceneDetectionEvaluation(Bitmap bitmap) {
//Create a scene detection analyzer instance based on the customized configuration.
MLSceneDetectionAnalyzerSetting setting = new MLSceneDetectionAnalyzerSetting.Factory()
// Set confidence for scene detection.
.setConfidence(confidence)
.create();
analyzer = MLSceneDetectionAnalyzerFactory.getInstance().getSceneDetectionAnalyzer(setting);
MLFrame frame = new MLFrame.Creator().setBitmap(bitmap).create();
Task<List<MLSceneDetection>> task = analyzer.asyncAnalyseFrame(frame);
task.addOnSuccessListener(new OnSuccessListener<List<MLSceneDetection>>() {
public void onSuccess(List<MLSceneDetection> result) {
// Processing logic for scene detection success.
for( MLSceneDetection sceneDetection : result) {
sb.append("Detected Scene : " + sceneDetection.getResult() + " , " + "Confidence : " + sceneDetection.getConfidence() + "\n");
tvResult.setText(sb.toString());
if (analyzer != null) {
analyzer.stop();
}
}
}})
.addOnFailureListener(new OnFailureListener() {
public void onFailure(Exception e) {
// Processing logic for scene detection failure.
// failure.
if (e instanceof MLException) {
MLException mlException = (MLException)e;
// Obtain the result code. You can process the result code and customize respective messages displayed to users.
int errorCode = mlException.getErrCode();
// Obtain the error information. You can quickly locate the fault based on the result code.
String errorMessage = mlException.getMessage();
Log.e(TAG, "MLException : " + errorMessage +", error code: "+ String.valueOf(errorCode));
} else {
// Other errors.
Log.e(TAG, "Exception : " + e.getMessage());
}
if (analyzer != null) {
analyzer.stop();
}
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
if(analyzer != null) {
analyzer.stop();
}
}
We can set the settings MLSceneDetectionAnalyzerSetting() and set the confidence level for scene detection. setConfidence() methods needs to get float value. After settings are fixed, we can create the analyzer with settings value. Then, we can set the frame with bitmap. Lastly, we have created a task for list of MLSceneDetection object. We have listener functions for success and failure. The service returns list of results. The results have two parameter which are result and confidence. We can set the response to textView tvResult.
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
More details, you can visit https://forums.developer.huawei.com/forumPortal/en/topic/0204400184662360088
we will get accuracy result ?
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Introduction
In this article, we will learn about Huawei Map Kit in HarmonyOs. Map Kit is an SDK for map development. It covers map data of more than 200 countries and regions, and supports over 70 languages. With this SDK, you can easily integrate map-based functions into your HarmonyOs application.
Development Overview
You need to install DevEcho Studio IDE and I assume that you have prior knowledge about the Harmony Os and java.
Hardware Requirements
A computer (desktop or laptop) running windows 10.
A HarmonyOs Smart Watch (with the USB cable), which is used for debugging.
Software Requirements
Java JDK installation package.
DevEcho Studio installed.
Steps:
Step 1: Create a HarmonyOs Application.
Step 1: Create a project in AppGallery
Step 2: Configure App in AppGallery
Step 3: Follow the SDK integration steps
Let's start coding
MapAbilitySlice.java
Java:
public class MapAbilitySlice extends AbilitySlice {
private static final HiLogLabel LABEL_LOG = new HiLogLabel(3, 0xD001100, "TAG");
private MapView mMapView;
@Override
public void onStart(Intent intent) {
super.onStart(intent);
CommonContext.setContext(this);
// Declaring and Initializing the HuaweiMapOptions Object
HuaweiMapOptions huaweiMapOptions = new HuaweiMapOptions();
// Initialize Camera Properties
CameraPosition cameraPosition =
new CameraPosition(new LatLng(12.972442, 77.580643), 10, 0, 0);
huaweiMapOptions
// Set Camera Properties
.camera(cameraPosition)
// Enables or disables the zoom function. By default, the zoom function is enabled.
.zoomControlsEnabled(false)
// Sets whether the compass is available. The compass is available by default.
.compassEnabled(true)
// Specifies whether the zoom gesture is available. By default, the zoom gesture is available.
.zoomGesturesEnabled(true)
// Specifies whether to enable the scrolling gesture. By default, the scrolling gesture is enabled.
.scrollGesturesEnabled(true)
// Specifies whether the rotation gesture is available. By default, the rotation gesture is available.
.rotateGesturesEnabled(false)
// Specifies whether the tilt gesture is available. By default, the tilt gesture is available.
.tiltGesturesEnabled(true)
// Sets whether the map is in lite mode. The default value is No.
.liteMode(false)
// Set Preference Minimum Zoom Level
.minZoomPreference(3)
// Set Preference Maximum Zoom Level
.maxZoomPreference(13);
// Initialize the MapView object.
mMapView = new MapView(this,huaweiMapOptions);
// Create the MapView object.
mMapView.onCreate();
// Obtains the HuaweiMap object.
mMapView.getMapAsync(new OnMapReadyCallback() {
@Override
public void onMapReady(HuaweiMap huaweiMap) {
HuaweiMap mHuaweiMap = huaweiMap;
mHuaweiMap.setOnMapClickListener(new OnMapClickListener() {
@Override
public void onMapClick(LatLng latLng) {
new ToastDialog(CommonContext.getContext()).setText("onMapClick ").show();
}
});
// Initialize the Circle object.
Circle mCircle = new Circle(this);
if (null == mHuaweiMap) {
return;
}
if (null != mCircle) {
mCircle.remove();
mCircle = null;
}
mCircle = mHuaweiMap.addCircle(new CircleOptions()
.center(new LatLng(12.972442, 77.580643))
.radius(500)
.fillColor(Color.GREEN.getValue()));
new ToastDialog(CommonContext.getContext()).setText("color green: " + Color.GREEN.getValue()).show();
int strokeColor = Color.RED.getValue();
float strokeWidth = 15.0f;
// Set the edge color of a circle
mCircle.setStrokeColor(strokeColor);
// Sets the edge width of a circle
mCircle.setStrokeWidth(strokeWidth);
}
});
// Create a layout.
ComponentContainer.LayoutConfig config = new ComponentContainer.LayoutConfig(ComponentContainer.LayoutConfig.MATCH_PARENT, ComponentContainer.LayoutConfig.MATCH_PARENT);
PositionLayout myLayout = new PositionLayout(this);
myLayout.setLayoutConfig(config);
ShapeElement element = new ShapeElement();
element.setShape(ShapeElement.RECTANGLE);
element.setRgbColor(new RgbColor(255, 255, 255));
myLayout.addComponent(mMapView);
super.setUIContent(myLayout);
}
}
Result
Tips and Tricks
Add required dependencies without fail.
Add required images in resources > base > media.
Add custom strings in resources > base > element > string.json.
Define supporting devices in config.json file.
Do not log the sensitive data.
Enable required service in AppGallery Connect.
Use respective Log methods to print logs.
Conclusion
In this article, we have learnt, integration of Huawei Map in HarmonyOs wearable device using Huawei Map Kit. Sample application shows how to implement Map kit in HarmonyOs Wearables device. Hope this articles helps you to understand and integration of map kit, you can use this feature in your HarmonyOs application to display map in wearable devices.
Thank you so much for reading this article and I hope this article helps you to understand Huawei Map Kit in HarmonyOS. Please provide your comments in the comment section and like.
References
Map Kit
Checkout in forum