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. Lucky Tree

    题目:http://codeforces.com/problemset/problem/109/C 题意:一棵树n个节点,组成一个图,每条边都有权值,对于i.j.k三个数,计算所有的 i 到 j 和 ...

  2. git 合并dev分支到 master分支 (merge)

    ## 查看分支列表 $ git branch -a ## 切换到本地dev分支 $ git checkout dev ## 更新本地dev 分支 $ git pull ## 切换到master 分支 ...

  3. Idea External Libraries 没有导入依赖

    Maven 下面是有依赖的,但是 Idea 的 External Libraries 没有导入进来,就非常奇怪,这个现象我在 Android Studio 也遇到过,要么找到 Maven 仓库,手动把 ...

  4. postgresql索引使用情况及坏索引处理

    1.postgresql中索引系统视图pg_stat_user_indexes TEST=# \d+ sys_stat_user_indexes View "SYS_CATALOG.sys_ ...

  5. java语言——跨平台原理,jre,jdk

    day1 Java是一种混合的编译运行方式:编译+解释(虚拟机) java的跨平台:在虚拟机中运行(jvm) jdk:jvm,核心类库,开发工具(开发环境) jre:Java的运行环境

  6. 常用的hive sql

    细节:sql 中有涉及到正则匹配函数的,要注意转义符号 因为在不同语言下正则匹配规则是否需要加转义符号是不同的,举例,regexp_replace 函数,在hive sql的正则匹配规则的 \d+ 需 ...

  7. Socket:由于系统缓冲区空间不足或队列已满,不能执行套接字上的操作

    https://blog.csdn.net/weixin_45932157/article/details/113999801 最近服务器的Socket代理软件经常报这个错误:log:Error On ...

  8. 四种语言刷算法之 组合总和 II

    力扣40. 组合总和 II 1.C void back(int* candidates, int candidatesSize, int target,int start,int *path,int ...

  9. STM32 I2C介绍和软件模拟I2C编程要点

    I2C协议层独特特征: 1. 通过地址(Master/Slave Address)区分不同的设备. 2. ACK信号体制,即通过ACK表示是否进行继续传输. 3.由SCL.SDA的四种关系,映射数据有 ...

  10. css小技巧【让背景最少是屏幕高度】【让三个字和四个字左右对齐】

    怎么让背景最少是屏幕高度 min-height: 100vh; 怎么让三个字和四个字左右对齐 text-align-last: justify;