#flutter #android-camera2
Вопрос:
В настоящее время я создаю этот виджет экрана камеры, который будет перемещаться на другой экран при обнаружении штрих-кода водительских прав.
Мой поток приложений выглядит так:
Виджет экрана 1 -> Виджет экрана камеры ->> Виджет экрана 2 (виджет экрана 2 имеет кнопку для возврата к виджету экрана 1).
Поток будет нормально работать около 10 раз, но затем он всегда будет отображаться на виджете экрана камеры.
Вот исключение, которое выбрасывается:
I/Camera (24242): closeCaptureSession
E/AndroidRuntime(24242): FATAL EXCEPTION: pool-89-thread-1
E/AndroidRuntime(24242): Process: com.example.visitor_checkin_app, PID: 24242
E/AndroidRuntime(24242): java.lang.IllegalStateException: Session has been closed; further changes are illegal.
E/AndroidRuntime(24242): at android.hardware.camera2.impl.CameraCaptureSessionImpl.checkNotClosed(CameraCaptureSessionImpl.java:886)
E/AndroidRuntime(24242): at android.hardware.camera2.impl.CameraCaptureSessionImpl.setRepeatingRequest(CameraCaptureSessionImpl.java:303)
E/AndroidRuntime(24242): at io.flutter.plugins.camera.Camera.refreshPreviewCaptureSession(Camera.java:434)
E/AndroidRuntime(24242): at io.flutter.plugins.camera.Camera.access$600(Camera.java:83)
E/AndroidRuntime(24242): at io.flutter.plugins.camera.Camera$2.onConfigured(Camera.java:373)
E/AndroidRuntime(24242): at android.hardware.camera2.impl.CallbackProxies$SessionStateCallbackProxy.lambda$onConfigured$0$CallbackProxies$SessionStateCallbackProxy(CallbackProxies.java:53)
E/AndroidRuntime(24242): at android.hardware.camera2.impl.-$Lambda$CallbackProxies$SessionStateCallbackProxy$soW0qC12Osypoky6AfL3P2-TeDw.run(Unknown Source:4)
E/AndroidRuntime(24242): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
E/AndroidRuntime(24242): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
E/AndroidRuntime(24242): at java.lang.Thread.run(Thread.java:923)
Версия флаттера: 2.5.1
Версия камеры: 0.9.4
Версия Android minSdk: 27
Ниже приведен код:
import 'dart:async';
import 'package:camera/camera.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:google_ml_kit/google_ml_kit.dart';
class CameraView extends StatefulWidget {
CameraView(
{Key? key,
this.initialDirection = CameraLensDirection.back})
: super(key: key);
static const CAMERAVIEW_ROUTE = "/cameraview";
final String title = "Barcode Scanner";
final CameraLensDirection initialDirection;
@override
_CameraViewState createState() => _CameraViewState();
}
class _CameraViewState extends State<CameraView> {
BarcodeScanner barcodeScanner = GoogleMlKit.vision.barcodeScanner(const [
BarcodeFormat.pdf417
]);
bool isBusy = false;
CameraController? _controller;
int _cameraIndex = 0;
@override
void initState() {
super.initState();
for (var i = 0; i < cameras.length; i ) {
if (cameras[i].lensDirection == widget.initialDirection) {
_cameraIndex = i;
break;
}
}
_startLiveFeed();
isBusy = false;
}
@override
void dispose() {
_stopLiveFeed();
barcodeScanner.close();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title)
),
body: _body()
);
}
Widget _body() {
Widget body = _liveFeedBody();
return body;
}
Widget _liveFeedBody() {
if (_controller?.value.isInitialized == false) {
return Container();
}
return Container(
color: Colors.black,
child: Stack(
fit: StackFit.expand,
children: <Widget>[
CameraPreview(_controller!)
],
),
);
}
Future _startLiveFeed() async {
final camera = cameras[_cameraIndex];
_controller = CameraController(
camera,
ResolutionPreset.high,
enableAudio: false,
);
_controller?.initialize().then((_) {
if (!mounted) {
return;
}
_controller?.startImageStream(_processCreateInputImage);
if (mounted) {
setState(() {});
}
});
}
Future _stopLiveFeed() async {
await _controller?.stopImageStream();
await _controller?.dispose();
_controller = null;
}
Future _processBarCodeImage(InputImage inputImage) async {
final barcodes = await barcodeScanner.processImage(inputImage);
if (barcodes.length > 0) {
for (var i = 0; i < barcodes.length; i) {
Barcode bcode = barcodes[i];
if (bcode.type == BarcodeType.driverLicense) {
BarcodeDriverLicense bcodeDL = bcode.value as BarcodeDriverLicense;
String scannedName = bcodeDL.lastName! ", " bcodeDL.firstName!;
Navigator.of(context).popAndPushNamed(
AnotherScreen.ANOTHER_SCREEN_ROUTE,
arguments: ScannedInfoArguments(
scannedName));
break;
}
}
}
}
Future _processCreateInputImage(CameraImage image) async {
if (isBusy) return;
isBusy = true;
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 camera = cameras[_cameraIndex];
final imageRotation =
InputImageRotationMethods.fromRawValue(camera.sensorOrientation) ??
InputImageRotation.Rotation_0deg;
final inputImageFormat =
InputImageFormatMethods.fromRawValue(image.format.raw) ??
InputImageFormat.NV21;
final planeData = image.planes.map(
(Plane plane) {
return InputImagePlaneMetadata(
bytesPerRow: plane.bytesPerRow,
height: plane.height,
width: plane.width,
);
},
).toList();
final inputImageData = InputImageData(
size: imageSize,
imageRotation: imageRotation,
inputImageFormat: inputImageFormat,
planeData: planeData,
);
final inputImage =
InputImage.fromBytes(bytes: bytes, inputImageData: inputImageData);
await _processBarCodeImage(inputImage);
isBusy = false;
}
}
С нетерпением ждем предложений и/или решений для решения этой проблемы.
Спасибо
Комментарии:
1. У меня та же проблема, ты когда-нибудь ее исправлял?