1、添加 依赖包:

implementation 'no.nordicsemi.android:dfu:1.11.0'

2、DfuService类继承  DfuBaseService

package com.example.ycblesdkdemo.dfu;

import android.app.Activity;
import android.os.Bundle; import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity; import no.nordicsemi.android.dfu.DfuBaseService; /**
* @author Finn_ZENGYUAN
* Blog:https://www.cnblogs.com/finn21/
* @date :2021/9/23 11:49
* @description:
*/
public class DfuService extends DfuBaseService { @Override
protected Class<? extends Activity> getNotificationTarget() {
return NotificationActivity.class;
} @Override
protected boolean isDebug() {
return true;
} @Override
public void onDestroy() {
super.onDestroy();
}
} class NotificationActivity extends AppCompatActivity { @Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// if (isTaskRoot()) {
// // Start the app before finishing
// final Intent intent = new Intent(this, UpdateZipActivity.class);
// intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// intent.putExtras(getIntent().getExtras()); // copy all extras
// startActivity(intent);
// }
//
// finish();
}
}

3、添加工具类  DfuUtils

package com.example.ycblesdkdemo.dfu;

import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.util.Log; import no.nordicsemi.android.dfu.DfuProgressListener;
import no.nordicsemi.android.dfu.DfuServiceController;
import no.nordicsemi.android.dfu.DfuServiceInitiator;
import no.nordicsemi.android.dfu.DfuServiceListenerHelper; import static android.content.Context.ACTIVITY_SERVICE; /**
* @author Finn_ZENGYUAN
* Blog:https://www.cnblogs.com/finn21/
* @date :2021/9/23 11:45
* @description:
*/
public class DfuUtils { private static DfuUtils dfuUtils;
private DfuServiceController serviceController;
private DfuServiceInitiator starter; public static DfuUtils getInstance() {
if (dfuUtils == null) {
synchronized (DfuUtils.class) {
if (dfuUtils == null) {
dfuUtils = new DfuUtils(); }
}
}
return dfuUtils;
} public void setmDfuProgressListener(Context mContext, DfuProgressListener dfuProgressListener) {
DfuServiceListenerHelper.registerProgressListener(mContext, dfuProgressListener); //监听升级进度
} //开始升级 /**
*
* @param mContext
* @param deviceMac 蓝牙mAC地址
* @param deviceName 蓝牙名称
* @param mDeviceZipFilePath 要升级的固件的地址
*/
public void startUpdate(Context mContext, String deviceMac, String deviceName, String mDeviceZipFilePath) {
if (mDeviceZipFilePath == null) {
// ToastUtils.showShort(mContext, mContext.getResources().getString(R.string.update_no_path));
Log.e("升级","开始升级");
return;
}
//闪退问题解决 兼容 启动前台通知的问题,因为这个库在升级的时候会在通知栏显示进度,
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
DfuServiceInitiator.createDfuNotificationChannel(mContext);
} starter = new DfuServiceInitiator(deviceMac)
.setDeviceName(deviceName)//设备名称
.setKeepBond(false)//保持设备绑定 官方demo为false
.setForceDfu(false)
.setPacketsReceiptNotificationsEnabled(false)
.setPacketsReceiptNotificationsValue(12)
.setUnsafeExperimentalButtonlessServiceInSecureDfuEnabled(true);//官方ndemo为true
// If you want to have experimental buttonless DFU feature supported call additionally:
starter.setZip(mDeviceZipFilePath);
serviceController = starter.start(mContext, DfuService.class); //启动升级服务
} //暂停升级
public void pauseDevice(Context mContext) {
if (isDfuServiceRunning(mContext) && serviceController != null) {
serviceController.pause();
}
} //销毁升级
public void abortDevice(Context mContext) {
if (isDfuServiceRunning(mContext) && serviceController != null) {
serviceController.abort();
}
} /**
* 判断dfu状态
*
* @return
*/
@SuppressLint("NewApi")
private boolean isDfuServiceRunning(Context mContext) {
final ActivityManager manager = (ActivityManager) mContext.getSystemService(ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (DfuService.class.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
} //退出 dfu
public void dispose(Context mContext,DfuProgressListener dfuProgressListener) {
DfuServiceListenerHelper.unregisterProgressListener(mContext, dfuProgressListener);
if (isDfuServiceRunning(mContext)) {
if (serviceController != null) {
serviceController.abort();
mContext.stopService(new Intent(mContext, DfuService.class));
}
}
if (starter != null) {
starter = null;
}
if (serviceController != null) {
serviceController = null;
}
} }

4、当前Activity  继承  DfuProgressListener 实现方法如下

    //实现DfuProgressListener的回调函数
@Override
public void onDeviceConnecting(String deviceAddress) {
} @Override
public void onDeviceConnected(String deviceAddress) {
} @Override
public void onDfuProcessStarting(String deviceAddress) {
} @Override
public void onDfuProcessStarted(String deviceAddress) { } @Override
public void onEnablingDfuMode(String deviceAddress) { } @Override
public void onProgressChanged(String deviceAddress, int percent, float speed, float avgSpeed, int currentPart, int partsTotal) {
//percent 是进度 在这里可以展示进度条
Log.e("升级",deviceAddress+"升级进度 "+percent+"===="+speed+"===="+avgSpeed+"===="+currentPart+"===="+partsTotal);
} @Override
public void onFirmwareValidating(String deviceAddress) { } @Override
public void onDeviceDisconnecting(String deviceAddress) { } @Override
public void onDeviceDisconnected(String deviceAddress) { } @Override
public void onDfuCompleted(String deviceAddress) {
//升级成功
Log.e("升级",deviceAddress+"升级成功");
} @Override
public void onDfuAborted(String deviceAddress) {
//升级流产,失败
// let's wait a bit until we cancel the notification. When canceled immediately it will be recreated by service again.
//升级错误
Log.e("升级",deviceAddress+"升级失败");
} @Override
public void onError(String deviceAddress, int error, int errorType, String message) {
//升级错误
Log.e("升级",deviceAddress+"升级错误"+error+"===="+errorType+"===="+message);
}

5、开始,退出升级调用:

 private void DfuLoad(){//开始升级
//先注册进度以及升级状态回调
DfuUtils.getInstance().setmDfuProgressListener(mContext,this);//升级状态回调
//开始正式升级
DfuUtils.getInstance().startUpdate(mContext,macVal,localName,filepathval); }
private void OutDfuLoad(){//退出升级
DfuUtils.getInstance().dispose(mContext,this);//升级状态回调 }

加油!

Android蓝牙固件升级 DFU-OTA 固件升级的更多相关文章

  1. gokit 统计分析 M2M接入服务 OTA固件升级 硬件社交化

    统计分析 M2M接入服务  OTA固件升级 硬件社交化 统计分析 为智能硬件定制的统计分析服务.只需添加入一行代码的集成工作,多维度的设备使用和用户行为数据就能自动统计出来. 演示 特色一:设备上线情 ...

  2. android蓝牙打印机

    您还未登录!|登录|注册|帮助 首页 业界 移动 云计算 研发 论坛 博客 下载 更多 reality_jie的专栏 编程的过程是一种微妙的享受       目录视图 摘要视图 订阅 CSDN2013 ...

  3. Android蓝牙实例(和单片机蓝牙模块通信)

    最近做毕设,需要写一个简单的蓝牙APP进行交互,在网上也找了很多资料,终于给搞定了,这里分享一下^_^. 1.Android蓝牙编程 蓝牙3.0及以下版本编程需要使用UUID,UUID是通用唯一识别码 ...

  4. Android 蓝牙4.0 BLE

    Android ble (Bluetooth Low Energy) 蓝牙4.0,也就是说API level >= 18,且支持蓝牙4.0的手机才可以使用. BLE是蓝牙4.0的核心Profil ...

  5. android 蓝牙4.0 开发介绍

    最近一直在研究一个蓝牙功能 由于本人是菜鸟  学起来比较忙 一直搞了好久才弄懂 , 网上对蓝牙4.0也就是几个个dome 抄来抄去,全是英文注解 , 对英语不好的朋友来说 真是硬伤 , 一些没必要的描 ...

  6. 【转】android蓝牙开发---与蓝牙模块进行通信--不错

    原文网址:http://www.cnblogs.com/wenjiang/p/3200138.html 近半个月来一直在搞android蓝牙这方面,主要是项目需要与蓝牙模块进行通信.开头的进展很顺利, ...

  7. Android 蓝牙开发(整理大全)

    Android蓝牙开发 鉴于国内Android蓝牙开发的例子很少,以及蓝牙开发也比较少用到,所以找的资料不是很全. (一): 由于Android蓝牙的通信都需要用到UUID,如果由手机发起搜索,当搜索 ...

  8. android -- 蓝牙 bluetooth (四)OPP文件传输

    在前面android -- 蓝牙 bluetooth (一) 入门文章结尾中提到了会按四个方面来写这系列的文章,前面已写了蓝牙打开和蓝牙搜索,这次一起来看下蓝牙文件分享的流程,也就是蓝牙应用opp目录 ...

  9. android -- 蓝牙 bluetooth (三)搜索蓝牙

    接上篇打开蓝牙继续,来一起看下蓝牙搜索的流程,触发蓝牙搜索的条件形式上有两种,一是在蓝牙设置界面开启蓝牙会直接开始搜索,另一个是先打开蓝牙开关在进入蓝牙设置界面也会触发搜索,也可能还有其它触发方式,但 ...

  10. android -- 蓝牙 bluetooth (一) 入门

    前段时间在 网上看了一些关于android蓝牙的文章,发现大部分是基于老版本(4.1以前含4.1)的源码,虽然无碍了解蓝牙的基本原理和工作流程,但对着4.2.2的代码看起来总是有些遗憾.所以针对4.2 ...

随机推荐

  1. CCRD_TOC_2008年第6期

    中信国健临床通讯 2008年第6期 EULAR专辑 目 录   类风湿关节炎 1. 积极的上台阶治疗策略让早期RA患者获得持久临床缓解 van DR Woude D, et al. EULAR 200 ...

  2. Vue 关键概念介绍

    Vue现在已经迭代到 3+ 版本,阅读官方文档的过程中发现作者的一些理念和思路很合我口味,很多概念与方案都是基于解决实际问题提出并实现的,且在权衡利弊后勇于打破常规,比如如何看待关注点分离?.可见,V ...

  3. 工业仿真:Chai 3D之点云技术

    推荐:将 NSDT场景编辑器 加入你的3D开发工具链. 介绍   点云是三维坐标系中的一组数据点.在 CHAI3D 中,这些点由 X.Y 和 Z 坐标定义,通常用于表示对象的外表面.   点云可以由3 ...

  4. Jmeter 常用命令 之 CLI模式

    一.Jmeter的非GUI模式命令(即CLI模式command line) 命令: 命令参数 命令释义 -n 设置命令行模式 -t 指定JMX脚本路径参数为:JMX脚本路径,若非当前目录需用全路径或相 ...

  5. vue模板三目运算判断报错

    问题: 关于vue三目运算符提示报错 1.三目运算符等于判断 {{ a==b ? '是' : '否'}} 2.其他三目运算符 <代表小于号(<) >代表大于符号(>) ≤表示小 ...

  6. springboot-maven打包项目

    在project 标签内,新增一下内容 <build> <plugins> <!--打包项目--> <plugin> <groupId>or ...

  7. MySQL/MariaDB如何创建用户并限制指定才能IP访问?

    MySQL/MariaDB如何创建用户并限制指定才能IP访问? 登入数据 $ mysql --version mysql Ver 15.1 Distrib 10.9.3-MariaDB, for de ...

  8. Python 获取磁盘使用

    import psutil def get_disk_info(): content = "" for disk in psutil.disk_partitions(): if ' ...

  9. python实现发票二维码解析

    通过发票左上角的二维码信息,获取发票的关键信息,只需将图片格式的电子发票或扫描后的发票图片传入即可. 测试结果如下: 增值税电子普通发票:{'发票代码': '031xxxxxx311', '发票号码' ...

  10. spring-boot logback 日志

    一.引入依赖 二.配置日志文件 三.完事啦!