fluttervisionsdkplugin 0.1.2 fluttervisionsdkplugin: ^0.1.2 copied to clipboard
A Flutter plugin package for integrating the Flutter Vision SDK into your Flutter application for scanning Barcodes and QrCodes
// ignore_for_file: avoid_print, unused_element, library_private_types_in_public_api
import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:fluttervisionsdkplugin/settings/camera_settings.dart';
import 'package:fluttervisionsdkplugin_example/secrets.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:fluttervisionsdkplugin/settings/focus_settings.dart';
import 'package:fluttervisionsdkplugin/settings/object_detection_settings.dart';
import 'package:fluttervisionsdkplugin/visioncamerawidget.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
FlutterToPluginCommunicator? communicator;
final env = Environment.staging;
bool isBarcodeBeingDetected = false;
bool isQRCodeBeingDetected = false;
bool isTextBeingDetected = false;
String scannedCode = '';
String scanErrorMessage = '';
String progress = '';
bool isConfiguring = false;
bool isAutoScanning = false;
bool isOnlineOCREnabled = true;
int scanMode = 1;
bool shouldDisplayFocusImage = false;
List<String> receivedCodes = [];
void _onScanError(String errorMessage) {
print('Scan Error: $errorMessage');
setState(() {
scanErrorMessage = errorMessage;
});
}
void updateReceivedCodes(List<String> codes) {
setState(() {
receivedCodes = codes;
});
}
void _onCodesReceived(List<String> codes) {
updateReceivedCodes(codes);
if (codes.isNotEmpty) {
updateScannedCode(codes.first);
} else {
updateScannedCode('');
}
}
void _onDetectionResult(bool textDetected, bool barCodeDetected, bool qrCodeDetected) {
print('Text Detected: $textDetected');
print('Barcode Detected: $barCodeDetected');
print('QR Code Detected: $qrCodeDetected');
}
void _onOCRImagesReceived(Map<String, dynamic> scanResult) {
print(scanResult);
}
void _changeCaptureMode(String mode) {
print('Changing Capture Mode to: $mode');
}
void _changeScanMode(String mode) {
print('Changing Scan Mode to: $mode');
}
void _capture() {
print('Capturing Photo');
}
void updateScannedType(bool isText, bool isBarcode, bool isQrCode) {
setState(() {
isTextBeingDetected = isText;
isBarcodeBeingDetected = isBarcode;
isQRCodeBeingDetected = isQrCode;
});
}
void updateScannedCode(String code) {
setState(() {
scannedCode = code;
});
}
void updateProgress(String progress) {
setState(() {
this.progress = progress;
});
}
void updateIsConfiguring(bool isConfiguring) {
setState(() {
this.isConfiguring = isConfiguring;
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: FutureBuilder<PermissionStatus>(
future: Permission.camera.status,
builder: (context, snapshot) {
if (Platform.isIOS || snapshot.data?.isGranted == true) {
return Column(
children: [
SizedBox(
width: double.infinity,
height: 400,
child: VisionCameraWidget(
environment: env,
onViewCreated: (communicator) {
this.communicator = communicator;
this.communicator?.setObjectDetectionSettings(ObjectDetectionSettings());
this.communicator?.setCameraSettings(CameraSettings());
this.communicator?.startCamera();
},
listener: MainNativeViewWidgetListener(this),
),
),
Expanded(
child: SingleChildScrollView(
child: Column(
children: [
Text(
'Scanned Code: $scannedCode',
style: const TextStyle(color: Colors.black, fontSize: 16),
),
Text(
'Barcode: $isBarcodeBeingDetected\t\tQRCode: $isQRCodeBeingDetected\t\tText: $isTextBeingDetected',
style: const TextStyle(color: Colors.black, fontSize: 16),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Expanded(
child: RadioListTile(
value: true,
title: const Text('Auto'),
groupValue: isAutoScanning,
onChanged: (i) {
setState(() {
isAutoScanning = true;
});
communicator?.setScanMode(1);
}),
),
Expanded(
child: RadioListTile(
value: false,
title: const Text('Manual'),
groupValue: isAutoScanning,
onChanged: (i) {
setState(() {
isAutoScanning = false;
});
communicator?.setScanMode(2);
}),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Flexible(
child: RadioListTile(
value: 1,
title: const Text('B'),
groupValue: scanMode,
onChanged: (i) {
setState(() {
scanMode = 1;
});
communicator?.setCaptureModeBarcode();
}),
),
Flexible(
child: RadioListTile(
value: 2,
title: const Text('Q'),
groupValue: scanMode,
onChanged: (i) {
setState(() {
scanMode = 2;
});
communicator?.setCaptureModeQrCode();
}),
),
if (!isAutoScanning)
Flexible(
child: RadioListTile(
value: 3,
title: const Text('O'),
groupValue: scanMode,
onChanged: (i) {
setState(() {
scanMode = 3;
});
communicator?.setCaptureModeOCR();
}),
),
],
),
if (!isAutoScanning && !isConfiguring)
ElevatedButton(
onPressed: () {
isOnlineOCREnabled = true;
communicator?.capturePhoto();
},
child: const Text('Capture Photo'),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (!isConfiguring)
ElevatedButton(
onPressed: () async {
updateIsConfiguring(true);
updateProgress('Working...');
communicator?.stopCamera();
await communicator?.configureOnDeviceOCR(
apiKey: switch (env) {
Environment.qa => throw UnimplementedError(),
Environment.dev => DEV.apiKey,
Environment.staging => STAGING.apiKey,
Environment.sandbox => SANDBOX.apiKey,
Environment.production => throw UnimplementedError(),
},
modelClass: ModelClass.shippingLabel,
modelSize: ModelSize.large);
},
child: const Text('Configure'),
),
if (progress.isNotEmpty) Text(progress)
],
),
if (!isConfiguring)
ElevatedButton(
onPressed: () {
isOnlineOCREnabled = false;
communicator?.capturePhoto();
},
child: const Text('Get Predictions'),
),
],
),
),
),
],
);
} else {
return Center(
child: FutureBuilder<bool>(
future: Permission.camera.isPermanentlyDenied,
builder: (context, snapshot) {
if (snapshot.data == true) {
return const Text("Go to Settings and allow camera permission");
} else {
return ElevatedButton(
onPressed: () async {
await Permission.camera.request();
setState(() {});
},
child: const Text('Request Camera Permission'));
}
},
));
}
},
),
),
);
}
}
class MainNativeViewWidgetListener implements PluginToFlutterCommunicator {
MainNativeViewWidgetListener(this._state);
final _MyAppState _state;
Timer? _timerTask;
@override
void onCameraStarted() {
_state.communicator?.setFocusSettings(FocusSettings());
}
@override
void onCameraStopped() {}
@override
void onCodesReceived(List<String> codes) {
_state.updateScannedCode(codes.join(','));
_resetTextAfterDelay();
}
@override
void onDetectionResult(bool isText, bool isBarcode, bool isQrCode) {
_state.updateScannedType(isText, isBarcode, isQrCode);
}
String? base64Image; List<String>? codes;
@override
void onImageCaptured(String base64Image, List<String> codes) {
this.base64Image = base64Image;
this.codes = codes;
if (_state.isOnlineOCREnabled) {
// _state.communicator?.callBolApi(
// apiKey: switch (_state.env) {
// Environment.qa => throw UnimplementedError(),
// Environment.dev => DEV.bolApiKey,
// Environment.staging => STAGING.bolApiKey,
// Environment.sandbox => SANDBOX.bolApiKey,
// Environment.production => throw UnimplementedError(),
// },
// image: base64Image,
// barcodes: codes);
_state.communicator?.callOcrApi(
apiKey: switch (_state.env) {
Environment.qa => throw UnimplementedError(),
Environment.dev => DEV.apiKey,
Environment.staging => STAGING.apiKey,
Environment.sandbox => SANDBOX.apiKey,
Environment.production => throw UnimplementedError(),
},
image: base64Image,
barcodes: codes,
sender: {
'contact_id': 'ctct_hNxjevb74gV62i5XTQvqg6'
},
recipient: {
'contact_id': 'ctct_hNxjevb74gV62i5XTQvqg6'
},
options: {
'match': {
'search': ['recipients'],
'location': true
},
'postprocess': {'require_unique_hash': false},
'transform': {'tracker': 'outbound', 'use_existing_tracking_number': false}
},
metadata: {
'Test': 'Pass'
});
} else {
_state.communicator?.getPredictions(base64Image, codes);
}
}
@override
void onOnDeviceConfigureProgress(double progress) {
print('Configure progress $progress');
_state.updateProgress(progress.toString());
}
@override
void onOnDeviceConfigurationComplete() {
print('On-Device Configuration Completed');
_state.communicator?.startCamera();
_state.updateProgress('');
_state.updateIsConfiguring(false);
}
@override
void onOnlineSLResult(Map<String, dynamic> result) {
_state.updateScannedCode(result.toString());
_resetTextAfterDelay();
}
@override
void onMatchingResult(Map<String, dynamic> result) {
_state.updateScannedCode(result.toString());
_resetTextAfterDelay();
}
@override
void onOnlineBOLResult(Map<String, dynamic> result) {
_state.updateScannedCode(result.toString());
_resetTextAfterDelay();
}
@override
void onOnDeviceOCRResult(Map<String, dynamic> result) {
print('ON-DEVICE OCR RESPONSE');
print(result);
_state.communicator?.callMatchingAPI(
apiKey: switch (_state.env) {
Environment.qa => throw UnimplementedError(),
Environment.dev => DEV.apiKey,
Environment.staging => STAGING.apiKey,
Environment.sandbox => SANDBOX.apiKey,
Environment.production => throw UnimplementedError(),
},
image: base64Image!,
barcodes: codes!,
onDeviceResponse: result,
sender: {
'contact_id': 'ctct_hNxjevb74gV62i5XTQvqg6'
},
recipient: {
'contact_id': 'ctct_hNxjevb74gV62i5XTQvqg6'
},
options: {
'parse_addresses': true,
'match_contacts': true
},
metadata: {
'Test': 'Pass'
}
);
// _state.updateScannedCode(result.toString());
// _resetTextAfterDelay();
}
@override
void onScanError(String error) {
_state.updateScannedCode(error);
_resetTextAfterDelay();
}
void _resetTextAfterDelay() {
_timerTask?.cancel();
_timerTask = Timer(const Duration(seconds: 4), () {
_state.updateScannedCode('');
_state.communicator?.rescan();
});
}
}