Flutter Camera Plugin导致条形码读取器崩溃

时间:2018-08-15 15:37:18

标签: android camera dart flutter

我的Flutter应用程序使用相机pugin和条形码读取器插件来拍照和扫描产品。当我先打开阅读器,然后拍照时,一切正常。但是,如果我先打开相机,条形码扫描器在识别条形码时会崩溃。我认为问题是相机页面,因为我尝试了多个扫描仪,并且每次都出现相同的错误:

     java.lang.IllegalArgumentException: Surface was abandoned
E/AndroidRuntime(26336):    at android.hardware.camera2.utils.SurfaceUtils.getSurfaceSize(SurfaceUtils.java:70)
E/AndroidRuntime(26336):    at android.hardware.camera2.params.OutputConfiguration.<init>(OutputConfiguration.java:237)
E/AndroidRuntime(26336):    at android.hardware.camera2.params.OutputConfiguration.<init>(OutputConfiguration.java:101)
E/AndroidRuntime(26336):    at android.hardware.camera2.impl.CameraDeviceImpl.createCaptureSession(CameraDeviceImpl.java:499)
E/AndroidRuntime(26336):    at io.flutter.plugins.camera.CameraPlugin$Camera.startPreview(CameraPlugin.java:672)
E/AndroidRuntime(26336):    at io.flutter.plugins.camera.CameraPlugin$Camera.access$2000(CameraPlugin.java:237)
E/AndroidRuntime(26336):    at io.flutter.plugins.camera.CameraPlugin$Camera$3.onOpened(CameraPlugin.java:437)
E/AndroidRuntime(26336):    at android.hardware.camera2.impl.CameraDeviceImpl$1.run(CameraDeviceImpl.java:139)
E/AndroidRuntime(26336):    at android.os.Handler.handleCallback(Handler.java:789)
E/AndroidRuntime(26336):    at android.os.Handler.dispatchMessage(Handler.java:98)
E/AndroidRuntime(26336):    at android.os.Looper.loop(Looper.java:164)
E/AndroidRuntime(26336):    at android.app.ActivityThread.main(ActivityThread.java:6938)
E/AndroidRuntime(26336):    at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime(26336):    at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
E/AndroidRuntime(26336):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
E/AndroidRuntime(26336): Caused by: android.hardware.camera2.legacy.LegacyExceptionUtils$BufferQueueAbandonedException
E/AndroidRuntime(26336):    at android.hardware.camera2.legacy.LegacyExceptionUtils.throwOnError(LegacyExceptionUtils.java:73)
E/AndroidRuntime(26336):    at android.hardware.camera2.legacy.LegacyCameraDevice.getSurfaceSize(LegacyCameraDevice.java:583)
E/AndroidRuntime(26336):    at android.hardware.camera2.utils.SurfaceUtils.getSurfaceSize(SurfaceUtils.java:68)

打开扫描仪的功能(使用:https://pub.dartlang.org/packages/barcode_scan):

  scan() async{
    try {
      String barcode = await BarcodeScanner.scan();
      setState(() {
        _nummer = barcode;
        _nummerController.text = _nummer;
      });
    } on PlatformException catch (e) {
      if (e.code == BarcodeScanner.CameraAccessDenied) {

      } else {

      }
    } on FormatException{

    } catch (e) {

    }
  }

该功能将打开我的相机页面:

  takePhoto() async {
    final result = await Navigator.push(
        context, MaterialPageRoute(builder: (context) => new CameraApp()));
    setState(() {
      _image = result.toString();
    });
  }

我的camera.dart文件(使用:https://pub.dartlang.org/packages/camera

import 'dart:async';
import 'dart:io';

import 'package:camera/camera.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';


class CameraApp extends StatefulWidget {
  @override
  _CameraAppState createState() => new _CameraAppState();
}

class _CameraAppState extends State<CameraApp> {
  CameraController controller;
  List<CameraDescription> cameras;
  bool _isReady = false;

  final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();

  Future<void> _setupCameras() async {
    try {
      // initialize cameras.
      cameras = await availableCameras();
      // initialize camera controllers.
      controller = new CameraController(cameras[0], ResolutionPreset.medium);
      await controller.initialize();
    } on CameraException catch (_) {
      // do something on error.
    }
    if (!mounted) return;
    setState(() {
      _isReady = true;
    });
  }

  @override
  void initState() {
    super.initState();
    _setupCameras();
  }

  @override
  void dispose() {
    controller?.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    double width = MediaQuery.of(context).size.width;
    double height = MediaQuery.of(context).size.height;


    if(controller == null){
      return new Scaffold(
          appBar: new AppBar(
            brightness: Brightness.light,
            backgroundColor: const Color.fromRGBO(127, 22, 22, 1.0),
            leading: new GestureDetector(
              child: new Icon(Icons.close),
              onTap: () {
                Navigator.pop(context);
              },
            ),
            title: new Text("Wein hinzufügen"),
          ),
        body: new Center(child:
          new Column(
              children: <Widget>[
                new Container(child: new Text("Es ist ein Fehler aufgetreten!", style: new TextStyle(fontSize: 24.0)), margin: new EdgeInsets.only(top: 40.0, bottom: 10.0),),
                new Container(child: new Text("Eventuell keine Kamera Erlaubniss.", style: new TextStyle(fontSize: 14.0),),),
                new Container(margin: new EdgeInsets.only(top: 100.0),child: new GestureDetector( onTap: _setupCameras,
                    child: new Image.asset("assets/images/refresh.png", width: 60.0, height: 60.0,)
                ),
                ),
            ]
          ))
      );
    }else{
      if (!controller.value.isInitialized) {
        return new Scaffold(
            appBar: new AppBar(
              brightness: Brightness.light,
              backgroundColor: const Color.fromRGBO(127, 22, 22, 1.0),
              leading: new GestureDetector(
                child: new Icon(Icons.close),
                onTap: () {
                  Navigator.pop(context);
                },
              ),
              title: new Text("Wein hinzufügen"),
            ),
            body: new Center(child:
            new Column(
                children: <Widget>[
                  new Container(child: new Text("Es ist ein Fehler aufgetreten!", style: new TextStyle(fontSize: 24.0)), margin: new EdgeInsets.only(top: 40.0, bottom: 10.0),),
                  new Container(child: new Text("Eventuell keine Kamera Erlaubniss.", style: new TextStyle(fontSize: 14.0),),),
                  new Container(margin: new EdgeInsets.only(top: 100.0),child: new GestureDetector( onTap: _setupCameras,
                      child: new Image.asset("assets/images/refresh.png", width: 60.0, height: 60.0,)
                  ),
                  ),
                ]
            ))
        );
      }else {
        return new Scaffold(
            key: _scaffoldKey,
            resizeToAvoidBottomPadding: false,
            appBar: new AppBar(
              brightness: Brightness.light,
              backgroundColor: const Color.fromRGBO(127, 22, 22, 1.0),
              leading: new GestureDetector(
                child: new Icon(Icons.close),
                onTap: () {
                  Navigator.pop(context);
                },
              ),
              title: new Text("Wein hinzufügen"),
            ),
            body: new Column(children: <Widget>[
              new Stack(alignment: Alignment.center, children: <Widget>[
                new AspectRatio(
                    aspectRatio: controller.value.aspectRatio,
                    child: new CameraPreview(controller)),
                new Container(
                  width: width * 0.6,
                  height: width * 0.8,
                  decoration: new BoxDecoration(
                    shape: BoxShape.rectangle,
                    color: const Color.fromRGBO(229, 229, 229, 0.3),
                    border: new Border.all(
                        color: const Color.fromRGBO(127, 22, 22, 1.0),
                        width: 1.0),
                  ),
                )
              ]),
              new Expanded(
                  child: new GestureDetector(
                      onTap: onTakePictureButtonPressed,
                      child: new Container(
                        color: Colors.black,
                        child: new Center(
                          child: new Container(
                            width: 70.0,
                            height: 70.0,
                            decoration: new BoxDecoration(
                                boxShadow: [
                                  new BoxShadow(
                                      color: Colors.black, blurRadius: 20.0)
                                ],
                                border: new Border.all(
                                    color: const Color.fromRGBO(
                                        92, 13, 13, 1.0),
                                    width: 8.0),
                                color: const Color.fromRGBO(127, 22, 22, 1.0),
                                shape: BoxShape.circle),
                          ),
                        ),
                      )))
            ]));
      }
    }
  }

  String timestamp() => new DateTime.now().millisecondsSinceEpoch.toString();


  void onTakePictureButtonPressed() {
    takePicture().then((String filePath) {
      if (mounted) {
        setState(() {

        });
        if (filePath != null){
          showInSnackBar('Picture saved to $filePath');
          controller.dispose();
          Navigator.pop(context, filePath);
        }
      }
    });
  }

  Future<String> takePicture() async {
    if (!controller.value.isInitialized) {
      showInSnackBar("Error, bitte versuchen sie es erneut!");
      return null;
    }
    final Directory extDir = await getApplicationDocumentsDirectory();
    final String dirPath = '${extDir.path}/Bilder/Notizen';
    await new Directory(dirPath).create(recursive: true);
    final String filePath = '$dirPath/${timestamp()}.png';

    if (controller.value.isTakingPicture) {
      // A capture is already pending, do nothing.
      return null;
    }

    try {
      await controller.takePicture(filePath);
    } on CameraException catch (e) {
      showInSnackBar(e.toString());
      return null;
    }
    return filePath;
  }

  void showInSnackBar(String message) {
    _scaffoldKey.currentState
        .showSnackBar(new SnackBar(content: new Text(message)));
  }


}

2 个答案:

答案 0 :(得分:0)

我的相机拍照功能崩溃了。

<块引用>

"java.lang.NullPointerException: Attempt to invoke virtual method 'int io.flutter.embedding.engine.systemchannels.PlatformChannel$DeviceOrientation.ordinal()' 在空对象引用 E/AndroidRuntime(18591) 上: io.flutter.plugins.camera.DeviceOrientationManager.getMediaOrientation(DeviceOrientationManager.java:58)"

对我来说帮助添加 在 initialize() 之后等待 controller.lockCaptureOrientation()。 试试这个,也许对你有帮助

   try {
        ...
          await controller.initialize();
          await controller.lockCaptureOrientation();

        }

答案 1 :(得分:-1)

尝试清理项目并重建:

flutter clean