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


  • 相关阅读:
    json格式
    UICollectionViewLayout继承UICollectionViewFlowLayout自定义布局
    iOS中如何生成二维码
    Xcode升级之后插件无法使用与不小心点击Skipbundle的解决办法
    如何上传本地代码到github
    Xcode实用快捷键以及Mac一些常用指令
    0925-0926 函数注意点
    0921控制结构注意点
    0920逻辑运算符,位运算,移位运算,三元运算符,短路性注意点
    0919表达式&运算符注意点
  • 原文地址:https://www.cnblogs.com/yjpjy/p/10178516.html
Copyright © 2011-2022 走看看