为啥要写这篇文章 !
- 想必能看到这篇文章一定是被鸿蒙版本的杰理SDK
折磨
过的吧! - 杰理提供的 demo 业务量太大,提供的文档 api 写的很全面。但是没有接入流程。
- 所以对于第一次接触这个产品的我来讲,一头雾水不知道如何做起。
- 但是又不想把整个 杰理demo 全部搬运过来,体积太大了。
- 自己尝试又不知道从何入手。
- 希望 杰理 能看到后面 HarmonyOS NEXT版本文档出一个初始化对接必要流程.
下面是我查询到的 鸿蒙next 版本的对接说明
- HarmonyOS NEXt版本对接的api 推荐这个: 杰理SDK HarmonyOS Next 版本
- 想了解初始化流程和说明,推荐这个: 杰理OTA外接库开发文档(HarmonyOS Next)
## 下面我来介绍一下 HarmonyOS Next 中 BLE杰理SDK对接流程!
正常初始化蓝牙
- 如何初始化蓝牙请参考 # HarmonyOS NEXT-蓝牙(Ble)开发流程——蓝牙流程说明
获取 杰理服务和特征值
- 如何获取服务和特征值请参考 # HarmonyOS NEXT-蓝牙(Ble)开发流程——获取 固件 携带的蓝牙服务
- 进行设备认证
- 进行 RCSP协议 初始化
进行必须的获取操作
- 这是 杰理demo 在初始化后上写的 (必须) 的操作
- 但是我遇到的业务没有做这些获取也没有影响(当然这是一切正常的情况)
- 为了防止 BUG 还是做了获取操作
上面必须的流程做完可以尝试做业务了
- OTA
详细步骤
一. 正常初始化蓝牙 、二. 获取 杰理服务和特征值
- 这两步操作请参考# HarmonyOS NEXT-蓝牙(Ble)开发流程
三. 进行设备认证 ⭐
- 在获取到 杰理的服务和特征值之后,必须要先进行设备认证
- ⭐ writeTrait_JieLi 这个是我在第二步获取到的 杰理的写入特征值
⭐ bleSendClass.BLESEND_autoPushSend 这个是消息发送队列
- 用于分包向固件写入数据 # 通过 写入特征 来进行向 固件 写入内容
let authListener: JL_Auth.AuthListener = { onSendData: (devId: string, data: ArrayBuffer) => { // 发送认证数据 if (writeTrait_JieLi) { bleSendClass.BLESEND_autoPushSend({serviceData:new Uint8Array(data),serviceType:writeTrait_JieLi}) } }, onAuthSuccess: () => { console.log("认证成功"); }, onAuthFailed: () => { console.log("认证失败"); }, } // 开始认证 let JLAuth = new JL_Auth.Auth(); JLAuth.startAuth(deviceId, authListener)
四.进行 RCSP协议 初始化
- 等到设备认证成功之后在进行 RCSP协议的初始化
- 在第
3
步onAuthSuccess
回调代表已经认证成功了,可以进行 RCSP协议的初始化 - ⭐ 但是需要知道一点 所谓的
初始化
,不过是把连接状态同步给 RCSP协议对象 。
// ⭐1. 首先我们需要先创建好 RCSP协议对象
let BLEPROPERTY_rcspImpl: JL_RCSP.RcspImpl = new JL_RCSP.RcspImpl();
// ⭐⭐⭐ 然后给 RCSP协议对象 添加Rcsp事件回调 和 设置RCSP数据发送回调
// 2. 添加 RCSP事件回调
// 2-1 创建回调函数
let oRcspCallback: JL_RCSP.OnRcspCallback = {
//Rcsp协议初始化回调
onRcspInit: async (device, isInit) => {
// ⭐ isInit true 代表初始化成功
// ⭐ isInit false 代表初始化失败
console.log('Rcsp协议已经初始化,结果为:', isInit)
},
//RCSP错误事件回调
onRcspError: (_device, _error, message) => {
console.log('RCSP错误事件回调', message)
},
//需要强制升级回调
onMandatoryUpgrade: () => {
console.log('需要强制升级回调')
},
//设备连接状态
onConnectStateChange: () => {
console.log('设备连接状态')
},
//设备主动发送的rcsp命令回调
onRcspCommand: () => {
},
//设备回复的rcsp命令回调
onRcspResponse: () => {
},
//设备主动发送的数据命令回调
onRcspDataCmd: () => {
},
}
// 2-2 添加事件回调
BLEPROPERTY_rcspImpl.addOnRcspCallback(oRcspCallback)
// 3. 设置RCSP数据发送回调
// 3-1 创建发送数据的回调函数
let onSendDataCallback: JL_RCSP.OnSendDataCallback = {
//向设备发送RCSP数据包
sendDataToDevice: (device, data) => {
// 把收到的消息依旧放入消息队列
bleSendClass.BLESEND_autoPushSend({serviceData:data ,serviceType:writeTrait_JieLi})
return true
}
}
// 3-2 设置RCSP数据发送回调
BLEPROPERTY_rcspImpl.setOnSendDataCallback(this.onSendDataCallback)
// 4 连接状态传递 -- 这两步骤必须做
// 4-1 通知设备状态
BLEPROPERTY_rcspImpl.transmitDeviceState(new JL_RCSP.BtDevice(deviceId), JL_RCSP.ConnectState.CONNECTED)
// 4-2 初始化RCSP操作封装对象
const operateWrapper = new JL_RCSPOP.RcspOperateWrapper(rcspImpl);
// 注意点:⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
// 1、2、3 这个步骤在认证之前做也可以。不用非的等到认证成功再去创建。
// 4-2 可以在 步骤三 中的 onAuthSuccess 回调中做
// 4-1 需要在 'BLECharacteristicChange' 监听蓝牙状态中调用,通知杰理SDK当前设备的状态
// 并且,new JL_RCSP.BtDevice(deviceId) 这个需要保存下来让更新状态的时候为 同一个设备。
// 所以当设备认证成功后,执行 4-2 , 然后实时的还要更新当前设备的状态
五. 进行必须的获取操作
- 这个是根据 杰理 提供的 demo 中所描述必须操作
- 在 Rcsp协议初始化回调
onRcspInit
回调中执行。但是要是初始化成功状态 这里只是展示需要的操作,实际工作中需要做好错误处理
//step:获取系统flash信息(必须) const flashInfo = await operateWrapper.getOperateByClass(JL_RCSPOP.OPWatch.OperateWatch.prototype)?.getFlashInfo() //step:获取在线的SDCardBean信息(在线的存储设备)(必须) const lineSdCardBeans = await operateWrapper.getOperateByClass(JL_RCSPOP.OPFile.OperateFile.prototype)?.getOnLineSdCardBeansAsync() //step:读取表盘列表(必须) const diallist = await operateWrapper.getOperateByClass(JL_RCSPOP.OPWatchDial.OperateWatchDial.prototype)?.getWatchResourseFileList() //step:获取手表配置信息(必须) const configureInfo = await operateWrapper.getOperateByClass(JL_RCSPOP.OPDevice.OperateDevice.prototype)?.getDeviceConfigureInfo() //step:读取手表是否在运动模式(必须) const sportStatus = await operateWrapper.getOperateByClass(JL_RCSPOP.OPSport.OperateSport.prototype)?.getSportsStatus(true)
做完上述操作,杰理SDK
就已经把 关键性动作
做完了。剩下就是看 API 完成业务和整个项目的架构
有一个需要知道的地方可以优化的地方
getOperateByClass 用来获取对应RCSP操作OP
- 注意:在
设备未改变
的情况下,RCSP对象是同一个
的情况下。getOperateByClass 获取到的操作类,为同一个
; - 所以可以把 获取对象的操作类,可以保存起来下次直接使用。
- 注意:在
下面讲一下 OTA升级流程
- 打开升级资源文件
- 创建 OTA类
- 开始升级
- 设备回连函数
更新RCSP协议
详细步骤
一 打开升级资源文件
如果是线上资源则需要先把资源下载并保存到本地
// updateFilePath 是资源文件的路径 let file = fileIo.openSync(updateFilePath, fileIo.OpenMode.READ_WRITE); // 获取文件的 文件描述符fd let fileFD = file.fd; // ⭐⭐⭐ 注意:现在获取完了不要关闭文件!!!!
二 创建 OTA类
const OTAManager = new JL_OTA.RcspOTAManager(rcspImpl);
三 开始升级
开始升级通过
OTAManager.startOTA
方法进行升级- 需要俩个参数,第一个是配置信息,第二个是 回调对象
// 1. 创建 配置信息
let otaConfig: JL_OTA.OtaConfig = new JL_OTA.OtaConfig();
otaConfig.isSupportNewRebootWay = true;
// 2. 创建 回调对象
let upgradeCallback: JL_OTA.OnUpgradeCallback = {
onStartOTA: () => {
console.log('OTA开始')
},
onReadData: (offset: number, size: number): Uint8Array => {
console.log('OTA读取升级数据并返回')
},
onNeedReconnect: (reConnectMsg: JL_OTA.ReconnectInfo) => {
console.log('OTA需要回连进行升级重启')
},
onProgress: (type: JL_OTA.UpgradeType, progress: number) => {
console.log('OTA当前升级进度')
},
onStopOTA: () => {
console.log('OTA升级结束')
},
onCancelOTA: () => {
console.log('OTA取消升级')
},
onError: (error: number, message: string) => {
console.log('OTA升级出现错误')
},
};
// 通过 startOTA 方法开始升级
OTAManager.startOTA(otaConfig, upgradeCallback);
在进行升级回连函数之前,先来完善下,OTA的回调对象 upgradeCallback
- 只有
onReadData
读取升级数据返回给SDk 和onNeedReconnect
进行设备回连。这俩个回调是必须要做的,这个是升级的必须步骤。 剩下的内容都是自己业务处理和错误处理。非必须实现
// ⭐⭐⭐ 1. onReadData 读取升级资源文件进度并返回给 SDK onReadData: (offset: number, size: number): Uint8Array => { const buffer = new Uint8Array(size) const result = fileIo.readSync(fileFD, buffer.buffer, { offset: offset, length: size }) if (result == size) { return buffer } else { return new Uint8Array(); } } // ⭐⭐⭐ 2. onNeedReconnect 设备回连 onNeedReconnect: (reConnectMsg: JL_OTA.ReconnectInfo) => { // 回连设备的 MAC 地址 const oldDeviceMac = reConnectMsg.deviceBleMac?.toUpperCase().replace(/:/g, ""); // 断开已经连接的设备然后重置所有数据 // 1. 断开连接设备 // 2. 重置所有数据(包括设备信息、蓝牙gattClient、和所有 杰理相关的所有数据) // ⭐ 3. 但是需要保留一个数据就是刚刚为了升级创建的 OTAManager , 因为这个等下回连还需要用到 // 断开连接重置所有数据之后,重新进行蓝牙扫描 // 把扫描到的数据执行 设备回连函数 },
四、设备回连函数
- 这个完全可以直接写在
onNeedReconnect
函数里面,我是为了精简业务,所以拆分了一下。 // 重连函数 reconnect(scanResult: ble.ScanResult) { let result = false; // 判断刚刚获取的 回连设备的mac地址 if (oldDeviceMac) { const advertisStr = (JL_OTA.toHexString(scanResult.data) as string).toUpperCase(); const index = advertisStr.indexOf("D60541544F4C4A"); if (index != -1 && scanResult.data) { const unit8Array = new Uint8Array(scanResult.data); const macArray = unit8Array.slice((index / 2) + 8, (index / 2) + 14).reverse(); result = this.oldDeviceMac == JL_OTA.toHexString(macArray).toUpperCase(); } } // 判断当前扫描到的设备是需要回连的设备 if (result) { // 当找到了需要回连设备时候,重新完整走一下蓝牙的流程。 // 因为已经找到需要回连的设备了,直接走 第3步 开始连接。 // 这个第3步就是完整蓝牙流程中的第3步,可点击上方连接查看 // 而且杰理的 RCSP 协议一些数据也需要重新释放然后创建 } // return result; }
五、更新RCSP协议
当回连设备时候,回连状态通过
BLEConnectionStateChange
得到当前设备已连接时候。需要进行更新动作// 通过 OTAManager.updateRcspImpl 来更新,刚刚新创建的 RCSP协议 对象 OTAManager.updateRcspImpl(BLEPROPERTY_rcspImpl);
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。