微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在颤动中单击相机按钮后手电筒重新启动

如何解决在颤动中单击相机按钮后手电筒重新启动

我正在尝试使用颤振中的相机插件(相机:^0.8.1+3)构建一个应用程序,在此应用程序中,我试图在手电筒打开时单击图片,但问题是它可以工作在某些 Oneplus 设备中正确,但在任何其他设备中,当我尝试单击图片时,手电筒会重新启动。我使用的是 Flutter 2。


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

import 'package:camera/camera.dart';
import 'package:Flutter/material.dart';
import 'package:video_player/video_player.dart';

class CameraExampleHome extends StatefulWidget {
  @override
  _CameraExampleHomeState createState() {
    return _CameraExampleHomeState();
  }
}

/// Returns a suitable camera icon for [direction].
IconData getCameraLensIcon(CameraLensDirection direction) {
  switch (direction) {
    case CameraLensDirection.back:
      return Icons.camera_rear;
    case CameraLensDirection.front:
      return Icons.camera_front;
    case CameraLensDirection.external:
      return Icons.camera;
    default:
      throw ArgumentError('UnkNown lens direction');
  }
}

void logError(String code,String? message) {
  if (message != null) {
    print('Error: $code\nError Message: $message');
  } else {
    print('Error: $code');
  }
}

class _CameraExampleHomeState extends State<CameraExampleHome>
    with WidgetsBindingObserver,TickerProviderStateMixin {
  CameraController? controller;
  XFile? imageFile;
  XFile? videoFile;
  VideoPlayerController? videoController;
  VoidCallback? videoPlayerListener;
  bool enableAudio = true;
  double _minAvailableExposureOffset = 0.0;
  double _maxAvailableExposureOffset = 0.0;
  double _currentExposureOffset = 0.0;
  late AnimationController _flashModeControlRowAnimationController;
  late Animation<double> _flashModeControlRowAnimation;
  late AnimationController _exposureModeControlRowAnimationController;
  late Animation<double> _exposureModeControlRowAnimation;
  late AnimationController _focusModeControlRowAnimationController;
  late Animation<double> _focusModeControlRowAnimation;
  double _minAvailableZoom = 1.0;
  double _maxAvailableZoom = 1.0;
  double _currentScale = 1.0;
  double _baseScale = 1.0;

  // Counting pointers (number of user fingers on screen)
  int _pointers = 0;

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance?.addobserver(this);

    _flashModeControlRowAnimationController = AnimationController(
      duration: const Duration(milliseconds: 10),vsync: this,);
    _flashModeControlRowAnimation = CurvedAnimation(
      parent: _flashModeControlRowAnimationController,curve: Curves.easeInCubic,);
    _exposureModeControlRowAnimationController = AnimationController(
      duration: const Duration(milliseconds: 10),);
    _exposureModeControlRowAnimation = CurvedAnimation(
      parent: _exposureModeControlRowAnimationController,);
    _focusModeControlRowAnimationController = AnimationController(
      duration: const Duration(milliseconds: 10),);
    _focusModeControlRowAnimation = CurvedAnimation(
      parent: _focusModeControlRowAnimationController,);
  }

  @override
  void dispose() {
    WidgetsBinding.instance?.removeObserver(this);
    _flashModeControlRowAnimationController.dispose();
    _exposureModeControlRowAnimationController.dispose();
    super.dispose();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    final CameraController? cameraController = controller;

    // App state changed before we got the chance to initialize.
    if (cameraController == null || !cameraController.value.isInitialized) {
      return;
    }

    if (state == AppLifecycleState.inactive) {
      cameraController.dispose();
    } else if (state == AppLifecycleState.resumed) {
      onNewCameraSelected(cameraController.description);
    }
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _scaffoldKey,appBar: AppBar(
        title: const Text('Camera example'),),body: Column(
        children: <Widget>[
          Expanded(
            child: Container(
              child: Padding(
                padding: const EdgeInsets.all(1.0),child: Center(
                  child: _cameraPreviewWidget(),decoration: Boxdecoration(
                color: Colors.black,border: Border.all(
                  color:
                  controller != null && controller!.value.isRecordingVideo
                      ? Colors.redAccent
                      : Colors.grey,width: 3.0,_captureControlRowWidget(),_modeControlRowWidget(),Padding(
            padding: const EdgeInsets.all(5.0),child: Row(
              mainAxisAlignment: MainAxisAlignment.start,children: <Widget>[
                _cameraTogglesRowWidget(),_thumbnailWidget(),],);
  }

  /// display the preview from the camera (or a message if the preview is not available).
  Widget _cameraPreviewWidget() {
    final CameraController? cameraController = controller;

    if (cameraController == null || !cameraController.value.isInitialized) {
      return const   Text(
        'Tap a camera',style: TextStyle(
          color: Colors.white,fontSize: 24.0,fontWeight: FontWeight.w900,);
    } else {
      return Listener(
        onPointerDown: (_) => _pointers++,onPointerUp: (_) => _pointers--,child: CameraPreview(
          controller!,child: LayoutBuilder(
              builder: (BuildContext context,BoxConstraints constraints) {
                return GestureDetector(
                  behavior: HitTestBehavior.opaque,onScaleStart: _handleScaleStart,onScaleUpdate: _handleScaleUpdate,onTapDown: (details) => onViewFinderTap(details,constraints),);
              }),);
    }
  }

  void _handleScaleStart(ScaleStartDetails details) {
    _baseScale = _currentScale;
  }

  Future<void> _handleScaleUpdate(ScaleUpdateDetails details) async {
    // When there are not exactly two fingers on screen don't scale
    if (controller == null || _pointers != 2) {
      return;
    }

    _currentScale = (_baseScale * details.scale)
        .clamp(_minAvailableZoom,_maxAvailableZoom);

    await controller!.setZoomLevel(_currentScale);
  }

  /// display the thumbnail of the captured image or video.
  Widget _thumbnailWidget() {
    final VideoPlayerController? localVideoController = videoController;

    return Expanded(
      child: Align(
        alignment: Alignment.centerRight,child: Row(
          mainAxisSize: MainAxisSize.min,children: <Widget>[
            localVideoController == null && imageFile == null
                ? Container()
                : SizedBox(
              child: (localVideoController == null)
                  ? Container(child: Image.file(File(imageFile!.path)))
                  : Container(
                child: Center(
                  child: AspectRatio(
                      aspectRatio:
                      localVideoController.value.size != null
                          ? localVideoController
                          .value.aspectRatio
                          : 1.0,child: VideoPlayer(localVideoController)),decoration: Boxdecoration(
                    border: Border.all(color: Colors.pink)),width: 64.0,height: 64.0,);
  }

  /// display a bar with buttons to change the flash and exposure modes
  Widget _modeControlRowWidget() {
    return Column(
      children: [
        Row(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,mainAxisSize: MainAxisSize.max,children: <Widget>[
            IconButton(
              icon: Icon(Icons.flash_on),color: Colors.blue,onpressed: controller != null ? onFlashModeButtonpressed : null,IconButton(
              icon: Icon(Icons.exposure),onpressed:
              controller != null ? onExposureModeButtonpressed : null,IconButton(
              icon: Icon(Icons.filter_center_focus),onpressed: controller != null ? onFocusModeButtonpressed : null,IconButton(
              icon: Icon(enableAudio ? Icons.volume_up : Icons.volume_mute),onpressed: controller != null ? onAudioModeButtonpressed : null,IconButton(
              icon: Icon(controller?.value.isCaptureOrientationLocked ?? false
                  ? Icons.screen_lock_rotation
                  : Icons.screen_rotation),onpressed: controller != null
                  ? onCaptureOrientationLockButtonpressed
                  : null,_flashModeControlRowWidget(),_exposureModeControlRowWidget(),_focusModeControlRowWidget(),);
  }

  Widget _flashModeControlRowWidget() {
    return SizeTransition(
      sizefactor: _flashModeControlRowAnimation,child: ClipRect(
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,children: [
            IconButton(
              icon: Icon(Icons.flash_off),color: controller?.value.flashMode == FlashMode.off
                  ? Colors.orange
                  : Colors.blue,onpressed: controller != null
                  ? () => onSetFlashModeButtonpressed(FlashMode.off)
                  : null,IconButton(
              icon: Icon(Icons.flash_auto),color: controller?.value.flashMode == FlashMode.auto
                  ? Colors.orange
                  : Colors.blue,onpressed: controller != null
                  ? () => onSetFlashModeButtonpressed(FlashMode.auto)
                  : null,IconButton(
              icon: Icon(Icons.flash_on),color: controller?.value.flashMode == FlashMode.always
                  ? Colors.orange
                  : Colors.blue,onpressed: controller != null
                  ? () => onSetFlashModeButtonpressed(FlashMode.always)
                  : null,IconButton(
              icon: Icon(Icons.highlight),color: controller?.value.flashMode == FlashMode.torch
                  ? Colors.orange
                  : Colors.blue,onpressed: controller != null
                  ? () => onSetFlashModeButtonpressed(FlashMode.torch)
                  : null,);
  }

  Widget _exposureModeControlRowWidget() {
    final ButtonStyle styleAuto = TextButton.styleFrom(
      primary: controller?.value.exposureMode == ExposureMode.auto
          ? Colors.orange
          : Colors.blue,);
    final ButtonStyle styleLocked = TextButton.styleFrom(
      primary: controller?.value.exposureMode == ExposureMode.locked
          ? Colors.orange
          : Colors.blue,);

    return SizeTransition(
      sizefactor: _exposureModeControlRowAnimation,child: ClipRect(
        child: Container(
          color: Colors.grey.shade50,child: Column(
            children: [
              Center(
                child: Text("Exposure Mode"),Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,children: [
                  TextButton(
                    child: Text('AUTO'),style: styleAuto,onpressed: controller != null
                        ? () =>
                        onSetExposureModeButtonpressed(ExposureMode.auto)
                        : null,onLongPress: () {
                      if (controller != null) {
                        controller!.setExposurePoint(null);
                        showInSnackBar('Resetting exposure point');
                      }
                    },TextButton(
                    child: Text('LOCKED'),style: styleLocked,onpressed: controller != null
                        ? () =>
                        onSetExposureModeButtonpressed(ExposureMode.locked)
                        : null,Center(
                child: Text("Exposure Offset"),children: [
                  Text(_minAvailableExposureOffset.toString()),Slider(
                    value: _currentExposureOffset,min: _minAvailableExposureOffset,max: _maxAvailableExposureOffset,label: _currentExposureOffset.toString(),onChanged: _minAvailableExposureOffset ==
                        _maxAvailableExposureOffset
                        ? null
                        : setExposureOffset,Text(_maxAvailableExposureOffset.toString()),);
  }

  Widget _focusModeControlRowWidget() {
    final ButtonStyle styleAuto = TextButton.styleFrom(
      primary: controller?.value.focusMode == FocusMode.auto
          ? Colors.orange
          : Colors.blue,);
    final ButtonStyle styleLocked = TextButton.styleFrom(
      primary: controller?.value.focusMode == FocusMode.locked
          ? Colors.orange
          : Colors.blue,);

    return SizeTransition(
      sizefactor: _focusModeControlRowAnimation,child: Column(
            children: [
              Center(
                child: Text("Focus Mode"),onpressed: controller != null
                        ? () => onSetFocusModeButtonpressed(FocusMode.auto)
                        : null,onLongPress: () {
                      if (controller != null) controller!.setFocusPoint(null);
                      showInSnackBar('Resetting focus point');
                    },onpressed: controller != null
                        ? () => onSetFocusModeButtonpressed(FocusMode.locked)
                        : null,);
  }

  /// display the control bar with buttons to take pictures and record videos.
  Widget _captureControlRowWidget() {
    final CameraController? cameraController = controller;

    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,children: <Widget>[
        IconButton(
          icon: const Icon(Icons.camera_alt),onpressed: cameraController != null &&
              cameraController.value.isInitialized
              // !cameraController.value.isRecordingVideo
              ? onTakePictureButtonpressed
              : null,IconButton(
          icon: const Icon(Icons.videocam),onpressed: cameraController != null &&
              cameraController.value.isInitialized &&
              !cameraController.value.isRecordingVideo
              ? onVideoRecordButtonpressed
              : null,IconButton(
          icon: cameraController != null &&
              cameraController.value.isRecordingPaused
              ? Icon(Icons.play_arrow)
              : Icon(Icons.pause),onpressed: cameraController != null &&
              cameraController.value.isInitialized &&
              cameraController.value.isRecordingVideo
              ? (cameraController.value.isRecordingPaused)
              ? onResumeButtonpressed
              : onPauseButtonpressed
              : null,IconButton(
          icon: const Icon(Icons.stop),color: Colors.red,onpressed: cameraController != null &&
              cameraController.value.isInitialized &&
              cameraController.value.isRecordingVideo
              ? onStopButtonpressed
              : null,)
      ],);
  }

  /// display a row of toggle to select the camera (or a message if no camera is available).
  Widget _cameraTogglesRowWidget() {
    final List<Widget> toggles = <Widget>[];

    final onChanged = (CameraDescription? description) {
      if (description == null) {
        return;
      }

      onNewCameraSelected(description);
    };

    if (cameras.isEmpty) {
      return const Text('No camera found');
    } else {
      for (CameraDescription cameraDescription in cameras) {
        toggles.add(
          SizedBox(
            width: 90.0,child: RadioListTile<CameraDescription>(
              title: Icon(getCameraLensIcon(cameraDescription.lensDirection)),groupValue: controller?.description,value: cameraDescription,onChanged:
              controller != null && controller!.value.isRecordingVideo
                  ? null
                  : onChanged,);
      }
    }

    return Row(children: toggles);
  }

  String timestamp() => DateTime.Now().millisecondsSinceEpoch.toString();

  void showInSnackBar(String message) {
    // ignore: deprecated_member_use
    _scaffoldKey.currentState?.showSnackBar(SnackBar(content: Text(message)));
  }

  void onViewFinderTap(TapDownDetails details,BoxConstraints constraints) {
    if (controller == null) {
      return;
    }

    final CameraController cameraController = controller!;

    final offset = Offset(
      details.localPosition.dx / constraints.maxWidth,details.localPosition.dy / constraints.maxHeight,);
    cameraController.setExposurePoint(offset);
    cameraController.setFocusPoint(offset);
  }

  void onNewCameraSelected(CameraDescription cameraDescription) async {
    if (controller != null) {
      await controller!.dispose();
    }
    final CameraController cameraController = CameraController(
      cameraDescription,ResolutionPreset.medium,enableAudio: enableAudio,imageFormatGroup: ImageFormatGroup.jpeg,);
    controller = cameraController;

    // If the controller is updated then update the UI.
    cameraController.addListener(() {
      if (mounted) setState(() {});
      if (cameraController.value.hasError) {
        showInSnackBar(
            'Camera error ${cameraController.value.errorDescription}');
      }
    });

    try {
      await cameraController.initialize();
      await Future.wait([
        cameraController
            .getminexposureOffset()
            .then((value) => _minAvailableExposureOffset = value),cameraController
            .getMaxExposureOffset()
            .then((value) => _maxAvailableExposureOffset = value),cameraController
            .getMaxZoomLevel()
            .then((value) => _maxAvailableZoom = value),cameraController
            .getMinZoomLevel()
            .then((value) => _minAvailableZoom = value),]);
    } on CameraException catch (e) {
      _showCameraException(e);
    }

    if (mounted) {
      setState(() {});
    }
  }

  void onTakePictureButtonpressed() {
    takePicture().then((XFile? file) {
      if (mounted) {
        setState(() {
          imageFile = file;
          videoController?.dispose();
          videoController = null;
           controller?.value.flashMode == FlashMode.torch;
        });
        if (file != null) showInSnackBar('Picture saved to ${file.path}');
      }
    });
  }

  void onFlashModeButtonpressed() {
    if (_flashModeControlRowAnimationController.value == 1) {
      _flashModeControlRowAnimationController.reverse();
    } else {
      _flashModeControlRowAnimationController.forward();
      _exposureModeControlRowAnimationController.reverse();
      _focusModeControlRowAnimationController.reverse();
    }
  }

  void onExposureModeButtonpressed() {
    if (_exposureModeControlRowAnimationController.value == 1) {
      _exposureModeControlRowAnimationController.reverse();
    } else {
      _exposureModeControlRowAnimationController.forward();
      _flashModeControlRowAnimationController.reverse();
      _focusModeControlRowAnimationController.reverse();
    }
  }

  void onFocusModeButtonpressed() {
    if (_focusModeControlRowAnimationController.value == 1) {
      _focusModeControlRowAnimationController.reverse();
    } else {
      _focusModeControlRowAnimationController.forward();
      _flashModeControlRowAnimationController.reverse();
      _exposureModeControlRowAnimationController.reverse();
    }
  }

  void onAudioModeButtonpressed() {
    enableAudio = !enableAudio;
    if (controller != null) {
      onNewCameraSelected(controller!.description);
    }
  }

  void onCaptureOrientationLockButtonpressed() async {
    if (controller != null) {
      final CameraController cameraController = controller!;
      if (cameraController.value.isCaptureOrientationLocked) {
        await cameraController.unlockCaptureOrientation();
        showInSnackBar('Capture orientation unlocked');
      } else {
        await cameraController.lockCaptureOrientation();
        showInSnackBar(
            'Capture orientation locked to ${cameraController.value.lockedCaptureOrientation.toString().split('.').last}');
      }
    }
  }

  void onSetFlashModeButtonpressed(FlashMode mode) {
    setFlashMode(mode).then((_) {
      if (mounted) setState(() {});
      showInSnackBar('Flash mode set to ${mode.toString().split('.').last}');

    });
  }

  void onSetExposureModeButtonpressed(ExposureMode mode) {
    setExposureMode(mode).then((_) {
      if (mounted) setState(() {});
      showInSnackBar('Exposure mode set to ${mode.toString().split('.').last}');
    });
  }

  void onSetFocusModeButtonpressed(FocusMode mode) {
    setFocusMode(mode).then((_) {
      if (mounted) setState(() {});
      showInSnackBar('Focus mode set to ${mode.toString().split('.').last}');
    });
  }

  void onVideoRecordButtonpressed() {
    startVideoRecording().then((_) {
      if (mounted) setState(() {});
    });
  }

  void onStopButtonpressed() {
    stopVideoRecording().then((file) {
      if (mounted) setState(() {});
      if (file != null) {
        showInSnackBar('Video recorded to ${file.path}');
        videoFile = file;
        _startVideoPlayer();
      }
    });
  }

  void onPauseButtonpressed() {
    pauseVideoRecording().then((_) {
      if (mounted) setState(() {});
      showInSnackBar('Video recording paused');
    });
  }

  void onResumeButtonpressed() {
    resumeVideoRecording().then((_) {
      if (mounted) setState(() {});
      showInSnackBar('Video recording resumed');
    });
  }

  Future<void> startVideoRecording() async {
    final CameraController? cameraController = controller;

    if (cameraController == null || !cameraController.value.isInitialized) {
      showInSnackBar('Error: select a camera first.');
      return;
    }

    if (cameraController.value.isRecordingVideo) {

      return;
    }

    try {
      await cameraController.startVideoRecording();
    } on CameraException catch (e) {
      _showCameraException(e);
      return;
    }
  }

  Future<XFile?> stopVideoRecording() async {
    final CameraController? cameraController = controller;

    if (cameraController == null || !cameraController.value.isRecordingVideo) {
      return null;
    }

    try {
      return cameraController.stopVideoRecording();
    } on CameraException catch (e) {
      _showCameraException(e);
      return null;
    }
  }

  Future<void> pauseVideoRecording() async {
    final CameraController? cameraController = controller;

    if (cameraController == null || !cameraController.value.isRecordingVideo) {
      return null;
    }

    try {
      await cameraController.pauseVideoRecording();
    } on CameraException catch (e) {
      _showCameraException(e);
      rethrow;
    }
  }

  Future<void> resumeVideoRecording() async {
    final CameraController? cameraController = controller;

    if (cameraController == null || !cameraController.value.isRecordingVideo) {
      return null;
    }

    try {
      await cameraController.resumeVideoRecording();
    } on CameraException catch (e) {
      _showCameraException(e);
      rethrow;
    }
  }

  Future<void> setFlashMode(FlashMode mode) async {
    if (controller == null) {
      return;
    }

    try {
      await controller!.setFlashMode(mode);
    } on CameraException catch (e) {
      _showCameraException(e);
      rethrow;
    }
  }

  Future<void> setExposureMode(ExposureMode mode) async {
    if (controller == null) {
      return;
    }

    try {
      await controller!.setExposureMode(mode);
    } on CameraException catch (e) {
      _showCameraException(e);
      rethrow;
    }
  }

  Future<void> setExposureOffset(double offset) async {
    if (controller == null) {
      return;
    }

    setState(() {
      _currentExposureOffset = offset;
    });
    try {
      offset = await controller!.setExposureOffset(offset);
    } on CameraException catch (e) {
      _showCameraException(e);
      rethrow;
    }
  }

  Future<void> setFocusMode(FocusMode mode) async {
    if (controller == null) {
      return;
    }

    try {
      await controller!.setFocusMode(mode);
    } on CameraException catch (e) {
      _showCameraException(e);
      rethrow;
    }
  }

  Future<void> _startVideoPlayer() async {
    if (videoFile == null) {
      return;
    }

    final VideoPlayerController vController =
    VideoPlayerController.file(File(videoFile!.path));
    videoPlayerListener = () {
      if (videoController != null && videoController!.value.size != null) {
        // Refreshing the state to update video player with the correct ratio.
        if (mounted) setState(() {});
        videoController!.removeListener(videoPlayerListener!);
      }
    };
    vController.addListener(videoPlayerListener!);
    await vController.setLooping(true);
    await vController.initialize();
    await videoController?.dispose();
    if (mounted) {
      setState(() {
        imageFile = null;
        videoController = vController;
      });
    }
    await vController.play();
  }

  Future<XFile?> takePicture() async {
    final CameraController? cameraController = controller;
    if (cameraController == null || !cameraController.value.isInitialized) {
      showInSnackBar('Error: select a camera first.');
      return null;
    }

    if (cameraController.value.isTakingPicture) {

      return null;
    }

    try {
      XFile file = await cameraController.takePicture();
      return file;
    } on CameraException catch (e) {
      _showCameraException(e);
      return null;
    }
  }

  void _showCameraException(CameraException e) {
    logError(e.code,e.description);
    showInSnackBar('Error: ${e.code}\n${e.description}');
  }
}

class CameraApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: CameraExampleHome(),);
  }
}

List<CameraDescription> cameras = [];

Future<void> main() async {

  try {
    WidgetsFlutterBinding.ensureInitialized();
    cameras = await availableCameras();
  } on CameraException catch (e) {
    logError(e.code,e.description);
  }
  runApp(CameraApp());
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?