1

So I am trying to get my camera preview working on iOS and Android, so that it can take a photo, however, I am receiving this error when trying to access my camera from the bottom navigation.

NoSuchMethodError: The Method '[]' was called on Null.
Receiver: null
Tried calling: [](0)

This is the camera I am using, and according to docs, this should be working correctly.

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:camera/camera.dart';
import 'package:stumble/main.dart';
import 'dart:async';

List<CameraDescription> cameras;

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();

  cameras = await availableCameras();
  runApp(MyApp());
}

class Camera extends StatefulWidget {
  Function setData;
  Camera({Key key, this.setData}) : super(key: key);

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

class _CameraScreenState extends State<Camera> {
  CameraController controller;
  int selectedCameraIndex;
  String imgPath;
  var image;

  @override
  void initState() {
    super.initState();
    controller = CameraController(cameras[0], ResolutionPreset.max);
    controller.initialize().then((_) {
      if (!mounted) {
        return;
      }
      setState(() {});
    });
  }

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

  @override
  Widget build(BuildContext context) {
    if (!controller.value.isInitialized) {
      return Container();
    }
    return MaterialApp(
      home: CameraPreview(controller),
    );
  }
}

I have tried various methods of troubleshooting and to no avail. Am I missing an asset entirely? How can I rectify? This is building on my initial question located here: Camera preview stretched in flutter

Edit: New code re: answers

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:camera/camera.dart';
import 'package:stumble/main.dart';
import 'dart:async';

List<CameraDescription> cameras;

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();

  cameras = await availableCameras();
  runApp(MyApp());
}

class Camera extends StatefulWidget {
  Function setData;
  Camera({Key key, this.setData}) : super(key: key);

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

class _CameraScreenState extends State<Camera> {
  CameraController controller;
  int selectedCameraIndex;
  String imgPath;
  var image;

  @override
  void initState() {
    super.initState();
    if (cameras.isNotEmpty) {
      controller = CameraController(cameras[0], ResolutionPreset.max);
      controller.initialize().then((_) {
        if (!mounted) {
          return;
        }
        setState(() {});
      });
    }
  }

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

  @override
  Widget build(BuildContext context) {
    if (cameras.isEmpty) {
      return Center(child: Text('No cameras available'));
    }
    if (!controller.value.isInitialized) {
      return Container();
    }
    return MaterialApp(
      home: CameraPreview(controller),
    );
  }
}

Edit:

onPressed: () {
            Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (context) => Camera(setData: (File file) {
                    _imageArray.add(file);
                    print("_imageArray--    " + _imageArray.length.toString());
                    setState(() {});
                  }),
                ));
dshukertjr
  • 15,244
  • 11
  • 57
  • 94
KirtM9
  • 231
  • 4
  • 19

3 Answers3

1

The error indicates that there is no available cameras in your current environment. Are you trying this out on a simulator? If so, that might be the cause.

Try to set a breakpoint to check the value of the cameras variable or print the length of it afterwards like this:

cameras = await availableCameras();
print(cameras.length);

If you get 0 as the length, that means there is no available cameras.

dshukertjr
  • 15,244
  • 11
  • 57
  • 94
  • So put those two that lines at the beginning? Or embedded somewhere? not sure I follow... – KirtM9 Apr 01 '21 at 00:02
  • The above code is just to confirm that the cameras variable is an empty List. If you want your code to work in a scenario where cameras are not available, you would have to use if statement to catch the case. Let me write up another answer right now. – dshukertjr Apr 01 '21 at 00:09
1

It seems like the error indicates that you do not have any available cameras. You should check if you have available cameras like this:

class _CameraScreenState extends State<Camera> {
  CameraController controller;
  int selectedCameraIndex;
  String imgPath;
  var image;

  @override
  void initState() {
    super.initState();
    if(cameras.isNotEmpty) {
      controller = CameraController(cameras[0], ResolutionPreset.max);
      controller.initialize().then((_) {
        if (!mounted) {
          return;
        }
        setState(() {});
      });
    }
  }

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

  @override
  Widget build(BuildContext context) {
    if(cameras.isEmpty) {
      return Center(child: Text('No cameras available'));
    }
    if (!controller.value.isInitialized) {
      return Container();
    }
    return MaterialApp(
      home: CameraPreview(controller),
    );
  }
}
dshukertjr
  • 15,244
  • 11
  • 57
  • 94
  • Tried this, now I am getting `NoSuchMethodError: The getter 'isNotEmpty' was called on null. Receiver:null. Tried calling: isNotEmpty` – KirtM9 Apr 02 '21 at 01:55
  • I added the code I am using. Can you take another look? – KirtM9 Apr 02 '21 at 01:56
  • @KirtM9 Thanks! Could I see the code for MyApp and App1? – dshukertjr Apr 02 '21 at 02:01
  • That is just my main.dart, which is very long. Shouldn't that line of code just be checking the cameras for the entire app? Also myApp and App1 are the same, I changed when uploading to stack overflow. Sorry for confusion. – KirtM9 Apr 02 '21 at 02:04
  • @KirtM9 Sure. Your previous error indicates that availableCameras() is retuning null. I just wanted to double check if there is something weird going on within MyApp. Can you set a breakpoint to confirm that availanleCameras() is returning null? – dshukertjr Apr 02 '21 at 02:44
  • Available cameras is no longer null. I have marked your answer as correct, as you have technically solved it. Do you have any other thoughts as to what is going astray with `isNotEmpty` ? – KirtM9 Apr 02 '21 at 03:10
  • Thanks @KirtM9 ! You have made my day. Do you by chance have some where in your code that's assigning something to 'cameras' ? It is weird that the value becomes null within initState. – dshukertjr Apr 02 '21 at 03:20
  • Nope, I added another edit to show the only other spot in my code where I use cameras, but it is to generate the screen in the bottom navigation, not in the page itself – KirtM9 Apr 02 '21 at 03:24
  • @KirtM9 Thanks. I'm outside right now, but let me write up a sample code as soon as I get back home for this issue. – dshukertjr Apr 02 '21 at 06:17
0

Could you see if this minimal sample works?

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:camera/camera.dart';

List<CameraDescription> cameras;

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();

  cameras = await availableCameras();
  print(cameras.length); // Confirm here that more than 1 cameras do exist
  runApp(MyApp());
}

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

class Camera extends StatefulWidget {
  Camera({Key key}) : super(key: key);

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

class _CameraScreenState extends State<Camera> {
  CameraController _controller;

  @override
  void initState() {
    super.initState();
    print(cameras.length); // Confirm here that cameras.length did not change from above
    if (cameras.isNotEmpty) {
      _controller = CameraController(cameras[0], ResolutionPreset.max);
      _controller.initialize().then((_) {
        if (!mounted) {
          return;
        }
        setState(() {});
      });
    }
  }

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

  @override
  Widget build(BuildContext context) {
    if (cameras.isEmpty) {
      return Center(child: Text('No cameras available'));
    }
    if (!_controller.value.isInitialized) {
      return Container();
    }
    return CameraPreview(_controller);
  }
}

dshukertjr
  • 15,244
  • 11
  • 57
  • 94