api 'no.nordicsemi.android:dfu:1.6.1'
private void checkPermissions(){
String[] permissions = {Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.WRITE_EXTERNAL_STORAGE
};
List permissionDeniedList = new ArrayList<>();
for (String permission : permissions) {
int permissionCheck = ContextCompat.checkSelfPermission(this, permission);
if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
onPermissionGranted(permission);
} else {
permissionDeniedList.add(permission);
}
}
if (!permissionDeniedList.isEmpty()) {
String[] deniedPermissions = permissionDeniedList.toArray(new String[permissionDeniedList.size()]);
ActivityCompat.requestPermissions(this, deniedPermissions, 12);
}
package com.google.jzhou.dfutest.dfu_service;
import android.app.Activity;
import android.content.Intent;
import android.os.IBinder;
import no.nordicsemi.android.dfu.BuildConfig;
import no.nordicsemi.android.dfu.DfuBaseService;
public class DfuService extends DfuBaseService {
@Override
protected Class extends Activity> getNotificationTarget() {
return NotificationActivity.class;
}
@Override
protected boolean isDebug() {
return BuildConfig.DEBUG;
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
return null;
}
}
package com.google.jzhou.dfutest.dfu_service;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import com.google.jzhou.dfutest.BaseActivity;
import com.google.jzhou.dfutest.DfuUpdateActivity;
public class NotificationActivity extends BaseActivity {
@Override
protected void onCreate(@Nullable 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, DfuUpdateActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Bundle bundle = getIntent().getExtras();
if(bundle != null) {
intent.putExtras(bundle); // 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();
}
}
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");
intent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(intent, 1);
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
Uri uri = data.getData();
if (uri == null)
return;
if ("file".equalsIgnoreCase(uri.getScheme())) {//使用第三方应用打开
path = uri.getPath();
} else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) {//4.4以后
path = getPath(this, uri);
} else {//4.4以下下系统调用方法
path = getRealPathFromURI(uri);
}
tv_show.setText(path);
if (requestCode == 1) {
progressBar.setVisibility(View.VISIBLE);
final DfuServiceInitiator starter = new DfuServiceInitiator(dfu_macAddress)
.setDeviceName(mBluetoothService.getName())
.setKeepBond(true);
// If you want to have experimental buttonless DFU feature supported call additionally:
starter.setUnsafeExperimentalButtonlessServiceInSecureDfuEnabled(true);
// but be aware of this: https://devzone.nordicsemi.com/question/100609/sdk-12-bootloader-erased-after-programming/
// and other issues related to this experimental service.
// Init packet is required by Bootloader/DFU from SDK 7.0+ if HEX or BIN file is given above.
// In case of a ZIP file, the init packet (a DAT file) must be included inside the ZIP file.
// if (mFileType == DfuService.TYPE_AUTO)
starter.setZip(uri, path);
// else {
// starter.setBinOrHex(mFileType, mFileStreamUri, mFilePath).setInitFile(mInitFileStreamUri, mInitFilePath);
// }
if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O){
starter.setForeground(false);
starter.setDisableNotification(true);
}
final DfuServiceController controller = starter.start(this, DfuService.class);
// You may use the controller to pause, resume or abort the DFU process.
// DfuServiceInitiator.createDfuNotificationChannel(this);
}
}
}
private final DfuProgressListener dfuProgressListener = new DfuProgressListener() {
@Override
public void onDeviceConnecting(String deviceAddress) {
// progressBar.setIndeterminate(true);
// mTextPercentage.setText(R.string.dfu_status_connecting);
Log.i("TEST", "onDeviceConnecting: " + deviceAddress);
}
@Override
public void onDeviceConnected(String deviceAddress) {
Log.i("TEST", "onDeviceConnected: " + deviceAddress);
}
@Override
public void onDfuProcessStarting(String deviceAddress) {
// progressBar.setIndeterminate(true);
// mTextPercentage.setText(R.string.dfu_status_starting);
Log.i("TEST", "onDfuProcessStarting: " + deviceAddress);
}
@Override
public void onDfuProcessStarted(String deviceAddress) {
Log.i("TEST", "onDfuProcessStarted: " + deviceAddress);
}
@Override
public void onEnablingDfuMode(String deviceAddress) {
Log.i("TEST", "onEnablingDfuMode: " + deviceAddress);
}
@Override
public void onProgressChanged(String deviceAddress, int percent, float speed, float avgSpeed, int currentPart, int partsTotal) {
Log.i("TEST", "onProgressChanged: " + deviceAddress + "百分比" + percent + ",speed "
+ speed + ",avgSpeed " + avgSpeed + ",currentPart " + currentPart
+ ",partTotal " + partsTotal);
tv_show.setText("升级进度:" + percent + "%");
}
@Override
public void onFirmwareValidating(String deviceAddress) {
Log.i("TEST", "onFirmwareValidating: " + deviceAddress);
}
@Override
public void onDeviceDisconnecting(String deviceAddress) {
Log.i("TEST", "onDeviceDisconnecting: " + deviceAddress);
}
@Override
public void onDeviceDisconnected(String deviceAddress) {
Log.i("TEST", "onDeviceDisconnected: " + deviceAddress);
}
@Override
public void onDfuCompleted(String deviceAddress) {
Log.i("TEST", "onDfuCompleted: " + deviceAddress);
// progressBar.setIndeterminate(true);
progressBar.setVisibility(View.GONE);
}
@Override
public void onDfuAborted(String deviceAddress) {
Log.i("TEST", "onDfuAborted: " + deviceAddress);
progressBar.setVisibility(View.GONE);
}
@Override
public void onError(String deviceAddress, int error, int errorType, String message) {
Log.i("TEST", "onError: " + deviceAddress + ",message:" + message);
progressBar.setVisibility(View.GONE);
}
};
@Override
protected void onResume() {
super.onResume();
DfuServiceListenerHelper.registerProgressListener(this, dfuProgressListener);
}
@Override
protected void onPause() {
super.onPause();
DfuServiceListenerHelper.unregisterProgressListener(this, dfuProgressListener);
}
final DfuServiceInitiator starter = new DfuServiceInitiator(dfu_macAddress)
.setDeviceName(mBluetoothService.getName())
.setKeepBond(true);
参数dfu_macAddress:扫描到的蓝牙MAC地址参数mBluetoothService.getName():扫描到的蓝牙设备名称
参数true/false: 是否保持设备绑定
starter.setUnsafeExperimentalButtonlessServiceInSecureDfuEnabled(true);
调用此方法使Nordic nrf52832进入bootloader模式starter.setZip(uri, path);
调用此方法设置升级文件 if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O){
starter.setForeground(false);
starter.setDisableNotification(true);
}
final DfuServiceController controller = starter.start(this, DfuService.class);
调用此方法启动升级服务进行升级
源码下载地址:https://download.csdn.net/download/mygod2008ok/10538088