2

Here I'm trying to access the camera from the app using the camera package and I'm a beginner in a flutter. Hope you'll help me in this

I've created an async method and declared the variable in it now I want to call the declared in inside by widget and tried calling it but it says "Undefined name 'firstCamera'". I've referred to https://flutter.dev/docs/cookbook/plugins/picture-using-camera. But I've used code in another page

Thanks in advance.

this is my code

import 'package:flutter/material.dart';
import 'dart:io';
import 'dart:async';
import 'package:camera/camera.dart';

class PrivacyPolicyPage extends StatefulWidget {

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

class _PrivacyPolicyPageState extends State<PrivacyPolicyPage> {


  Future<void> camera() async {

    final cameras = await availableCameras();
    firstCamera = cameras.first;
  }
  CameraDescription? firstCamera;

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: TakePictureScreen(camera:firstCamera,),
    );
  }
}

class TakePictureScreen extends StatefulWidget {


  const TakePictureScreen({Key? key,required this.camera}) : super(key: key);
  final CameraDescription camera;

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

class _TakePictureScreenState extends State<TakePictureScreen> {
  late CameraController _controller;
  late Future<void> _initializeControllerFuture;

  @override
  void initState() {
    super.initState();
    // To display the current output from the Camera,
    // create a CameraController.
    _controller = CameraController(
      // Get a specific camera from the list of available cameras.
      widget.camera,
      // Define the resolution to use.
      ResolutionPreset.medium,
    );

    // Next, initialize the controller. This returns a Future.
    _initializeControllerFuture = _controller.initialize();
    @override
    void dispose() {
      // Dispose of the controller when the widget is disposed.
      _controller.dispose();
      super.dispose();
    }

  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: FutureBuilder<void>(
        future: _initializeControllerFuture,
        builder: (context,snapshot){
          if(snapshot.connectionState == ConnectionState.done){
            //If the Future is complete, display the preview.
            return CameraPreview(_controller);

          }
          else{
          //Other wise,display a loading indicator
            return const Center(child:CircularProgressIndicator());
          }
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () async {
          try{
            await _initializeControllerFuture;
            final image = await _controller.takePicture();
            await Navigator.of(context).push(
              MaterialPageRoute(
                builder:(context) => DisplayPictureScreen(
                  imagePath:image.path,
                )
              )
            );
          } catch(e){
            //If an error occurs, log the error to the console.
            print(e);
          }

        },
        child: const Icon(Icons.camera),
      ),
    );
  }
}

class DisplayPictureScreen extends StatelessWidget {
  final String imagePath;
  const DisplayPictureScreen({Key? key, required this.imagePath}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title:const Text("Display the Picture")),
      body:Image.file(File(imagePath)),
    );
  }
}
1
  • Hey, do you solve this? Because i have the same problem and i don't know how to manage with that Commented Feb 3, 2022 at 10:28

2 Answers 2

1

You have to define the variable outside the method. Your _PrivacyPolicyPageState class should look like this:

class _PrivacyPolicyPageState extends State<PrivacyPolicyPage> {

  // Define outside
  CameraDescription firstCamera;

  Future<void> camera() async {
    // Obtain a list of the available cameras on the device.
    final cameras = await availableCameras();

    // Get a specific camera from the list of available cameras.
    // Assigne a value to firstCamera variable
    firstCamera = cameras.first;

  }
  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: TakePictureScreen(camera:firstCamera,),
    );
  }
}
Sign up to request clarification or add additional context in comments.

6 Comments

I tried this but it says 'Error: Field 'firstCamera' should be initialized because its type 'CameraDescription' doesn't allow null.' and we can't use late
You are in a nullsafe env, my bad, try with CameraDescription? firstCamera; and be sure to call camera() first
I've searched a lot but still didn't find the solution, sorry to bother you again but that does not work either it says ' : Error: The argument type 'CameraDescription?' can't be assigned to the parameter type 'CameraDescription' because 'CameraDescription?' is nullable and 'CameraDescription' isn't.'
Can you copypaste exactly your code please?
i've edited the code with the changes you told me to do
|
0

According the doc, You need to put that code in the main.dart before the runApp():

// Ensure that plugin services are initialized so that 
// `availableCameras()`
// can be called before `runApp()`
WidgetsFlutterBinding.ensureInitialized();

// Obtain a list of the available cameras on the device.
final cameras = await availableCameras();

// Get a specific camera from the list of available cameras.
final firstCamera = cameras.first;

runApp(
  PrivacyPolicyPage(camera: camera),
);

And after that you will be able to put firstCamera in widgets as parameter and it will be available there

class PrivacyPolicyPage extends StatelessWidget {
    PrivacyPolicyPage(required this.camera);
    final CameraDescription camera;

    @override
    Widget build(BuildContext context) {
    return SafeArea(
        child: TakePictureScreen(camera:camera),
    );
  }
}

class TakePictureScreen extends StatefulWidget {
    const TakePictureScreen({Key? key,required this.camera}) : 
        super(key: key);
    final CameraDescription camera;

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

And you will be able to use it in _TakePictureScreenState like widget.camera

Also, you can create an InheritedWidget, and then you will be able to use camera in the deeper widgets

2 Comments

I tried that also but don't know how to call the variable on another page because I have to access the camera on another page.
You just need to pass it through the tree to the widget where you have to use it

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.