
回复
本文原创发布在华为开发者社区,更多鸿蒙场景化示例请见华为开发者联盟官网“行业实践与常见问题”专题页。
相关场景示例推荐:宝宝身高体重记录曲线、蓝牙通信
本示例是主要分为3个部分:
打开应用后,用户开启蓝牙授权,进入主页面,根据需求调用功能。(具体使用见readme)
工程主页请求蓝牙授权
页面打开时获取设备蓝牙开启状态
以serviceUuid为过滤条件进行扫描(见下代码),实际开发过程中可以按业务场景配置扫描条件或不设置,具体可以参考官网
基于扫描出来的随机Mac地址(deviceId)做连接/断开操作
可以基于connectStateChange获取连接状态做其他操作
let scanFilter: ble.ScanFilter = {
serviceUuid: "00001810-0000-1000-8000-00805F9B34FB"
};
let scanOptions: ble.ScanOptions = {
interval: 100,
dutyMode: ble.ScanDuty.SCAN_MODE_LOW_POWER,
matchMode: ble.MatchMode.MATCH_MODE_AGGRESSIVE,
}
ble.startBLEScan([scanFilter], scanOptions);
this.change = !this.change
this.oldWeight = this.nowWeight
this.change === false ? (this.weight = '100%') : (this.weight = (componentUtils.getRectangleById('flag2')
.size
.width
.toString() + 'px'))
//在这里传入测量的当前体重
//如果体重没有变化,不会触发左侧刷新,因此多加一条判断来刷新左侧
this.oldWeight === this.nowWeight ? (this.DV = 0) : (this.DV = this.nowWeight - this.oldWeight)
TextPickerDialog.show({
//滑动弹窗选择器,封装函数更好
range: this.goals,
selected: this.select,
disappearTextStyle: { color: Color.Red, font: { size: 15, weight: FontWeight.Lighter } },
textStyle: { color: Color.Black, font: { size: 20, weight: FontWeight.Normal } },
selectedTextStyle: { color: Color.Blue, font: { size: 30, weight: FontWeight.Bolder } },
onAccept: (value: TextPickerResult) => {
// 设置select为按下确定按钮时候的选中项index,这样当弹窗再次弹出时显示选中的是上一次确定的选项
this.select = value.index
hilog.info(0x0000, "TextPickerDialog:onAccept()" + JSON.stringify(value), '')
this.flag = value.value.toString(); //刷新状态,更改体重目标为选中的数值
},
onCancel: () => {
hilog.info(0x0000, "TextPickerDialog:onCancel()", '')
},
onChange: (value: TextPickerResult) => {
hilog.info(0x0000, "TextPickerDialog:onChange()" + JSON.stringify(value), '')
}
})
Canvas(this.context)
.width(this.weight)
.height('100%')
.onReady(() => {...})
//添加一个画布组件,利用其事件函数进行位置计算
Canvas(this.context)
.width('100%')
.height('100%')
.onReady(() => {
...
// 如果想要设置x轴偏移随体重变化而变化,可以自行计算x坐标,根据当前体重占当前区间的百分比以及屏幕和线段的长度就可以计算出来
if (this.weight >= WeightHiatus.START_HIATUS && this.weight <= WeightHiatus.FIRST_HIATUS) { //偏瘦图片,后续自行更换
let x_Offset = px2vp(componentUtils.getRectangleById('line1').localOffset.x) //计算每个线段相对于父组件的x偏移量
this.context.drawImage(Picture.img1, X_Positoin(x_Offset, WeightHiatus.START_HIATUS, WeightHiatus.FIRST_HIATUS, this.weight, lineWith), y_Position, SizeNumber.SIZE3, SizeNumber.SIZE3)
} else if (this.weight <= WeightHiatus.SECOND_HIATUS) {...}
else if (this.weight <= WeightHiatus.THIRD_HIATUS){...}
else if (this.weight <= WeightHiatus.FOURTH_HIATUS) {...} else {...}
})
getPedometerData() {
try {
sensor.once(sensor.SensorId.PEDOMETER, (data: sensor.PedometerResponse) => {
hilog.info(0x0000, 'Succeeded in invoking once. Step count: ' + data.steps, '');
this.stepNum = data.steps ? data.steps : 0;
this.onPedometer()
});
} catch (error) {
let e: BusinessError = error as BusinessError;
hilog.error(0x0000, `Failed to invoke once. Code: ${e.code}, message: ${e.message}`, '');
}
}
onPedometer() {
try {
sensor.on(sensor.SensorId.PEDOMETER, (data: sensor.PedometerResponse) => {
hilog.info(0x0000, 'Succeeded in invoking on. Step count: ' + data.steps, '');
this.stepNum = data.steps ? data.steps : 0;
}, { interval: 100000000 });
} catch (error) {
let e: BusinessError = error as BusinessError;
hilog.error(0x0000, `Failed to invoke on. Code: ${e.code}, message: ${e.message}`, '');
}
}