Merge branch 'master' into backend_nfc

# Conflicts:
#	pubspec.yaml
backend_nfc
suvaissov 2021-05-26 12:41:59 +06:00
commit 27d0d6d11d
9 changed files with 182 additions and 49 deletions

View File

@ -12,6 +12,15 @@
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
<application <application
tools:replace="android:label" tools:replace="android:label"

View File

@ -24,6 +24,8 @@ const TextStyle productTextStyle = const TextStyle(
fontWeight: FontWeight.w400, color: Colors.black, fontSize: 15); fontWeight: FontWeight.w400, color: Colors.black, fontSize: 15);
const TextStyle buttonTitleTextStyle = const TextStyle( const TextStyle buttonTitleTextStyle = const TextStyle(
fontWeight: FontWeight.w700, color: whiteColor, fontSize: 14); fontWeight: FontWeight.w700, color: whiteColor, fontSize: 14);
const TextStyle buttonTitleDisableTextStyle = const TextStyle(
fontWeight: FontWeight.w700, color: fillColor, fontSize: 14);
const TextStyle buttonBigTitleTextStyle = const TextStyle( const TextStyle buttonBigTitleTextStyle = const TextStyle(
fontWeight: FontWeight.w700, fontWeight: FontWeight.w700,
color: whiteColor, color: whiteColor,

View File

@ -49,9 +49,31 @@ class _ImageShowContainerState extends State<ImageShowContainer> {
final DialogService _dialogService = locator<DialogService>(); final DialogService _dialogService = locator<DialogService>();
final BluetoothDevice printerBtDevice = Redux.store.state.settingState.printerBT; final BluetoothDevice printerBtDevice = Redux.store.state.settingState.printerBT;
final BluetoothManager bluetoothManager = BluetoothManager.instance;
bool _printing = false; 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 { void _print() async {
final SettingState state = Redux.store.state.settingState; final SettingState state = Redux.store.state.settingState;
if(state.printerBT == null) { if(state.printerBT == null) {
@ -61,7 +83,7 @@ class _ImageShowContainerState extends State<ImageShowContainer> {
bool isIos = Platform.isIOS; bool isIos = Platform.isIOS;
int chunkSizeBytes = 3096; int chunkSizeBytes = 3096;
int queueSleepTimeMs = 50; int queueSleepTimeMs = 100;
if(isIos){ if(isIos){
chunkSizeBytes = 75; chunkSizeBytes = 75;
@ -95,12 +117,14 @@ class _ImageShowContainerState extends State<ImageShowContainer> {
_dialogService.showDialog(description: res.msg); _dialogService.showDialog(description: res.msg);
} }
} }
} finally { } catch (e) {
print(e);
}
await Future.delayed(Duration(seconds: 7));
setState(() { setState(() {
_printing = false; _printing = false;
}); });
} }
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -124,7 +148,7 @@ class _ImageShowContainerState extends State<ImageShowContainer> {
), ),
) )
else else
IconButton(icon: Icon(Icons.print), onPressed: _print) IconButton(icon: Icon(Icons.print), onPressed: _preparePrint)
], ],
), ),
body: ListView( body: ListView(

View File

@ -117,13 +117,13 @@ Future<Ticket> testTicketImage(PaperSize paper) async {
// Print image // Print image
final ByteData byteData = await rootBundle.load('assets/images/check.png'); final ByteData byteData = await rootBundle.load('assets/images/check.png');
final Uint8List bytes = byteData.buffer.asUint8List(); final Uint8List bytes = byteData.buffer.asUint8List();
final Im.Image imagea = Im.decodeImage(bytes); final Im.Image image = Im.decodeImage(bytes);
// Using `ESC *` // Using `ESC *`
//ticket.image(imagea); //ticket.image(imagea);
// Using `GS v 0` (obsolete) // Using `GS v 0` (obsolete)
//ticket.imageRaster(imagea); //ticket.imageRaster(imagea);
// Using `GS ( L` // Using `GS ( L`
ticket.imageRaster(imagea, imageFn: PosImageFn.bitImageRaster); ticket.imageRaster(image, imageFn: PosImageFn.bitImageRaster);
//ticket.image(imagea); //ticket.image(imagea);
@ -137,8 +137,8 @@ Future<Ticket> printImageCheck(PaperSize paper, String base64Src) async {
final Ticket ticket = Ticket(paper); final Ticket ticket = Ticket(paper);
final Uint8List bytes = base64Decode(base64Src); final Uint8List bytes = base64Decode(base64Src);
final Im.Image image = Im.decodeImage(bytes); final Im.Image image = Im.decodeImage(bytes);
//ticket.imageRaster(image, imageFn: PosImageFn.bitImageRaster); ticket.imageRaster(image, imageFn: PosImageFn.bitImageRaster);
ticket.image(image); //ticket.image(image);
ticket.feed(2); ticket.feed(2);
ticket.cut(); ticket.cut();
return ticket; return ticket;
@ -209,17 +209,15 @@ Future<Ticket> printTextCheck(PaperSize paper, String encoding, var data ) async
const double qrSize = 200; const double qrSize = 200;
try { try {
final uiImg = await QrPainter( final uiImg = await QrPainter(
data: qr, data: qr,
version: QrVersions.auto, version: QrVersions.auto,
gapless: true, gapless: true,
).toImageData(qrSize); ).toImageData(qrSize);
final dir = await getTemporaryDirectory(); //final dir = await getTemporaryDirectory();
final pathName = '${dir.path}/qr_tmp.png'; //final pathName = '${dir.path}/qr_tmp.png';
final qrFile = File(pathName); //final qrFile = File(pathName);
final imgFile = await qrFile.writeAsBytes(uiImg.buffer.asUint8List()); //final imgFile = await qrFile.writeAsBytes(uiImg.buffer.asUint8List());
final img = Im.decodePng(imgFile.readAsBytesSync()); final img = Im.decodePng(uiImg.buffer.asUint8List());
ticket.image(img); ticket.image(img);
//ticket.qrcode(qr, size: QRSize.Size1 ); //ticket.qrcode(qr, size: QRSize.Size1 );

View File

@ -1,7 +1,11 @@
import 'dart:io'; import 'dart:io';
import 'dart:typed_data'; 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'; 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'; import 'package:aman_kassa_flutter/core/route_names.dart';
import 'package:aman_kassa_flutter/core/services/dialog_service.dart'; import 'package:aman_kassa_flutter/core/services/dialog_service.dart';
import 'package:aman_kassa_flutter/core/services/navigator_service.dart'; import 'package:aman_kassa_flutter/core/services/navigator_service.dart';
@ -13,8 +17,10 @@ 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_bluetooth/esc_pos_bluetooth.dart';
import 'package:esc_pos_utils/esc_pos_utils.dart'; import 'package:esc_pos_utils/esc_pos_utils.dart';
import 'package:flutter/material.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:aman_kassa_flutter/views/settings/printer/PrinterTest.dart';
import 'package:flutter_redux/flutter_redux.dart'; import 'package:flutter_redux/flutter_redux.dart';
import 'package:logger/logger.dart';
import 'component/setting_item.dart'; import 'component/setting_item.dart';
import './printer/data/settings_envi.dart'; import './printer/data/settings_envi.dart';
@ -28,29 +34,42 @@ class SettingPrinterView extends StatefulWidget {
class _SettingPrinterViewState extends State<SettingPrinterView> { class _SettingPrinterViewState extends State<SettingPrinterView> {
NavigatorService _navigatorService = locator<NavigatorService>(); NavigatorService _navigatorService = locator<NavigatorService>();
final DialogService _dialogService = locator<DialogService>(); final DialogService _dialogService = locator<DialogService>();
PrinterBluetoothManager printerManager = PrinterBluetoothManager(); final PrinterBluetoothManager printerManager = PrinterBluetoothManager();
final BluetoothManager bluetoothManager = BluetoothManager.instance;
final Logger log = getLogger('SettingPrinterView');
bool _printing = false;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_permission();
} }
void _testPrint() async { void _testPrint() async {
setState(() {
_printing = true;
});
try {
final SettingState state = Redux.store.state.settingState; final SettingState state = Redux.store.state.settingState;
printerManager.selectPrinter(PrinterBluetooth(state.printerBT)); printerManager.selectPrinter(PrinterBluetooth(state.printerBT));
bool isIos = Platform.isIOS; bool isIos = Platform.isIOS;
int chunkSizeBytes = 3096; int chunkSizeBytes = 3096;
int queueSleepTimeMs = 50; int queueSleepTimeMs = 100;
if(isIos) { if (isIos) {
chunkSizeBytes = 75; chunkSizeBytes = 75;
queueSleepTimeMs = 10; queueSleepTimeMs = 10;
} }
log.i(chunkSizeBytes);
log.i(queueSleepTimeMs);
// TODO Don't forget to choose printer's paper // TODO Don't forget to choose printer's paper
PaperSize paper = state.printerPaperSize == SettingPrinterPaperM80 ? PaperSize.mm80 : PaperSize.mm58; PaperSize paper = state.printerPaperSize == SettingPrinterPaperM80 ? PaperSize.mm80 : PaperSize.mm58;
if(SettingPrinterEncodingImage == state.printerEncoding) { if (SettingPrinterEncodingImage == state.printerEncoding) {
final PosPrintResult res = await printerManager.printTicket( final PosPrintResult res = await printerManager.printTicket(
await testTicketImage(paper), await testTicketImage(paper),
chunkSizeBytes: chunkSizeBytes, chunkSizeBytes: chunkSizeBytes,
@ -65,6 +84,17 @@ class _SettingPrinterViewState extends State<SettingPrinterView> {
); );
_dialogService.showDialog(description: res.msg); _dialogService.showDialog(description: res.msg);
} }
} catch (e) {
print('ERROR');
print(e);
}
//7 sec safe disconnect
await Future.delayed(Duration(seconds: 7));
setState(() {
_printing = false;
});
} }
@ -108,13 +138,15 @@ class _SettingPrinterViewState extends State<SettingPrinterView> {
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.end,
children: [ children: [
AmanIconButtonHorizontal( BusyButtonIcon(
icon: Icons.local_printshop_outlined, icon: Icons.local_printshop_outlined,
title: 'Напечатать тестовую страницу', title: 'Напечатать тестовую страницу',
activeColor: primaryColor, busy: _printing,
selected: vm.printerBT != null, enabled: vm.printerBT != null,
onPressed: () { onPressed: () {
_testPrint();
_startInitialPrint();
}, },
), ),
], ],
@ -127,4 +159,57 @@ class _SettingPrinterViewState extends State<SettingPrinterView> {
), ),
); );
} }
//Метод для получения постоянного доступа к местополения
//только для Android
void _permission() async {
if( Platform.isAndroid) {
var status = await Permission.locationAlways.status;
log.i(status);
if (status.isUndetermined || status.isDenied || status.isPermanentlyDenied) {
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 {
_navigatorService.pop();
}
}
}
}
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');
});
}
}
} }

View File

@ -52,7 +52,7 @@ class _BusyButtonState extends State<BusyButton> {
? AutoSizeText( ? AutoSizeText(
widget.title, widget.title,
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: buttonTitleTextStyle, style: widget.enabled ? buttonTitleTextStyle : buttonTitleDisableTextStyle,
minFontSize: 2, minFontSize: 2,
maxLines: 1, maxLines: 1,
) )

View File

@ -68,7 +68,7 @@ class _BusyButtonIconState extends State<BusyButtonIcon> {
Text( Text(
widget.title, widget.title,
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: buttonTitleTextStyle, style: widget.enabled ? buttonTitleTextStyle : buttonTitleDisableTextStyle,
maxLines: 1, maxLines: 1,
), ),
], ],

View File

@ -401,6 +401,20 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.9.2" 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: petitparser:
dependency: transitive dependency: transitive
description: description:

View File

@ -38,6 +38,7 @@ dependencies:
esc_pos_utils: ^0.3.6 # no edit for 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 charset_converter: ^1.0.3
crypto: ^2.1.5 crypto: ^2.1.5
permission_handler: ^5.0.1+2
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
sdk: flutter sdk: flutter