Arbaz Irshad
Arbaz Irshad

Reputation: 809

How to turn on camera flash in flutter?

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'),
            ),
          );
  }
}

Upvotes: 6

Views: 22312

Answers (4)

Abed Putra
Abed Putra

Reputation: 1215

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.

Upvotes: 4

Robert Apikyan
Robert Apikyan

Reputation: 2092

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,
}

Upvotes: 3

Asim Zubair
Asim Zubair

Reputation: 615

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),
            ),
          )

Upvotes: 15

Rodrigo Bastos
Rodrigo Bastos

Reputation: 2448

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

Upvotes: 3

Related Questions