From 16ea7ead942efa309ce76e7e546e5608d7b0408d Mon Sep 17 00:00:00 2001 From: error500 Date: Tue, 1 Feb 2022 13:22:39 +0600 Subject: [PATCH] flutter_blue added for ios --- lib/core/services/blue_print_service.dart | 135 +++++++++++++++---- lib/views/settings/setting_printer_view.dart | 8 +- pubspec.lock | 16 ++- pubspec.yaml | 1 + 4 files changed, 132 insertions(+), 28 deletions(-) diff --git a/lib/core/services/blue_print_service.dart b/lib/core/services/blue_print_service.dart index b409b3a..a9c712e 100644 --- a/lib/core/services/blue_print_service.dart +++ b/lib/core/services/blue_print_service.dart @@ -1,43 +1,106 @@ +import 'dart:io'; import 'dart:typed_data'; import 'package:aman_kassa_flutter/core/base/base_service.dart'; import 'package:bluetooth_print/bluetooth_print.dart'; import 'package:bluetooth_print/bluetooth_print_model.dart'; - - +import 'package:flutter_blue/flutter_blue.dart' as flutter_blue; +import 'package:flutter_blue/gen/flutterblue.pb.dart' as proto; class BluePrintService extends BaseService { - BluetoothPrint _bluetooth = BluetoothPrint.instance; + final BluetoothPrint _bluetoothAndr = BluetoothPrint.instance; + flutter_blue.BluetoothDevice? _bluetoothDeviceIOS; + final flutter_blue.FlutterBlue _bluetoothIOS = + flutter_blue.FlutterBlue.instance; + + final bool isAndroid = Platform.isAndroid; + final bool isIos = Platform.isIOS; + // final bool isAndroid = false; + // final bool isIos = true; + BluetoothDevice? _device; Future scan() async { - await _bluetooth.startScan(timeout: Duration(seconds: 4)); + if (isAndroid) { + await _bluetoothAndr.startScan(timeout: Duration(seconds: 4)); + } else if (isIos) { + await _bluetoothIOS.startScan(timeout: const Duration(seconds: 5)); + } } Future stopScan() async { - await _bluetooth.stopScan(); + if (isAndroid) { + await _bluetoothAndr.stopScan(); + } else if (isIos) { + await _bluetoothIOS.stopScan(); + } } - Stream> get scanResult => _bluetooth.scanResults; + Stream> get scanResult { + if (isAndroid) + return _bluetoothAndr.scanResults; + else + return _bluetoothIOS.scanResults.asyncMap>( + (event) => + Future.wait(event.toList().map((e) async => BluetoothDevice() + ..name = e.device.name + ..type = e.device.type.index + ..address = e.device.id.id))); + } + Stream get isScanning => + isAndroid ? _bluetoothAndr.isScanning : _bluetoothIOS.isScanning; + + Stream get state => isAndroid + ? _bluetoothAndr.state + : _bluetoothIOS.state.asyncMap((event) => event.index); - Stream get isScanning => _bluetooth.isScanning; - Stream get state => _bluetooth.state; set device(BluetoothDevice device) => _device = device; - Future connect() async { bool response = false; if (_device == null) { response = false; } else { + // try { + // await _bluetoothAndr.connect(_device!); + // await Future.delayed(Duration(seconds: 5)); + // response = true; + // } catch (e) { + // print('Error connect $e'); + // response = false; + // } + try { - await _bluetooth.connect(_device!); - await Future.delayed(Duration(seconds: 5)); + if (isAndroid) { + await _bluetoothAndr.connect(_device!); + } else if (isIos) { + _bluetoothDeviceIOS = flutter_blue.BluetoothDevice.fromProto( + proto.BluetoothDevice( + name: _device?.name ?? '', + remoteId: _device?.address ?? '', + type: proto.BluetoothDevice_Type.valueOf(_device?.type ?? 0), + ), + ); + final List connectedDevices = + await _bluetoothIOS.connectedDevices; + final int deviceConnectedIndex = connectedDevices + .indexWhere((flutter_blue.BluetoothDevice bluetoothDevice) { + return bluetoothDevice.id == _bluetoothDeviceIOS?.id; + }); + if (deviceConnectedIndex < 0) { + await _bluetoothDeviceIOS?.connect(); + } + } + response = true; - } catch (e) { - print('Error connect $e'); + _device?.connected = true; + return Future.value(response); + } on Exception catch (error) { + print('$runtimeType - Error $error'); response = false; + _device?.connected = false; + return Future.value(response); } } return response; @@ -46,7 +109,11 @@ class BluePrintService extends BaseService { Future disconnect() async { bool response = false; try { - await _bluetooth.disconnect(); + if (isAndroid) { + await _bluetoothAndr.disconnect(); + } else if (isIos) { + await _bluetoothDeviceIOS?.disconnect(); + } response = true; } catch (e) { print('Error $e'); @@ -55,21 +122,37 @@ class BluePrintService extends BaseService { return response; } - Future printBytes(Uint8List bytes, { int chunkSizeBytes = 20, int queueSleepTimeMs = 20 }) async { - Map config = Map(); - final len = bytes.length; - List> chunks = []; - for (var i = 0; i < len; i += chunkSizeBytes) { - var end = (i + chunkSizeBytes < len) ? i + chunkSizeBytes : len; - chunks.add(bytes.sublist(i, end)); - } + Future printBytes(Uint8List bytes, + {int chunkSizeBytes = 20, int queueSleepTimeMs = 20}) async { + if (isAndroid) { + Map config = Map(); + final len = bytes.length; + List> chunks = []; + for (var i = 0; i < len; i += chunkSizeBytes) { + var end = (i + chunkSizeBytes < len) ? i + chunkSizeBytes : len; + chunks.add(bytes.sublist(i, end)); + } - for (var i = 0; i < chunks.length; i += 1) { - await _bluetooth.rawBytes(config, chunks[i]); - await Future.delayed(Duration(milliseconds: queueSleepTimeMs)); + for (var i = 0; i < chunks.length; i += 1) { + await _bluetoothAndr.rawBytes(config, chunks[i]); + await Future.delayed(Duration(milliseconds: queueSleepTimeMs)); + } + } else if (isIos) { + final List bluetoothServices = + await _bluetoothDeviceIOS?.discoverServices() ?? + []; + final flutter_blue.BluetoothService bluetoothService = + bluetoothServices.firstWhere( + (flutter_blue.BluetoothService service) => service.isPrimary, + ); + final flutter_blue.BluetoothCharacteristic characteristic = + bluetoothService.characteristics.firstWhere( + (flutter_blue.BluetoothCharacteristic bluetoothCharacteristic) => + bluetoothCharacteristic.properties.write, + ); + await characteristic.write(bytes, withoutResponse: true); } - return true; } } diff --git a/lib/views/settings/setting_printer_view.dart b/lib/views/settings/setting_printer_view.dart index 0b33dc3..2316462 100644 --- a/lib/views/settings/setting_printer_view.dart +++ b/lib/views/settings/setting_printer_view.dart @@ -49,7 +49,13 @@ class _SettingPrinterViewState extends State { try { final SettingState state = Redux.store!.state.settingState!; printerManager.device = state.printerBT!; - await printerManager.connect(); + bool isConnected = await printerManager.connect(); + if(isConnected == false) { + await Future.delayed(Duration(seconds: 3)); + await printerManager.disconnect(); + return; + } + await Future.delayed(Duration(seconds: 3)); bool isIos = Platform.isIOS; int chunkSizeBytes = 3096; int queueSleepTimeMs = 100; diff --git a/pubspec.lock b/pubspec.lock index 7bf0b18..74dc448 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -78,6 +78,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.15.0" + convert: + dependency: transitive + description: + name: convert + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.1" crypto: dependency: transitive description: @@ -160,6 +167,13 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_blue: + dependency: "direct main" + description: + name: flutter_blue + url: "https://pub.dartlang.org" + source: hosted + version: "0.8.0" flutter_lock_screen: dependency: "direct main" description: @@ -491,7 +505,7 @@ packages: name: rxdart url: "https://pub.dartlang.org" source: hosted - version: "0.27.3" + version: "0.26.0" shared_preferences: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 08515ac..3053480 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -40,6 +40,7 @@ dependencies: permission_handler: ^8.3.0 bluetooth_print: path: ../bluetooth_print + flutter_blue: ^0.8.0 dev_dependencies: flutter_test: sdk: flutter