How to turn on camera flash in flutter?
Asked Answered
C

4

6

I am building an app where you users can upload their videos to firebase. I am using the camera package for the camera module. I want to turn on the flash when the user clicks on the flash icon or turn it off.

I tried to find a way to turn on the flash through the camera package but I couldn't find any way to open up the flash.Then, I tried using the lamp package but for some reason the flash is not opening.

import 'dart:io';

import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/material.dart';
import 'package:camera/camera.dart';
import 'package:flutter_icons/flutter_icons.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
import 'package:flutter/foundation.dart';
import 'package:lamp/lamp.dart';

enum FlashState { Flash_OFF, Flash_On, Flash_Auto }

class CameraView extends StatefulWidget {
  final List<CameraDescription> cameras = [];
  CameraView() {
    availableCameras().then((cams) {
      cameras.addAll(cams);
      print(cameras.length);
      print(cams.toString());
    });
  }

  @override
  _CameraViewState createState() => _CameraViewState();
}

class _CameraViewState extends State<CameraView>
    with SingleTickerProviderStateMixin {
  CameraController _controller;
  int _selectedCameraIndex;
  bool _isRecording;

  FlashState currentFlashState = FlashState.Flash_OFF;
  String flashIcon = 'flash-off';

  AnimationController _animationController;
  Animation _colorTween;

  @override
  void initState() {
    _animationController =
        AnimationController(vsync: this, duration: Duration(milliseconds: 300));
    _colorTween = ColorTween(begin: Colors.blueGrey, end: Colors.red)
        .animate(_animationController);
    // _controller = CameraController(widget.cameras[0], ResolutionPreset.high,
    //     enableAudio: true);
    // _isRecording = false;
    // _controller.initialize().then((_) {
    //   if (!mounted) {
    //     return;
    //   }
    //   setState(() {});
    // });
    if (widget.cameras.length > 0) {
      setState(() {
        _selectedCameraIndex = 0;
      });
      _switchCamera(widget.cameras[_selectedCameraIndex]);
    }
    super.initState();
  }

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

  Future<void> _startVideoRecording(BuildContext context) async {
    if (!_controller.value.isInitialized) {
      await showDialog(
          context: context,
          builder: (BuildContext context) {
            return AlertDialog(
              title: Text('Camera Not Responding.'),
              content: Center(
                child: Text('Something went wrong.Try Again Later.'),
              ),
              actions: <Widget>[
                FlatButton(
                  child: Text('Okay.'),
                  onPressed: () {
                    Navigator.of(context).pop();
                  },
                )
              ],
            );
          });
      return null;
    }
    if (_controller.value.isRecordingVideo) {
      return null;
    }
    setState(() {
      _isRecording = true;
    });
    final Directory appDirectory = await getApplicationDocumentsDirectory();
    final String videoDirectory = '${appDirectory.path}/Videos';
    await Directory(videoDirectory).create(recursive: true);
    final String currentTime = DateTime.now().millisecondsSinceEpoch.toString();
    final String filePath = '$videoDirectory/$currentTime.mp4';

    try {
      //Lamp.turnOn();
      await _controller.startVideoRecording(filePath);
      //Lamp.turnOff();
      StorageReference firebaseStorageReference =
          FirebaseStorage.instance.ref().child(basename(filePath));
      StorageUploadTask videoUploadTask = firebaseStorageReference.putFile(
        File(filePath),
        StorageMetadata(contentType: 'video/mp4'),
      );
      StorageTaskSnapshot uploadSnapshot = await videoUploadTask.onComplete;
    } catch (error) {
      print(error);
      return null;
    }
  }

  Future<void> _stopVideoRecording() async {
    if (!_controller.value.isRecordingVideo) {
      return null;
    }

    try {
      await _controller.stopVideoRecording();
      setState(() {
        _isRecording = false;
      });
    } catch (error) {
      print(error);
      return null;
    }
  }

  Future<void> _switchCamera(CameraDescription cameraDescription) async {
    if (_controller != null) {
      await _controller.dispose();
    }
    _controller = CameraController(cameraDescription, ResolutionPreset.high);

    _controller.addListener(() {
      if (mounted) {
        setState(() {});
      }
      if (_controller.value.hasError) {
        Fluttertoast.showToast(
            msg: 'An Error Occured',
            toastLength: Toast.LENGTH_SHORT,
            gravity: ToastGravity.BOTTOM,
            timeInSecForIos: 2,
            textColor: Colors.white,
            backgroundColor: Colors.black38);
      }
    });
    try {
      await _controller.initialize();
    } catch (error) {
      print(error);
    }

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

  void _onSwitchCamera() {
    _selectedCameraIndex = _selectedCameraIndex < widget.cameras.length - 1
        ? _selectedCameraIndex + 1
        : 0;
    CameraDescription selectedCamera = widget.cameras[_selectedCameraIndex];
    _switchCamera(selectedCamera);
    setState(() {
      _selectedCameraIndex = _selectedCameraIndex;
    });
  }

  @override
  Widget build(BuildContext context) {
    return _controller.value.isInitialized
        ? Stack(
            fit: StackFit.expand,
            children: <Widget>[
              AspectRatio(
                aspectRatio: _controller.value.aspectRatio,
                child: CameraPreview(_controller),
              ),
              Positioned(
                left: MediaQuery.of(context).size.width * 0.40,
                bottom: MediaQuery.of(context).size.height * 0.04,
                child: AnimatedBuilder(
                  animation: _colorTween,
                  builder: (context, child) => IconButton(
                    icon: Icon(
                      MaterialCommunityIcons.getIconData('video'),
                    ),
                    color: _colorTween.value,
                    iconSize: 80.0,
                    onPressed: () {
                      if (!_isRecording) {
                        _animationController.forward();
                        _startVideoRecording(context);
                      } else if (_isRecording) {
                        _animationController.reverse();
                        _stopVideoRecording();
                      }
                    },
                  ),
                ),
              ),
              Positioned(
                right: 22.0,
                top: 22.0,
                child: IconButton(
                  icon: Icon(
                    MaterialCommunityIcons.getIconData('camera-switch'),
                  ),
                  onPressed: _onSwitchCamera,
                  iconSize: 28.0,
                ),
              ),
              Positioned(
                left: 22.0,
                top: 22.0,
                child: IconButton(
                  icon: Icon(
                    MaterialCommunityIcons.getIconData(flashIcon),
                  ),
                  onPressed: () {
                    currentFlashState =
                        currentFlashState.index < FlashState.values.length - 1
                            ? FlashState.values[currentFlashState.index + 1]
                            : FlashState.values[0];
                            if(currentFlashState == FlashState.Flash_On){
                              setState(() {
                                flashIcon = 'flash';
                              });
                              //Lamp.turnOn(); Turning on the flash through lamp package flutter but the flash not opening 
                            } else if(currentFlashState == FlashState.Flash_Auto){
                              setState(() {
                                flashIcon = 'flash-auto';
                              });
                            } else {
                              setState(() {
                                flashIcon = 'flash-off';
                              });
                              //Lamp.turnOff(); 
                            }
                  },
                ),
              )
            ],
          )
        : Container(
            child: Center(
              child: Text('Loading'),
            ),
          );
  }
}
Chronicles answered 2/10, 2019 at 15:35 Comment(2)
Have you got any solution?Playa
I have checked following packages for flash feature in flutter but none of them is working: flutter_flashlight, flutter_lantern, torch_compat, faro_torchAbecedarium
M
14

According to recent update on camera: ^0.8.0. You can use your camera flash manually:

Step-1: First follow this whole camera instructions: https://flutter.dev/docs/cookbook/plugins/picture-using-camera

Step-2: Then create any button, and on its onPressed function, just write this line.

//**For Flash OFF**:

 ElevatedButton(
            onPressed: () {
              _cameraController.setFlashMode(FlashMode.off);
            },
            style: ElevatedButton.styleFrom(primary: Colors.transparent),
            child: Text(
              "Flash Off",
              style: TextStyle(
                  color: Colors.white, backgroundColor: Colors.transparent),
            ),
          ),


 // **For Flash ON**
     ElevatedButton(
            onPressed: () {
              _cameraController.setFlashMode(FlashMode.always);
            },
            style: ElevatedButton.styleFrom(primary: Colors.transparent),
            child: Text(
              "Flash On",
              style: TextStyle(
                  color: Colors.white, backgroundColor: Colors.transparent),
            ),
          )
 //**For AUTO Flash:**
  ElevatedButton(
            onPressed: () {
              _cameraController.setFlashMode(FlashMode.auto);
            },
            style: ElevatedButton.styleFrom(primary: Colors.transparent),
            child: Text(
              "Auto Flash",
              style: TextStyle(
                  color: Colors.white, backgroundColor: Colors.transparent),
            ),
          )
Mortgage answered 15/3, 2021 at 12:8 Comment(0)
K
4

I tried camera:^0.10.5+2 and tried to implement the suggestions here but it didn't work. After some time of research, I found a way to turn on the flashlight using FlashMode.torch.

Like this: _cameraController.setFlashMode(FlashMode.torch);

Note: I use a POCO phone.

Khalsa answered 1/6, 2023 at 16:18 Comment(0)
C
3

Right now there's no camera plugin that accepts the use of flash. One workaround people are using is use this package https://pub.dev/packages/lamp to turn on the phone lamp before taking a photo and turning off afterwards.

It's not the ideal solution, but right now is the best one available

Cavesson answered 2/10, 2019 at 16:52 Comment(2)
I have tried this but the flash is not turning on for some reason.Chronicles
@ArbazIrshad you're right. it only works on iOS which makes it kind of useless :(Reticular
P
3

Asim Zubairs answer is correct, for flutter camera plugin, it's good to highlight that FlashMode.always is turning on flashlight only while capturing the photo, but if you want to turn on the flashlight and keep it, for situations like video recording, FlashMode.torch will work for that.

Here is the FlashMode enum from the camera plugin

enum FlashMode {
  /// Do not use the flash when taking a picture.
  off,

  /// Let the device decide whether to flash the camera when taking a picture.
  auto,

  /// Always use the flash when taking a picture.
  always,

  /// Turns on the flash light and keeps it on until switched off.
  torch,
}
Pervade answered 31/8, 2021 at 13:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.