(FLUTTER) My Scan Page(EAN-13), Doesn't Work at All, and I Don't Know Why

90 views Asked by At

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/


0

There are 0 answers