I'm developing an app using Flutter, and I'm new to it. One of the pages in the app is designed to scan barcodes, and I'm currently testing with EAN-13. The camera opens fine when connected to the phone, but no matter how I adjust it, there's no response when the camera scans a barcode. I've been working on this for a day with no progress. Could someone help me identify what might be wrong with my code?
thx :)
...
...
...
import 'package:camera/camera.dart';
import 'package:google_ml_kit/google_ml_kit.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
void main() => runApp(Davascan());
class Davascan extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'test',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: ScanPage(),
);
}
}
class ScanPage extends StatefulWidget {
@override
_ScanPageState createState() => _ScanPageState();
}
class _ScanPageState extends State<ScanPage> {
CameraController? cameraController;
late List<CameraDescription> cameras;
late CameraDescription firstCamera;
bool isCameraInitialized = false;
bool isPermissionGranted = false;
String barcode = '';
@override
void initState() {
super.initState();
initializeCamera();
}
///////////////////////////////////////////////////////////////////////////////
void navigateToProductDetail(String productSn) async {
final url = Uri.parse('http://dafa.mid.com.tw/api/product/$productSn');
try {
final response = await http.get(url);
if (response.statusCode == 200 && response.body.isNotEmpty) {
final productDetails = json.decode(response.body);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Davascanlist(productDetails),
),
);
} else {
showAlertDialog('123', '123');
}
} catch (e) {
showAlertDialog('456', '456:$e');
}
}
void showAlertDialog(String title, String content) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text(title),
content: Text(content),
actions: <Widget>[
TextButton(
child: Text('test'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
/////////////////////////////////////////////////////////////////////////////////////////////
Future<void> initializeCamera() async {
cameras = await availableCameras();
firstCamera = cameras.first;
cameraController = CameraController(
firstCamera,
ResolutionPreset.high,
);
await cameraController!.initialize().then((_) {
if (!mounted) return;
setState(() {
isCameraInitialized = true;
startBarcodeScanStream();
});
});
final status = await Permission.camera.request();
setState(() => isPermissionGranted = status == PermissionStatus.granted);
}
/////////////////////////////////////////////////////////////////////////////////////////////////
void startBarcodeScanStream() async {
if (isPermissionGranted && isCameraInitialized) {
cameraController!.startImageStream((CameraImage image) async {
final WriteBuffer allBytes = WriteBuffer();
for (Plane plane in image.planes) {
allBytes.putUint8List(plane.bytes);
}
final bytes = allBytes.done().buffer.asUint8List();
final Size imageSize = Size(image.width.toDouble(), image.height.toDouble());
final InputImageRotation imageRotation = InputImageRotation.Rotation_0deg;
final InputImageFormat inputImageFormat = InputImageFormatMethods.fromRawValue(image.format.raw) ?? InputImageFormat.NV21;
final List<InputImagePlaneMetadata> planeData = image.planes.map(
(Plane plane) {
return InputImagePlaneMetadata(
bytesPerRow: plane.bytesPerRow,
height: plane.height,
width: plane.width,
);
},
).toList();
final InputImageData inputImageData = InputImageData(
size: imageSize,
imageRotation: imageRotation,
inputImageFormat: inputImageFormat,
planeData: planeData,
);
final InputImage inputImage = InputImage.fromBytes(bytes: bytes, inputImageData: inputImageData);
final barcodeScanner = GoogleMlKit.vision.barcodeScanner([
BarcodeFormat.ean13, //EAN-13
]);
final List<Barcode> barcodes = await barcodeScanner.processImage(inputImage);
for (Barcode barcode in barcodes) {
final String rawValue = barcode.value.displayValue ?? ''; // The barcode value
if (rawValue.isNotEmpty) {
setState(() {
this.barcode = rawValue;
});
navigateToProductDetail(rawValue);
// Stop scanning after the first barcode is found
cameraController!.stopImageStream();
break;
}
}
});
}
}
//////////////////////////////////////////////////////////////////////////////////
Future<void> fetchProductInfo(String barcode) async {
var url = Uri.parse('http://dafa.mid.com.tw/api/product/$barcode');
try {
var response = await http.get(url);
if (response.statusCode == 200) {
var productInfo = json.decode(response.body);
// Do something with the product info
// For example, navigate to a new screen with the product info
} else {
setState(() => this.barcode = 'Failed to load product info');
}
} catch (e) {
setState(() => this.barcode = 'Error retrieving product info: $e');
}
}
@override
void dispose() {
cameraController?.dispose();
super.dispose();
}
///////////////////////////////////////////////////////////////////
@override
Widget build(BuildContext context) {
var scanArea = MediaQuery.of(context).size.width * 0.8;
var scanAreaHeight = scanArea * 0.65; // GTN-13
return Scaffold(
appBar: AppBar(
title: Text('TEST'),
backgroundColor: Color.fromARGB(255, 179, 18, 6),
),
body: isCameraInitialized
? Stack(
fit: StackFit.expand,
children: <Widget>[
CameraPreview(cameraController!),
Container(
alignment: Alignment.center,
child: Container(
width: scanArea,
height: scanAreaHeight,
decoration: BoxDecoration(
border: Border.all(
color: Colors.red,
width: 3.0,
),
),
),
),
Container(
alignment: Alignment.center,
child: CustomPaint(
size: Size(scanArea, scanAreaHeight),
painter: OverlayPainter(scanArea: scanArea, scanAreaHeight: scanAreaHeight),
),
),
],
)
: Center(child: CircularProgressIndicator()),
);
}
}
class ProductPage extends StatelessWidget {
final Map productInfo;
ProductPage(this.productInfo);
@override
Widget build(BuildContext context) {
String imageUrl = productInfo['p_pic'] ?? 'https://via.placeholder.com/150';
return Scaffold(
appBar: AppBar(
title: Text(productInfo['p_name']),
),
body: SingleChildScrollView(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Image.network(imageUrl, fit: BoxFit.cover),
Text('stackOverFlow: ${productInfo['p_name']}', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
Text('stackOverFlow: ${productInfo['p_unit']}', style: TextStyle(fontSize: 18)),
Text('stackOverFlow: ${productInfo['p_storage']}', style: TextStyle(fontSize: 18)),
Text('stackOverFlow: ${productInfo['p_barcode']}', style: TextStyle(fontSize: 18)),
Text('stackOverFlow: ${productInfo['p_store_code']}', style: TextStyle(fontSize: 18)),
Text('stackOverFlow: ${productInfo['p_stock']}', style: TextStyle(fontSize: 18)),
Text('stackOverFlow: ${productInfo['p_price']}元', style: TextStyle(fontSize: 18)),
Text('stackOverFlow: ${productInfo['p_price2']}元', style: TextStyle(fontSize: 18)),
Text('stackOverFlow: ${productInfo['p_status'] == "1" ? "test" : "test"}', style: TextStyle(fontSize: 18)),
],
),
),
);
}
}
class OverlayPainter extends CustomPainter {
final double scanArea;
final double scanAreaHeight;
OverlayPainter({required this.scanArea, required this.scanAreaHeight});
@override
void paint(Canvas canvas, Size size) {
final rect = Rect.fromLTWH(
size.width / 2 - scanArea / 2,
size.height / 2 - scanAreaHeight / 2,
scanArea,
scanAreaHeight,
);
final Path background = Path()
..addRect(Rect.fromLTRB(0, 0, size.width, size.height))
..addRect(rect)
..fillType = PathFillType.evenOdd;
final Paint paint = Paint()..color = Colors.black.withOpacity(0.5);
canvas.drawPath(background, paint);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return false;
}
}
I've tried everything I can, including Googling and consulting with ChatGPT. This has been a challenging task for a flutter beginner. I'm also attaching my pubspec.yaml file for reference
name: flutter_application_1
description: A new Flutter project.
publish_to: 'none'
version: 1.0.0+1
environment:
sdk: '>=3.1.5 <4.0.0'
dependencies:
flutter:
sdk: flutter
google_maps_flutter: ^2.0.10
permission_handler: ^11.0.1
url_launcher: ^6.0.12
barcode_scan2: ^4.1.4
http: ^0.13.3
camera: ^0.9.4+5
google_ml_kit: ^0.7.2
sqflite: ^2.0.0+3
path_provider: ^2.0.2
cupertino_icons: ^1.0.2
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^2.0.0
flutter:
uses-material-design: true
assets:
- images/
- txt/