diff --git a/android/build.gradle b/android/build.gradle index d3348e4..421c32e 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -35,5 +35,5 @@ android { dependencies { implementation 'androidx.core:core:1.0.2' - implementation 'no.nordicsemi.android:dfu:1.11.0' + implementation 'no.nordicsemi.android:dfu:1.12.0' } diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml index 1b701d5..0ed1e72 100644 --- a/android/src/main/AndroidManifest.xml +++ b/android/src/main/AndroidManifest.xml @@ -1,8 +1,14 @@ - - + + + + + + + + diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index 9dfd902..c0cae45 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -26,7 +26,7 @@ apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { - compileSdkVersion 30 + compileSdkVersion 31 sourceSets { main.java.srcDirs += 'src/main/kotlin' diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index 8d1465a..87bc748 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -6,6 +6,12 @@ to allow setting breakpoints, to provide hot reload, etc. --> + + + + + + if (details.requested.group == 'androidx.core' && !details.requested.name.contains('androidx') ) { - details.useVersion "1.3.0-alpha01" + //details.useVersion "1.3.0-alpha01" + details.useVersion "1.5.0" } } } diff --git a/example/ios/Runner/Info.plist b/example/ios/Runner/Info.plist index 8dfcd33..831e0f5 100644 --- a/example/ios/Runner/Info.plist +++ b/example/ios/Runner/Info.plist @@ -2,6 +2,16 @@ + NSBluetoothAlwaysUsageDescription + Need BLE permission + NSBluetoothPeripheralUsageDescription + Need BLE permission + NSLocationAlwaysAndWhenInUseUsageDescription + Need Location permission + NSLocationAlwaysUsageDescription + Need Location permission + NSLocationWhenInUseUsageDescription + Need Location permission CFBundleDevelopmentRegion en CFBundleExecutable diff --git a/example/lib/generated/i18n.dart b/example/lib/generated/i18n.dart index 30fdb7a..b3e2ae3 100644 --- a/example/lib/generated/i18n.dart +++ b/example/lib/generated/i18n.dart @@ -11,23 +11,22 @@ import 'package:flutter/material.dart'; class S implements WidgetsLocalizations { const S(); - static S current; + static S? current; static const GeneratedLocalizationsDelegate delegate = - GeneratedLocalizationsDelegate(); + GeneratedLocalizationsDelegate(); - static S of(BuildContext context) => Localizations.of(context, S); + static S? of(BuildContext context) => Localizations.of(context, S); @override TextDirection get textDirection => TextDirection.ltr; - } class $en extends S { const $en(); } -class GeneratedLocalizationsDelegate extends LocalizationsDelegate { +class GeneratedLocalizationsDelegate extends LocalizationsDelegate { const GeneratedLocalizationsDelegate(); List get supportedLocales { @@ -36,8 +35,9 @@ class GeneratedLocalizationsDelegate extends LocalizationsDelegate { ]; } - LocaleListResolutionCallback listResolution({Locale fallback, bool withCountry = true}) { - return (List locales, Iterable supported) { + LocaleListResolutionCallback listResolution( + {Locale? fallback, bool withCountry = true}) { + return (List? locales, Iterable supported) { if (locales == null || locales.isEmpty) { return fallback ?? supported.first; } else { @@ -46,26 +46,27 @@ class GeneratedLocalizationsDelegate extends LocalizationsDelegate { }; } - LocaleResolutionCallback resolution({Locale fallback, bool withCountry = true}) { - return (Locale locale, Iterable supported) { + LocaleResolutionCallback resolution( + {Locale? fallback, bool withCountry = true}) { + return (Locale? locale, Iterable supported) { return _resolve(locale, fallback, supported, withCountry); }; } @override - Future load(Locale locale) { - final String lang = getLang(locale); + Future load(Locale locale) { + final String? lang = getLang(locale); if (lang != null) { switch (lang) { case "en": S.current = const $en(); - return SynchronousFuture(S.current); + return SynchronousFuture(S.current); default: - // NO-OP. + // NO-OP. } } S.current = const S(); - return SynchronousFuture(S.current); + return SynchronousFuture(S.current); } @override @@ -77,7 +78,8 @@ class GeneratedLocalizationsDelegate extends LocalizationsDelegate { /// /// Internal method to resolve a locale from a list of locales. /// - Locale _resolve(Locale locale, Locale fallback, Iterable supported, bool withCountry) { + Locale _resolve(Locale? locale, Locale? fallback, Iterable supported, + bool withCountry) { if (locale == null || !_isSupported(locale, withCountry)) { return fallback ?? supported.first; } @@ -110,7 +112,9 @@ class GeneratedLocalizationsDelegate extends LocalizationsDelegate { } // If no country requirement is requested, check if this locale has no country. - if (true != withCountry && (supportedLocale.countryCode == null || supportedLocale.countryCode.isEmpty)) { + if (true != withCountry && + (supportedLocale.countryCode == null || + supportedLocale.countryCode!.isEmpty)) { return true; } } @@ -119,8 +123,11 @@ class GeneratedLocalizationsDelegate extends LocalizationsDelegate { } } -String getLang(Locale l) => l == null - ? null - : l.countryCode != null && l.countryCode.isEmpty - ? l.languageCode - : l.toString(); +String? getLang(Locale l) { + try { + return l.countryCode != null && l.countryCode!.isEmpty + ? l.languageCode + : l.toString(); + } catch (_) {} + return null; +} diff --git a/example/lib/main.dart b/example/lib/main.dart index aad0013..fc08c02 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -1,8 +1,11 @@ import 'dart:async'; +import 'package:collection/collection.dart' show IterableExtension; import 'package:flutter/material.dart'; import 'package:flutter_nordic_dfu/flutter_nordic_dfu.dart'; -import 'package:flutter_blue/flutter_blue.dart'; +import 'package:flutter_blue_plus/flutter_blue_plus.dart'; +import 'package:permission_handler/permission_handler.dart'; +//import 'package:permission_handler:permission_handler.dart'; void main() => runApp(MyApp()); @@ -12,11 +15,11 @@ class MyApp extends StatefulWidget { } class _MyAppState extends State { - final FlutterBlue flutterBlue = FlutterBlue.instance; - StreamSubscription scanSubscription; + final FlutterBluePlus flutterBlue = FlutterBluePlus.instance; + StreamSubscription? scanSubscription; List scanResults = []; bool dfuRunning = false; - int dfuRunningInx; + int? dfuRunningInx; @override void initState() { @@ -43,6 +46,7 @@ class _MyAppState extends State { print('deviceAddress: $deviceAddress, percent: $percent'); }), ); + print("HELLLOOOOOOOOOOOOOOOOOOOOOOOOO"); print(s); dfuRunning = false; } catch (e) { @@ -51,25 +55,30 @@ class _MyAppState extends State { } } - void startScan() async{ + void startScan() async { + var scanStatus = await Permission.bluetoothScan.request().isGranted; + var bluetoothConnectStatus = + await Permission.bluetoothConnect.request().isGranted; + 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); - }); - }, - ); + if (scanStatus && bluetoothConnectStatus) { + scanSubscription = flutterBlue.scan().listen( + (scanResult) { + if (scanResults.firstWhereOrNull( + (ele) => ele.device.id == scanResult.device.id) != + null) { + return; + } + setState(() { + /// add result to results if not added + scanResults.add(scanResult); + }); + }, + ); + } }); } @@ -150,19 +159,19 @@ class ProgressListenerListener extends DfuProgressListenerAdapter { } class DeviceItem extends StatelessWidget { - final ScanResult scanResult; + final ScanResult? scanResult; - final VoidCallback onPress; + final VoidCallback? onPress; - final bool isRunningItem; + 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; + var name = "Unknown"; + if (scanResult!.device.name != null && scanResult!.device.name.length > 0) { + name = scanResult!.device.name; } return Card( child: Padding( @@ -175,14 +184,14 @@ class DeviceItem extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(name), - Text(scanResult.device.id.id), - Text("RSSI: ${scanResult.rssi}"), + Text(scanResult!.device.id.id), + Text("RSSI: ${scanResult!.rssi}"), ], ), ), TextButton( onPressed: onPress, - child: isRunningItem ? Text("Abort Dfu") : Text("Start Dfu")) + child: isRunningItem! ? Text("Abort Dfu") : Text("Start Dfu")) ], ), ), diff --git a/example/pubspec.yaml b/example/pubspec.yaml index ed5c286..f431461 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -3,7 +3,7 @@ description: Demonstrates how to use the flutter_nordic_dfu plugin. publish_to: 'none' environment: - sdk: ">=2.0.0-dev.68.0 <3.0.0" + sdk: '>=2.12.0 <3.0.0' dependencies: flutter: @@ -11,9 +11,10 @@ dependencies: # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.2 - - flutter_blue: ^0.8.0 + cupertino_icons: ^1.0.4 + flutter_blue_plus: ^1.1.2 + collection: ^1.15.0 + permission_handler: ^9.2.0 dev_dependencies: flutter_test: @@ -22,6 +23,8 @@ dev_dependencies: flutter_nordic_dfu: path: ../ + flutter_lints: ^1.0.4 + # For information on the generic Dart part of this file, see the # following page: https://www.dartlang.org/tools/pub/pubspec diff --git a/example/test/widget_test.dart b/example/test/widget_test.dart index 0dbf1cb..e1505f1 100644 --- a/example/test/widget_test.dart +++ b/example/test/widget_test.dart @@ -19,7 +19,7 @@ void main() { expect( find.byWidgetPredicate( (Widget widget) => widget is Text && - widget.data.startsWith('Running on:'), + widget.data!.startsWith('Running on:'), ), findsOneWidget, ); diff --git a/lib/assets/file.zip b/lib/assets/file.zip new file mode 100644 index 0000000..1ac96b9 Binary files /dev/null and b/lib/assets/file.zip differ diff --git a/lib/flutter_nordic_dfu.dart b/lib/flutter_nordic_dfu.dart index d81532a..118d867 100644 --- a/lib/flutter_nordic_dfu.dart +++ b/lib/flutter_nordic_dfu.dart @@ -100,16 +100,18 @@ class FlutterNordicDfu { const AndroidSpecialParameter(), IosSpecialParameter iosSpecialParameter = const IosSpecialParameter(), }) async { - + print("calling method"); _channel.setMethodCallHandler((MethodCall call) async { switch (call.method) { case "onDeviceConnected": + print("calling method: onDeviceConnected"); progressListener?.onDeviceConnected(call.arguments); break; case "onDeviceConnecting": progressListener?.onDeviceConnecting(call.arguments); break; case "onDeviceDisconnected": + print("calling method: onDeviceDisconnected"); progressListener?.onDeviceDisconnected(call.arguments); break; case "onDeviceDisconnecting": @@ -119,9 +121,11 @@ class FlutterNordicDfu { progressListener?.onDfuAborted(call.arguments); break; case "onDfuCompleted": + print("calling method: onDfuCompleted"); progressListener?.onDfuCompleted(call.arguments); break; case "onDfuProcessStarted": + print("calling method: onDfuProcessStarted"); progressListener?.onDfuProcessStarted(call.arguments); break; case "onDfuProcessStarting":