flutter-nordic-dfu
This library allows you to do a Device Firmware Update (DFU) of your nrf51 or nrf52 chip from Nordic Semiconductor. It works for Android and iOS fine.
This is the implementation of the reference "react-native-nordic-dfu"
For more info about the DFU process, see: Resources
Add your dfu zip file to example/assets/file.zip
Run example project
Scan device
Start dfu
You can pass an absolute file path or asset file to FlutterNordicDfu
Use absolute file path
/// You can define your ProgressListenerListener
await FlutterNordicDfu.startDfu(
'EB:75:AD:E3:CA:CF', '/file/to/zip/path/file.zip',
progressListener: ProgressListenerListener(),
);
class ProgressListenerListener extends DfuProgressListenerAdapter {
@override
void onProgressChanged(String deviceAddress, int percent, double speed,
double avgSpeed, int currentPart, int partsTotal) {
super.onProgressChanged(
deviceAddress, percent, speed, avgSpeed, currentPart, partsTotal);
print('deviceAddress: $deviceAddress, percent: $percent');
}
}
/// Or you can use DefaultDfuProgressListenerAdapter
await FlutterNordicDfu.startDfu(
'EB:75:AD:E3:CA:CF',
'assets/file.zip',
fileInAsset: true,
progressListener:
DefaultDfuProgressListenerAdapter(onProgressChangedHandle: (
deviceAddress,
percent,
speed,
avgSpeed,
currentPart,
partsTotal,
) {
print('deviceAddress: $deviceAddress, percent: $percent');
}),
);
Use asset file path
/// just set [fileInAsset] true
await FlutterNordicDfu.startDfu(
'EB:75:AD:E3:CA:CF', 'assets/file.zip',
progressListener: ProgressListenerListener(),
fileInAsset: true,
);
class ProgressListenerListener extends DfuProgressListenerAdapter {
@override
void onProgressChanged(String deviceAddress, int percent, double speed,
double avgSpeed, int currentPart, int partsTotal) {
super.onProgressChanged(
deviceAddress, percent, speed, avgSpeed, currentPart, partsTotal);
print('deviceAddress: $deviceAddress, percent: $percent');
}
}
Run this command:
With Flutter:
$ flutter pub add flutter_nordic_dfu
This will add a line like this to your package's pubspec.yaml (and run an implicit dart pub get):
dependencies:
flutter_nordic_dfu: ^3.0.0
Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.
Now in your Dart code, you can use:
import 'package:flutter_nordic_dfu/flutter_nordic_dfu.dart';
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_nordic_dfu/flutter_nordic_dfu.dart';
import 'package:flutter_blue/flutter_blue.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final FlutterBlue flutterBlue = FlutterBlue.instance;
StreamSubscription<ScanResult> scanSubscription;
List<ScanResult> scanResults = <ScanResult>[];
bool dfuRunning = false;
int dfuRunningInx;
@override
void initState() {
super.initState();
}
Future<void> doDfu(String deviceId) async {
stopScan();
dfuRunning = true;
try {
var s = await FlutterNordicDfu.startDfu(
deviceId,
'assets/file.zip',
fileInAsset: true,
progressListener:
DefaultDfuProgressListenerAdapter(onProgressChangedHandle: (
deviceAddress,
percent,
speed,
avgSpeed,
currentPart,
partsTotal,
) {
print('deviceAddress: $deviceAddress, percent: $percent');
}),
);
print(s);
dfuRunning = false;
} catch (e) {
dfuRunning = false;
print(e.toString());
}
}
void startScan() async{
scanSubscription?.cancel();
await flutterBlue.stopScan();
setState(() {
scanResults.clear();
scanSubscription = flutterBlue.scan().listen(
(scanResult) {
if (scanResults.firstWhere(
(ele) => ele.device.id == scanResult.device.id,
orElse: () => null) !=
null) {
return;
}
setState(() {
/// add result to results if not added
scanResults.add(scanResult);
});
},
);
});
}
void stopScan() {
scanSubscription?.cancel();
scanSubscription = null;
setState(() => scanSubscription = null);
}
@override
Widget build(BuildContext context) {
final isScanning = scanSubscription != null;
final hasDevice = scanResults.length > 0;
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
actions: <Widget>[
isScanning
? IconButton(
icon: Icon(Icons.pause_circle_filled),
onPressed: dfuRunning ? null : stopScan,
)
: IconButton(
icon: Icon(Icons.play_arrow),
onPressed: dfuRunning ? null : startScan,
)
],
),
body: !hasDevice
? const Center(
child: const Text('No device'),
)
: ListView.separated(
padding: const EdgeInsets.all(8),
itemBuilder: _deviceItemBuilder,
separatorBuilder: (context, index) => const SizedBox(height: 5),
itemCount: scanResults.length,
),
),
);
}
Widget _deviceItemBuilder(BuildContext context, int index) {
var result = scanResults[index];
return DeviceItem(
isRunningItem: (dfuRunningInx == null ? false : dfuRunningInx == index),
scanResult: result,
onPress: dfuRunning
? () async {
await FlutterNordicDfu.abortDfu();
setState(() {
dfuRunningInx = null;
});
}
: () async {
setState(() {
dfuRunningInx = index;
});
await this.doDfu(result.device.id.id);
setState(() {
dfuRunningInx = null;
});
},
);
}
}
class ProgressListenerListener extends DfuProgressListenerAdapter {
@override
void onProgressChanged(String deviceAddress, int percent, double speed,
double avgSpeed, int currentPart, int partsTotal) {
super.onProgressChanged(
deviceAddress, percent, speed, avgSpeed, currentPart, partsTotal);
print('deviceAddress: $deviceAddress, percent: $percent');
}
}
class DeviceItem extends StatelessWidget {
final ScanResult scanResult;
final VoidCallback onPress;
final bool isRunningItem;
DeviceItem({this.scanResult, this.onPress, this.isRunningItem});
@override
Widget build(BuildContext context) {
var name = "Unknow";
if (scanResult.device.name != null && scanResult.device.name.length > 0) {
name = scanResult.device.name;
}
return Card(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: <Widget>[
Icon(Icons.bluetooth),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(name),
Text(scanResult.device.id.id),
Text("RSSI: ${scanResult.rssi}"),
],
),
),
TextButton(
onPressed: onPress,
child: isRunningItem ? Text("Abort Dfu") : Text("Start Dfu"))
],
),
),
);
}
}
Author: fengqiangboy
Official Website:https://github.com/fengqiangboy/flutter-nordic-dfu