zoukankan      html  css  js  c++  java
  • Android BLE dfu升级

    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();
    }


  • 相关阅读:
    C# 给图片添加透明的文字、图片水印
    Parallel.Invoke 并行的使用
    C# 使用NPOI 导出Excel
    选择性的使用 serialize() 进行序列化
    C#中 计时器用法
    关于图片加载失败后显示默认图片
    C# 文件下载
    C#中 什么是装箱和拆箱
    MySql中 where IN 字符串
    管理信息系统 课程设计
  • 原文地址:https://www.cnblogs.com/yjpjy/p/10178516.html
Copyright © 2011-2022 走看看