dfu升级适用于nordic  nRF51  nRF52 的系统,github上提供了相关升级的库https://github.com/NordicSemiconductor/Android-DFU-Library 支持 Android 4.3+

gradle配置如下:

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

在使用前请先配置好BLE的相关权限以及动态权限 读写权限 定位等可以使用EasyPermission配置

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" />

第一步 我们创建一个service集成DfuBaseService

public class DfuService extends DfuBaseService {
public DfuService() {
} @Override
protected Class<? extends Activity> getNotificationTarget() {
return NotificationActivity.class;
} @Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
}

第二步 创建一个NotificationActivity

public class NotificationActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); // If this activity is the root activity of the task, the app is not running
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);
} // Now finish, which will drop you to the activity at which you were at the top of the task stack
finish();
}
}

其中UpdateZipActivity即为处理升级业务的界面

在这里要根据你的业务需求来,可以把升级包打包在apk里,也可以做成下载后升级的情况

如果是打包在apk里可以按下面做,如果你是下载的情况只需要改starter.setZip(uri, path); 传入文件uri和路径即可

private DfuServiceInitiator starter; 

starter = new DfuServiceInitiator(mac).setDeviceName("Smart Lock").setKeepBond(false).setPacketsReceiptNotificationsEnabled(true).setPacketsReceiptNotificationsValue(10);
// If you want to have experimental buttonless DFU feature supported call additionally:
starter.setUnsafeExperimentalButtonlessServiceInSecureDfuEnabled(true);
starter.setZip(R.raw.update24); //setDeviceName为设备过滤条件 setzip传入raw文件的路径即可

@Override
protected void onResume() {

DfuServiceListenerHelper.registerProgressListener(this, mDfuProgressListener); //监听升级进度
starter.start(this, DfuService.class); //启动升级服务

}

/**
* dfu升级监听
*/
private final DfuProgressListener mDfuProgressListener = new DfuProgressListener() {
@Override
public void onDeviceConnecting(String deviceAddress) {
Log.i("dfu", "onDeviceConnecting");
proBar.setIndeterminate(true);
airUpgradeTv.setText(R.string.dfu_status_connecting);
} @Override
public void onDeviceConnected(String deviceAddress) { } @Override
public void onDfuProcessStarting(String deviceAddress) {
proBar.setIndeterminate(true);
airUpgradeTv.setText(R.string.dfu_status_starting);
} @Override
public void onDfuProcessStarted(String deviceAddress) {
Log.i("dfu", "onDfuProcessStarted");
} @Override
public void onEnablingDfuMode(String deviceAddress) {
Log.i("dfu", "onEnablingDfuMode");
proBar.setIndeterminate(true);
airUpgradeTv.setText(R.string.dfu_status_switching_to_dfu);
} @Override
public void onProgressChanged(String deviceAddress, int percent, float speed, float avgSpeed, int currentPart, int partsTotal) {
Log.i("dfu", "onProgressChanged");
Log.i("dfu", "onProgressChanged" + percent);
proBar.setProgress(percent);
proBar.setIndeterminate(false);
airUpgradeTv.setText(percent + "%");
} @Override
public void onFirmwareValidating(String deviceAddress) {
Log.i("dfu", "onFirmwareValidating");
proBar.setIndeterminate(true);
airUpgradeTv.setText(R.string.dfu_status_validating);
} @Override
public void onDeviceDisconnecting(String deviceAddress) {
Log.i("dfu", "onDeviceDisconnecting");
} @Override
public void onDeviceDisconnected(String deviceAddress) {
Log.i("dfu", "onDeviceDisconnected");
proBar.setIndeterminate(true);
airUpgradeTv.setText(R.string.dfu_status_disconnecting); } @Override
public void onDfuCompleted(String deviceAddress) { airUpgradeTv.setText(R.string.dfu_status_completed);
proBar.setProgress(100);
proBar.setIndeterminate(false);
//升级成功
new Handler().postDelayed(new Runnable() {
@Override
public void run() { // if this activity is still open and upload process was completed, cancel the notification
final NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.cancel(DfuService.NOTIFICATION_ID); }
},200); } @Override
public void onDfuAborted(String deviceAddress) {
Log.i("dfu", "onDfuAborted");
//升级流产,失败
airUpgradeTv.setText(R.string.dfu_status_aborted);
// let's wait a bit until we cancel the notification. When canceled immediately it will be recreated by service again.
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
Toast.makeText(UpdateZipActivity.this, "升级出错", Toast.LENGTH_SHORT).show();
// if this activity is still open and upload process was completed, cancel the notification
final NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.cancel(DfuService.NOTIFICATION_ID);
}
}, 200); } @Override
public void onError(String deviceAddress, int error, int errorType, String message) {
Log.i("dfu", "onError"); airUpgradeTv.setText(getString(R.string.dfu_status_aborted));
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
// if this activity is still open and upload process was completed, cancel the notification
final NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.cancel(DfuService.NOTIFICATION_ID); }
}, 200); }
@Override
protected void onPause() {
  //取消监听
DfuServiceListenerHelper.unregisterProgressListener(this, mDfuProgressListener);
super.onPause();
}

Android BLE dfu升级的更多相关文章

  1. BLE空中升级 谈(二)

    BLE 空中升级谈 -- CC2541 的产品开发中OAD注意事项(续) TI CC2541支持多个硬件,多个软件对它进行空中升级,可以有不同的组合,硬件有 编号 名称 Hex 用法 1 Cc2540 ...

  2. Android BLE蓝牙详细解读

    代码地址如下:http://www.demodashi.com/demo/15062.html 随着物联网时代的到来,越来越多的智能硬件设备开始流行起来,比如智能手环.心率检测仪.以及各式各样的智能家 ...

  3. nrf52——DFU升级USB/UART升级方式详解(基于SDK开发例程)

    摘要:在前面的nrf52--DFU升级OTA升级方式详解(基于SDK开发例程)一文中我测试了基于蓝牙的OTA,本文将开始基于UART和USB(USB_CDC_)进行升级测试. 整体升级流程: 整个过程 ...

  4. nrf52——DFU升级OTA升级方式详解(基于SDK开发例程)

    在我们开始前,默认你已经安装好了一些基础工具,如nrfutil,如果你没有安装过请根据官方中文博客去安装好这些基础工具,连接如下:Nordic nRF5 SDK开发环境搭建(nRF51/nRF52芯片 ...

  5. Android BLE 蓝牙低功耗教程,中央BluetoothGatt和周边BluetoothGattServer的实现

    http://blog.csdn.net/wave_1102/article/details/39271693 分类: Android(105) 作者同类文章X Android4.3 规范了BLE的A ...

  6. 蓝牙4.0——Android BLE开发官方文档翻译

    ble4.0开发整理资料_百度文库 http://wenku.baidu.com/link?url=ZYix8_obOT37JUQyFv-t9Y0Sv7SPCIfmc5QwjW-aifxA8WJ4iW ...

  7. android开发 更新升级安装到一半自动闪退

    如题:android开发 更新升级安装到一半自动闪退,,,解决办法,如下(红色为我新增的代码) /**     * 安装APK文件     */    private void installApk( ...

  8. 【转】蓝牙4.0——Android BLE开发官方文档翻译

    原文网址:http://ricardoli.com/2014/07/31/%E8%93%9D%E7%89%9940%E2%80%94%E2%80%94android-ble%E5%BC%80%E5%8 ...

  9. Android ble 蓝牙4.0 总结

    本文介绍Android ble 蓝牙4.0,也就是说API level >= 18,且支持蓝牙4.0的手机才可以使用,如果手机系统版本API level < 18,也是用不了蓝牙4.0的哦 ...

随机推荐

  1. vim搜索及高亮取消

    1. 命令模式下,输入:/字符串 比如搜索user, 输入/user 按下回车之后,可以看到vim已经把光标移动到该字符处和高亮了匹配的字符串 2. 查看下一个匹配,按下n(小写n) 3. 跳转到上一 ...

  2. 新版seqseq接口说明

    attention_mechanism = tf.contrib.seq2seq.BahdanauAttention(num_units=FLAGS.rnn_hidden_size, memory = ...

  3. nodejs window平台上 以服务运行

    刚学nodejs  想使用 sc create 来创建服务,但是倒腾了很久没有弄出来,创建是成功了,使用 net start 启动服务报错,没有控制功能.后来网上找了一下 发现这个东西:nssm 使用 ...

  4. 【C/C++】C++11 Lambda

    Lambda C++11 中 lambda 是一个匿名函数对象 最简形式 []{ cout << "lambda" << endl; }(); // pri ...

  5. element-- 修改MessageBox 弹框 中确定和取消按钮顺序

    需求:修改弹框中的 取消/确定按钮顺序,及头部和底部背景颜色; 原ui效果图 需求ui效果图 方法:对取消及确定按钮自定义类名,样式重写

  6. C++标准模板库(STL)之Pair

    1.Pair的常用用法 pair:两个元素绑在一起作为一个合成元素.可以看成是两个元素的结构体. struct pair { typeName1 first; typeName2 second; }; ...

  7. PhotoShop常用的功能汇总

    1.将图层变为"智能对象"后如何调整大小? 答: ctrl + T 2.如何对文字添加投影? 答: 点击文字图层,“图层”->"图层样式"->&qu ...

  8. linux常用命令 cut字符截取命令

    cut 字符截取 cut [选项] 文件名 选项 -f 列号: 提取第几列 -d 分割符:按照指定的分隔符分割列 默认使用制表符("tab")进行分割 ssgao:Download ...

  9. ES6的let

    1.let声明的变量只在它所在的代码块有效. 例子: var a = [];for (var i = 0; i < 10; i++) {a[i] = function () {console.l ...

  10. 跟随我在oracle学习php(15)

    开发环境 独立开发环境:组成 Windows/Linux php Apache MySQL 集成开发环境:phpstudy wamp xammp 关系数据库: SQL: Struct Query La ...