ota / 固件更新 / 空中升级 即 通过手机升级BLE蓝牙设备。
固件更新最重要的就是参考 官方升级依赖库、与 官方使用Demo
官方空中升级依赖库:https://github.com/NordicSemiconductor/Android-DFU-Library
官方使用Demo:https://github.com/NordicSemiconductor/Android-nRF-Toolbox
简单使用(如果你不花太长时间就想接入的Demo,当然也由于短小而不靠谱)
1、添加依赖(我用的不是最新版)
//固件更新 implementation 'no.nordicsemi.android:dfu:1.6.1'
2、配置参数与开始升级
/**进行空中升级 [zipPath]:升级文件*/
@WorkerThread//我是在子线程运行的,没在主线程测试过
private fun updateDevice(zipPath: String) {
//配置升级参数
val initiator = DfuServiceInitiator(mMac)//设备地址
initiator.setPacketsReceiptNotificationsEnabled(false)//启用或禁用数据包接收通知(PRN)过程
initiator.setUnsafeExperimentalButtonlessServiceInSecureDfuEnabled(true)//官方Demo为true
initiator.setDeviceName("智能手环")//设备名称,怎么写都行
initiator.setKeepBond(false)//保持设备绑定 官方Demo为false
initiator.setZip(File(zipPath).toUri(), zipPath)//指定更新文件(zip文件)
val controller = //您可以使用控制器暂停,恢复或中止DFU过程。
initiator.start(baseContext, DfuService::class.java)//调用此方法启动升级服务进行升级
}
3、创建上文用到的 DfuService
<!--仿照官方Demo-->
<service
android:name=".db.view.ota.DfuService"
android:exported="true">
<intent-filter>
<action android:name="no.nordicsemi.android.action.DFU_UPLOAD" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</service>
class DfuService : DfuBaseService() {
/**点击更新通知时打开此Activity*/
override fun getNotificationTarget(): Class<out Activity> {
return UpdateProgressActivity::class.java
}
override fun isDebug(): Boolean = true
}
4、在页面可见与不可见时进行升级监听
/**固件更新监听*/
private val dufProgressListener: DfuProgressListener? = object : DfuProgressListener {
/**设备连接了*/
override fun onDeviceConnected(deviceAddress: String?) {
MLog.d("onDeviceConnected() called with: " + "deviceAddress = [" + deviceAddress + "]")
}
/**升级准备开始*/
override fun onDfuProcessStarting(deviceAddress: String?) {
MLog.d("onDfuProcessStarting() called with: " + "deviceAddress = [" + deviceAddress + "]")
}
/**正在连接设备*/
override fun onDeviceConnecting(deviceAddress: String?) {
MLog.d("onDeviceConnecting() called with: " + "deviceAddress = [" + deviceAddress + "]")
}
/**更新进度开始*/
override fun onDfuProcessStarted(deviceAddress: String?) {
MLog.d("onDfuProcessStarted() called with: " + "deviceAddress = [" + deviceAddress + "]")
}
/**升级中的回调*/
override fun onProgressChanged(
deviceAddress: String?, percent: Int, speed: Float, avgSpeed: Float, currentPart: Int,
partsTotal: Int
) {
MLog.d("onProgressChanged() called with: " + "deviceAddress = [" + deviceAddress + "], percent = [" + percent + "], speed = [" + speed + "], avgSpeed = [" + avgSpeed + "], currentPart = [" + currentPart + "], partsTotal = [" + partsTotal + "]")
}
/**设备正在断开*/
override fun onDeviceDisconnecting(deviceAddress: String?) {
MLog.d("onDeviceDisconnecting() called with: " + "deviceAddress = [" + deviceAddress + "]")
}
/**设备断开了*/
override fun onDeviceDisconnected(deviceAddress: String?) {
MLog.d("onDeviceDisconnected() called with: " + "deviceAddress = [" + deviceAddress + "]")
}
/**升级完成*/
override fun onDfuCompleted(deviceAddress: String?) {
MLog.d("onDfuCompleted() called with: " + "deviceAddress = [" + deviceAddress + "]")
}
/**升级失败*/
override fun onError(
deviceAddress: String?, error: Int, errorType: Int, message: String?
) {
MLog.d("onError() called with: " + "deviceAddress = [" + deviceAddress + "], error = [" + error + "], errorType = [" + errorType + "], message = [" + message + "]")
}
/**固件验证-未用*/
override fun onFirmwareValidating(deviceAddress: String?) {
MLog.d("onFirmwareValidating() called with: " + "deviceAddress = [" + deviceAddress + "]")
}
/**未用*/
override fun onDfuAborted(deviceAddress: String?) {
MLog.d("onDfuAborted() called with: " + "deviceAddress = [" + deviceAddress + "]")
}
/**未用*/
override fun onEnablingDfuMode(deviceAddress: String?) {
MLog.d("onEnablingDfuMode() called with: " + "deviceAddress = [" + deviceAddress + "]")
}
}
override fun onResume() {
super.onResume()
DfuServiceListenerHelper.registerProgressListener(baseContext, dufProgressListener)
}
override fun onPause() {
super.onPause()
DfuServiceListenerHelper.unregisterProgressListener(baseContext, dufProgressListener)
}