From 0de81ff7d2059b248bff5837c4dd2348eab65cca Mon Sep 17 00:00:00 2001 From: suvaissov Date: Wed, 5 May 2021 13:37:11 +0600 Subject: [PATCH 1/3] uses permission access --- android/app/src/main/AndroidManifest.xml | 8 ++++++++ lib/views/settings/setting_printer_view.dart | 7 +++++++ 2 files changed, 15 insertions(+) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 0483e66..b03e72b 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -9,6 +9,14 @@ + + + + + + + + { NavigatorService _navigatorService = locator(); final DialogService _dialogService = locator(); PrinterBluetoothManager printerManager = PrinterBluetoothManager(); + final Logger log = getLogger('SettingPrinterView'); @override @@ -48,6 +51,10 @@ class _SettingPrinterViewState extends State { chunkSizeBytes = 75; queueSleepTimeMs = 10; } + + log.i(chunkSizeBytes); + log.i(queueSleepTimeMs); + // TODO Don't forget to choose printer's paper PaperSize paper = state.printerPaperSize == SettingPrinterPaperM80 ? PaperSize.mm80 : PaperSize.mm58; if(SettingPrinterEncodingImage == state.printerEncoding) { From f45835d215e79ad7ddafa222c06090851acb6351 Mon Sep 17 00:00:00 2001 From: suvaissov Date: Wed, 19 May 2021 12:11:39 +0600 Subject: [PATCH 2/3] printer android fix --- android/app/src/main/AndroidManifest.xml | 7 +- lib/shared/shared_styles.dart | 2 + lib/views/check/image_show_container.dart | 36 +++++- lib/views/settings/printer/PrinterTest.dart | 20 ++- lib/views/settings/setting_printer_view.dart | 129 ++++++++++++++----- lib/widgets/fields/busy_button.dart | 2 +- lib/widgets/fields/busy_button_icon.dart | 2 +- pubspec.lock | 14 ++ pubspec.yaml | 1 + 9 files changed, 159 insertions(+), 54 deletions(-) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index b03e72b..8277d0d 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -13,9 +13,10 @@ - - - + + + + { final PrinterBluetoothManager printerManager = PrinterBluetoothManager(); final DialogService _dialogService = locator(); final BluetoothDevice printerBtDevice = Redux.store.state.settingState.printerBT; + final BluetoothManager bluetoothManager = BluetoothManager.instance; bool _printing = false; + void _preparePrint() async { + if (Platform.isIOS) { + await _print(); + } else { + bluetoothManager.state.listen((val) { + print("state = $val"); + if (!mounted) return; + if (val == 12) { + print('on'); + _print(); + + } else if (val == 10) { + print('off'); + _dialogService.showDialog( + description: 'Отсутвует соеденение Bluetooth или он отключен' , title: 'Bluetooth'); + } + print('state is $val'); + }); + } + } + void _print() async { final SettingState state = Redux.store.state.settingState; if(state.printerBT == null) { @@ -47,7 +69,7 @@ class _ImageShowContainerState extends State { bool isIos = Platform.isIOS; int chunkSizeBytes = 3096; - int queueSleepTimeMs = 50; + int queueSleepTimeMs = 100; if(isIos){ chunkSizeBytes = 75; @@ -81,11 +103,13 @@ class _ImageShowContainerState extends State { _dialogService.showDialog(description: res.msg); } } - } finally { - setState(() { - _printing = false; - }); + } catch (e) { + print(e); } + await Future.delayed(Duration(seconds: 7)); + setState(() { + _printing = false; + }); } @override @@ -110,7 +134,7 @@ class _ImageShowContainerState extends State { ), ) else - IconButton(icon: Icon(Icons.print), onPressed: _print) + IconButton(icon: Icon(Icons.print), onPressed: _preparePrint) ], ), body: ListView( diff --git a/lib/views/settings/printer/PrinterTest.dart b/lib/views/settings/printer/PrinterTest.dart index e9e646b..3dbaba7 100644 --- a/lib/views/settings/printer/PrinterTest.dart +++ b/lib/views/settings/printer/PrinterTest.dart @@ -117,13 +117,13 @@ Future testTicketImage(PaperSize paper) async { // Print image final ByteData byteData = await rootBundle.load('assets/images/check.png'); final Uint8List bytes = byteData.buffer.asUint8List(); - final Im.Image imagea = Im.decodeImage(bytes); + final Im.Image image = Im.decodeImage(bytes); // Using `ESC *` //ticket.image(imagea); // Using `GS v 0` (obsolete) //ticket.imageRaster(imagea); // Using `GS ( L` - ticket.imageRaster(imagea, imageFn: PosImageFn.bitImageRaster); + ticket.imageRaster(image, imageFn: PosImageFn.bitImageRaster); //ticket.image(imagea); @@ -137,8 +137,8 @@ Future printImageCheck(PaperSize paper, String base64Src) async { final Ticket ticket = Ticket(paper); final Uint8List bytes = base64Decode(base64Src); final Im.Image image = Im.decodeImage(bytes); - //ticket.imageRaster(image, imageFn: PosImageFn.bitImageRaster); - ticket.image(image); + ticket.imageRaster(image, imageFn: PosImageFn.bitImageRaster); + //ticket.image(image); ticket.feed(2); ticket.cut(); return ticket; @@ -209,17 +209,15 @@ Future printTextCheck(PaperSize paper, String encoding, var data ) async const double qrSize = 200; try { final uiImg = await QrPainter( - data: qr, version: QrVersions.auto, gapless: true, ).toImageData(qrSize); - final dir = await getTemporaryDirectory(); - final pathName = '${dir.path}/qr_tmp.png'; - final qrFile = File(pathName); - final imgFile = await qrFile.writeAsBytes(uiImg.buffer.asUint8List()); - final img = Im.decodePng(imgFile.readAsBytesSync()); - + //final dir = await getTemporaryDirectory(); + //final pathName = '${dir.path}/qr_tmp.png'; + //final qrFile = File(pathName); + //final imgFile = await qrFile.writeAsBytes(uiImg.buffer.asUint8List()); + final img = Im.decodePng(uiImg.buffer.asUint8List()); ticket.image(img); //ticket.qrcode(qr, size: QRSize.Size1 ); diff --git a/lib/views/settings/setting_printer_view.dart b/lib/views/settings/setting_printer_view.dart index 0daa2d1..ddab91c 100644 --- a/lib/views/settings/setting_printer_view.dart +++ b/lib/views/settings/setting_printer_view.dart @@ -1,6 +1,8 @@ import 'dart:io'; import 'dart:typed_data'; +import 'package:aman_kassa_flutter/widgets/fields/busy_button_icon.dart'; +import 'package:flutter_bluetooth_basic/flutter_bluetooth_basic.dart'; import 'package:aman_kassa_flutter/core/locator.dart'; import 'package:aman_kassa_flutter/core/logger.dart'; import 'package:aman_kassa_flutter/core/route_names.dart'; @@ -14,6 +16,7 @@ import 'package:aman_kassa_flutter/widgets/fields/aman_icon_button_horizontal.da import 'package:esc_pos_bluetooth/esc_pos_bluetooth.dart'; import 'package:esc_pos_utils/esc_pos_utils.dart'; import 'package:flutter/material.dart'; +import 'package:permission_handler/permission_handler.dart'; import 'package:aman_kassa_flutter/views/settings/printer/PrinterTest.dart'; import 'package:flutter_redux/flutter_redux.dart'; import 'package:logger/logger.dart'; @@ -30,48 +33,67 @@ class SettingPrinterView extends StatefulWidget { class _SettingPrinterViewState extends State { NavigatorService _navigatorService = locator(); final DialogService _dialogService = locator(); - PrinterBluetoothManager printerManager = PrinterBluetoothManager(); + final PrinterBluetoothManager printerManager = PrinterBluetoothManager(); + final BluetoothManager bluetoothManager = BluetoothManager.instance; final Logger log = getLogger('SettingPrinterView'); + bool _printing = false; @override void initState() { super.initState(); + _permission(); + } void _testPrint() async { - final SettingState state = Redux.store.state.settingState; - printerManager.selectPrinter(PrinterBluetooth(state.printerBT)); - bool isIos = Platform.isIOS; - int chunkSizeBytes = 3096; - int queueSleepTimeMs = 50; + setState(() { + _printing = true; + }); + try { + final SettingState state = Redux.store.state.settingState; + printerManager.selectPrinter(PrinterBluetooth(state.printerBT)); + bool isIos = Platform.isIOS; + int chunkSizeBytes = 3096; + int queueSleepTimeMs = 100; - if(isIos) { - chunkSizeBytes = 75; - queueSleepTimeMs = 10; + if (isIos) { + chunkSizeBytes = 75; + queueSleepTimeMs = 10; + } + + log.i(chunkSizeBytes); + log.i(queueSleepTimeMs); + + // TODO Don't forget to choose printer's paper + PaperSize paper = state.printerPaperSize == SettingPrinterPaperM80 ? PaperSize.mm80 : PaperSize.mm58; + if (SettingPrinterEncodingImage == state.printerEncoding) { + final PosPrintResult res = await printerManager.printTicket( + await testTicketImage(paper), + chunkSizeBytes: chunkSizeBytes, + queueSleepTimeMs: queueSleepTimeMs + ); + _dialogService.showDialog(description: res.msg); + } else { + final PosPrintResult res = await printerManager.printTicket( + await printTextCheck(paper, state.printerEncoding, exampleJson['check_text']), + chunkSizeBytes: chunkSizeBytes, + queueSleepTimeMs: queueSleepTimeMs + ); + _dialogService.showDialog(description: res.msg); + } + } catch (e) { + print('ERROR'); + print(e); } - log.i(chunkSizeBytes); - log.i(queueSleepTimeMs); + //7 sec safe disconnect + await Future.delayed(Duration(seconds: 7)); - // TODO Don't forget to choose printer's paper - PaperSize paper = state.printerPaperSize == SettingPrinterPaperM80 ? PaperSize.mm80 : PaperSize.mm58; - if(SettingPrinterEncodingImage == state.printerEncoding) { - final PosPrintResult res = await printerManager.printTicket( - await testTicketImage(paper), - chunkSizeBytes: chunkSizeBytes, - queueSleepTimeMs: queueSleepTimeMs - ); - _dialogService.showDialog(description: res.msg); - } else { - final PosPrintResult res = await printerManager.printTicket( - await printTextCheck(paper, state.printerEncoding, exampleJson['check_text']), - chunkSizeBytes: chunkSizeBytes, - queueSleepTimeMs: queueSleepTimeMs - ); - _dialogService.showDialog(description: res.msg); - } + setState(() { + _printing = false; + }); } @@ -115,13 +137,15 @@ class _SettingPrinterViewState extends State { child: Column( mainAxisAlignment: MainAxisAlignment.end, children: [ - AmanIconButtonHorizontal( + BusyButtonIcon( icon: Icons.local_printshop_outlined, title: 'Напечатать тестовую страницу', - activeColor: primaryColor, - selected: vm.printerBT != null, + busy: _printing, + enabled: vm.printerBT != null, onPressed: () { - _testPrint(); + + _startInitialPrint(); + }, ), ], @@ -134,4 +158,45 @@ class _SettingPrinterViewState extends State { ), ); } + + //Метод для получения постоянного доступа к местополения + //только для Android + void _permission() async { + if( Platform.isAndroid) { + var status = await Permission.locationAlways.status; + if (status.isUndetermined || status.isDenied || status.isPermanentlyDenied) { + if (await Permission.locationAlways + .request() + .isGranted) { + print('Granted'); + } else { + _dialogService.showDialog( + description: 'Необходимо указать постоянный доступ к местоположении для поиска принтера'); + } + } + } + } + + void _startInitialPrint() async { + + + if (Platform.isIOS) { + await _testPrint(); + } else { + bluetoothManager.state.listen((val) { + print("state = $val"); + if (!mounted) return; + if (val == 12) { + print('on'); + _testPrint(); + + } else if (val == 10) { + print('off'); + _dialogService.showDialog( + description: 'Отсутвует соеденение Bluetooth или он отключен' , title: 'Bluetooth'); + } + print('state is $val'); + }); + } + } } diff --git a/lib/widgets/fields/busy_button.dart b/lib/widgets/fields/busy_button.dart index d3c879a..5e5c7d4 100644 --- a/lib/widgets/fields/busy_button.dart +++ b/lib/widgets/fields/busy_button.dart @@ -52,7 +52,7 @@ class _BusyButtonState extends State { ? AutoSizeText( widget.title, textAlign: TextAlign.center, - style: buttonTitleTextStyle, + style: widget.enabled ? buttonTitleTextStyle : buttonTitleDisableTextStyle, minFontSize: 2, maxLines: 1, ) diff --git a/lib/widgets/fields/busy_button_icon.dart b/lib/widgets/fields/busy_button_icon.dart index fcd413c..6365f2e 100644 --- a/lib/widgets/fields/busy_button_icon.dart +++ b/lib/widgets/fields/busy_button_icon.dart @@ -68,7 +68,7 @@ class _BusyButtonIconState extends State { Text( widget.title, textAlign: TextAlign.center, - style: buttonTitleTextStyle, + style: widget.enabled ? buttonTitleTextStyle : buttonTitleDisableTextStyle, maxLines: 1, ), ], diff --git a/pubspec.lock b/pubspec.lock index f5cbfd4..3f8ceb6 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -401,6 +401,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.9.2" + permission_handler: + dependency: "direct main" + description: + name: permission_handler + url: "https://pub.dartlang.org" + source: hosted + version: "5.1.0+2" + permission_handler_platform_interface: + dependency: transitive + description: + name: permission_handler_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.2" petitparser: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index cbfa26c..33b5cd2 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -37,6 +37,7 @@ dependencies: esc_pos_bluetooth: ^0.2.8 esc_pos_utils: ^0.3.6 # no edit for esc_pos_bluetooth: ^0.2.8 charset_converter: ^1.0.3 + permission_handler: ^5.0.1+2 dev_dependencies: flutter_test: sdk: flutter From 760fc63da02e013193a3f8b799c607f4b71bafaa Mon Sep 17 00:00:00 2001 From: suvaissov Date: Wed, 26 May 2021 12:21:45 +0600 Subject: [PATCH 3/3] confirm on location permissions --- lib/views/settings/setting_printer_view.dart | 25 +++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/lib/views/settings/setting_printer_view.dart b/lib/views/settings/setting_printer_view.dart index ddab91c..a94b72f 100644 --- a/lib/views/settings/setting_printer_view.dart +++ b/lib/views/settings/setting_printer_view.dart @@ -1,6 +1,7 @@ import 'dart:io'; import 'dart:typed_data'; +import 'package:aman_kassa_flutter/core/models/dialog_models.dart'; import 'package:aman_kassa_flutter/widgets/fields/busy_button_icon.dart'; import 'package:flutter_bluetooth_basic/flutter_bluetooth_basic.dart'; import 'package:aman_kassa_flutter/core/locator.dart'; @@ -164,14 +165,26 @@ class _SettingPrinterViewState extends State { void _permission() async { if( Platform.isAndroid) { var status = await Permission.locationAlways.status; + log.i(status); if (status.isUndetermined || status.isDenied || status.isPermanentlyDenied) { - if (await Permission.locationAlways - .request() - .isGranted) { - print('Granted'); + DialogResponse response = await _dialogService.showConfirmationDialog( + title: 'Доступ', + description: 'Для поиска устройств Bluetooth необходимо предоставить доступ к отслеживанию геолокации.', + cancelTitle: 'Нет', + confirmationTitle: 'Хорошо', + ); + if (response.confirmed) { + if (await Permission.locationAlways + .request() + .isGranted) { + print('Granted'); + } else { + _dialogService.showDialog( + description: 'Необходимо указать постоянный доступ к местоположении для поиска принтера'); + _navigatorService.pop(); + } } else { - _dialogService.showDialog( - description: 'Необходимо указать постоянный доступ к местоположении для поиска принтера'); + _navigatorService.pop(); } } }