react-native-vision-camera: 🐛 `takePhoto()` doesn't resolve on Android

Question

This is the error I get upon attempting to use takePhoto() on android. This of course is followed by the failure of my promise. I’ve tried googling the error but I’m not at all finding information a view manager issue (?).

system/view-not-found: [system/view-not-found] The given view (ID 5079) was not found in the view manager.

Below is the code that is producing this


import { useCameraDevices, Camera,} from 'react-native-vision-camera' ;




function CameraElement (props) {
//Ref creation
  const cameraRef = React.useRef();
  const devices = useCameraDevices()
  const device = devices.back

  ....
 
//Handles Taking photo
const handleCapture = async () => {
  const data = await cameraRef.current.takePhoto({
    enableAutoStabilization: true,
    skipMetadata: true,
    photoCodec: 'jpeg',
    quality: 100,
  });
  console.log(data);
}

  return (

      <View style = {{alignItems:'center',}}>
 
             ....

//THE RELEVANT PART
        <Modal
        animationType="none"
        transparent = {true}
        visible = {isVisCam}>
          <Camera
            ref = {cameraRef}
            style={{width:styles.windowWidth,height:styles.windowHeight*.9}}
            device={device}
            isActive={true}
            photo = {true}
          />
          <View style = {{height:styles.windowHeight*.1, backgroundColor:"white"}}>
            <TouchableOpacity onPress = {handleCapture}><Image source = {require(....)} style = {[styles.iconDim, {alignSelf:"flex-start", justifyContent:"center", margin: 10}]}/></TouchableOpacity>
          </View>

        </Modal>

//END OF CAMERA Code

      </View>

  );
};

export default CameraElement;


What I tried

No response

VisionCamera Version

2.4.1

Additional information

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 2
  • Comments: 34 (11 by maintainers)

Most upvoted comments

Any update on this issue? In my case, I have to use Modal as a container. (Its working properly on ios and not working on android)

Hi @mrousavy , I have a requirement to render the camera inside a modal. Is there any way we can overcome this defect and render it inside a modal ?

I Have same issue, I solve this issue with add a state for wait camera initialized:

for example: … const cameraRef = useRef<Camera>(null); const [isCameraInitialized, setIsCameraInitialized] = useState(false); const devices = useCameraDevices(); const device = devices.back;

const onCameraInitialized = useCallback(() => { console.log(‘Camera initialized!’); setIsCameraInitialized(true); }, []);

const handleCapture = useCallback(async () => { try { if(cameraRef&&cameraRef.current&&isCameraInitialized){ const img = await cameraRef.current.takePhoto({ enableAutoStabilization: true, skipMetadata: true, photoCodec: ‘jpeg’, quality: 100, }); console.log(img); } } catch (error) { console.log(“hey”) console.log({error}); } },[cameraRef, isCameraInitialized])

return( … <Camera ref={cameraRef} style={{flex: 1}} device={device} isActive={true} onInitialized={onCameraInitialized} // <-- wait camera initialized onError={onError} enableZoomGesture={false} photo={true} orientation=“portrait” /> // component to call handleCapture … ) …

@mrousavy Following up again, any chance of making vision-camera to work on modals ?

I Have same issue, I solve this issue with add a state for wait camera initialized:

for example: … const cameraRef = useRef(null); const [isCameraInitialized, setIsCameraInitialized] = useState(false); const devices = useCameraDevices(); const device = devices.back;

const onCameraInitialized = useCallback(() => { console.log(‘Camera initialized!’); setIsCameraInitialized(true); }, []);

const handleCapture = useCallback(async () => { try { if(cameraRef&&cameraRef.current&&isCameraInitialized){ const img = await cameraRef.current.takePhoto({ enableAutoStabilization: true, skipMetadata: true, photoCodec: ‘jpeg’, quality: 100, }); console.log(img); } } catch (error) { console.log(“hey”) console.log({error}); } },[cameraRef, isCameraInitialized])

return( … <Camera ref={cameraRef} style={{flex: 1}} device={device} isActive={true} onInitialized={onCameraInitialized} // <-- wait camera initialized onError={onError} enableZoomGesture={false} photo={true} orientation=“portrait” /> // component to call handleCapture … ) …

I could kiss you right now. I already had this function:

const onCameraInitialized = useCallback(() => {
  console.log('Camera initialized!');
  setIsCameraInitialized(true);
}, []);

But setIsCameraInitialized(true) was (only sometimes!!) getting called too early. Therefore, even though the isInitialized prop was triggered, the camera sometimes wasn’t truly initialized (apparently), so this randomly (annoyoingly inconsistently) threw the session/camera-not-ready: [session/camera-not-ready] The Camera is not ready yet! Wait for the onInitialized() callback! 🙄:

useUpdateEffect(() => {
  const takeBackgroundPic = async() => {
    picData = Platform.OS === 'android' ? await camera.current?.takeSnapshot() : await camera.current?.takePhoto();
   }
  if(isCameraInitialized==true){
    takeBackgroundPic();
  }
}, [isCameraInitialized])

So in my view, the isInitialized prop is inconsistent.

But thanks to your additional if statements (if(cameraRef && cameraRef.current && isCameraInitialized){}), it works now!!! Bless you. I don’t know if I ever would have solved this without you.

EDIT: Scratch that…the session/camera-not-ready: [session/camera-not-ready] The Camera is not ready yet! Wait for the onInitialized() callback! error started appearing again. I had to add:

try {
  ...
}
} catch (error) {
  ...
  setIsCameraInitialized(false); <-- Add this
  setIsCameraInitialized(true); <-- Add this
}

…to trigger the useUpdateEffect again in case the camera initialized error appeared.

i am getting this error Error taking photo: [capture/photo-not-enabled: [capture/photo-not-enabled] Photo capture is disabled! Pass photo={true} to enable photo capture.] although <Camera style={{ height: 300, marginTop: 150 }} photo={true} device={device} onInitialized={onCameraInitialized} // <-- wait camera initialized

isActive={true}
ref={cameraRef}

/> i have set it to true please some one share something with me to make it correct @mrousavy

Alright I ended up going off what you said, and just trying a bunch of different emulators and then I went to using a physical phone and that resolved everything. Thank you!

I don’t know if it helps you. But for my emulator, the takePhoto function doesn’t work with the back camera. And I just found out why. It happened because the Android emulator by default uses the back camera as a VirtualScene option. I changed it to emulated. And everything works well! Screenshot 2023-03-03 at 10 18 15

Same here…