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);//升級狀態回調 }
加油!