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. Python实战项目5-Git远程仓库/分支合并/冲突解决

    Git分支 为什么要有分支 可以保证主分支的版本都是可以查看的版本 我们都在开发分支开发,开发完成 合并代码 分支操作 分支查看 git branch 分支创建 git branch 分支名 分支切换 ...

  2. 红米手机刷 LineageOS (实操)

    参考:https://miuiver.com/how-to-flash-lineageos/ 实操机型:红米note8 1. 下载Android Platform-Tools 2. 下载对应机型的TW ...

  3. 奇迹网站编辑保存的时候提示Access is denied

    出现上面这个情况 只有在IIS模式下运行奇迹MU网站系统才会出现这个问题. 解决办法: 给网站目录赋予everyone权限 1.在网站目录右键属性 2在文件夹属性界面,点击"安全" ...

  4. 常用的git提交代码命令

    日常开发使用的git提交代码的方法 一.初始化本地仓库,提交代码,提交到远程git仓库 1.初始化代码仓库git init2.将当前目录下的所有文件放到暂存区git add .3.查看文件状态git ...

  5. 552. 学生出勤记录 II (Hard)

    问题描述 552. 学生出勤记录 II (Hard) 可以用字符串表示一个学生的出勤记录,其中的每个字符用来标记当天的出勤情况(缺勤.迟到.到场).记录中只含下面三种字符: 'A':Absent,缺勤 ...

  6. Java面向对像之方法重写

    方法重写Override 重写:需要有继承关系,子类重写父类的方法! 特点: 1.方法名必须相同 2.参数列表必须相同 3.修饰符:范围可以扩大:public > Protected > ...

  7. 前端下载csv文件

    var str = [ 'ssssssssssssssssssssssssssssssssssssssss' ]; var uri = 'data:text/csv;charset=utf-8,%EF ...

  8. 实现两个APP之间的跳转传值

    应用A 跳转到 应用B 1.在B中设置URL Schemes     加入一项item 并赋值,比如kiloMeter 并在B中实现 - (BOOL)application:(UIApplicatio ...

  9. Mysql主从备份指定库别名

    问题:replicate-rewrite-db  不生效 解决方案: 尝试 注释掉 replicate-do-db ,不写 replicate-ignore-db,只写 replicate-rewri ...

  10. 在SublimeText3中想使用快捷键调出插件ColorPicker不起作用办法解决

    在SublimeText3中快速打开插件ColorPicker的快捷健是Ctrl+Shift+C,但是我试了却不管用,后来发现是跟插件ConvertToUTF8插件中的快捷键冲突导致,知道原因就好办了 ...