skip to Main Content

While trying to use expo-camera with the latest Expo version 51 in a react native project and Android , it seems that there is no ability to scan any kind of code. While turning my camera to a QR code, literally nothing happens. I use the code below:

import React, { useState } from 'react';
import { Text, View, StyleSheet, Button } from 'react-native';
import { CameraView, useCameraPermissions } from 'expo-camera';

import Screen from './Screen';
import TextHyperlink from '../components/TextHyperlink';

function ScannerScreen() {
    const [scanned, setScanned] = useState(false);
    const [result, setResult] = useState(null);
    const [permission, requestPermission] = useCameraPermissions();

    if (!permission) {
        return <View />;
    }

    if (!permission.granted) {
        return (
            <View style={styles.container}>
                <Text style={{ textAlign: 'center' }}>
                    We need your permission to show the camera
                </Text>
                <Button onPress={requestPermission} title='grant permission' />
            </View>
        );
    }

    const handleBarCodeScanned = ({ data }) => {
        if (data) {
            setScanned(true);
            setResult(data);
        }
    };

    const handleResult = () => {
        if (!result) return null;

        if (result.startsWith('http')) {
            return (
                <TextHyperlink
                    style={styles.resultlink}
                    text={result}
                    url={result}
                />
            );
        } else {
            return <Text style={styles.resulttext}>{result}</Text>;
        }
    };

    return (
        <Screen>
            <View style={styles.camerabox}>
                <CameraView
                    barcodeScannerSettings={{
                        barcodeTypes: [
                            'aztec',
                            'ean13',
                            'ean8',
                            'qr',
                            'pdf417',
                            'upc_e',
                            'datamatrix',
                            'code39',
                            'code93',
                            'itf14',
                            'codabar',
                            'code128',
                            'upc_a',
                        ],
                    }}
                    onBarCodeScanned={
                        scanned ? undefined : handleBarCodeScanned
                    }
                    style={StyleSheet.absoluteFillObject}
                />
                {scanned && (
                    <Button
                        title={'Tap to Scan Again'}
                        onPress={() => setScanned(false)}
                    />
                )}
            </View>
            <View style={styles.textbox}>{handleResult()}</View>
        </Screen>
    );
}

const styles = StyleSheet.create({
    camerabox: {
        flex: 1,
        justifyContent: 'center',
        width: '100%',
    },
    resultlink: {
        color: 'blue',
        flexWrap: 'wrap',
        fontFamily: 'monospace',
        padding: 20,
        textDecorationLine: 'underline',
    },
    resulttext: {
        color: 'white',
        flexWrap: 'wrap',
        fontFamily: 'monospace',
        padding: 20,
    },
    textbox: {
        borderTopColor: 'blue',
        borderTopWidth: 3,
        alignItems: 'center',
        flex: 1,
        justifyContent: 'center',
        width: '100%',
    },
});

export default ScannerScreen;

Dependencies used:

"expo": "~51.0.21"
"expo-camera": "^15.0.14"
"react-native": "0.74.3"

Expo 51 uses expo-camera with and useCameraPermissions(), instead of and requestCameraPermissionsAsync().

The fact is that my code worked perfectly with Expo 50.

2

Answers


  1. Chosen as BEST ANSWER

    In Expo 51, unlike previous versions, the onBarCodeScanned has been converted to onBarcodeScanned.


    • Note that I’ve replaced CameraView with Camera from expo-camera, and added the BarCodeScanner component from expo-barcode-scanner inside the Camera component. This should allow you to scan barcodes using the camera.

    • Expo BarCodeScanner : https://docs.expo.dev/versions/latest/sdk/bar-code-scanner/

    • How to migrate from expo-barcode-scanner to expo-camera : https://github.com/expo/fyi/blob/main/barcode-scanner-to-expo-camera.md

      import React, { useState } from 'eact';
      import { Text, View, StyleSheet, Button } from 'eact-native';
      import { Camera, useCameraPermissions } from 'expo-camera';
      import { BarCodeScanner } from 'expo-barcode-scanner';
      import Screen from './Screen';
      import TextHyperlink from '../components/TextHyperlink';
      
      function ScannerScreen() {
        const [scanned, setScanned] = useState(false);
        const [result, setResult] = useState(null);
        const [permission, requestPermission] = useCameraPermissions();
      
        if (!permission) {
            return <View />;
        }
      
        if (!permission.granted) {
            return (
                <View style={styles.container}>
                    <Text style={{ textAlign: 'center' }}>
                        We need your permission to show the camera
                    </Text>
                    <Button onPress={requestPermission} title='grant permission' />
                </View>
            );
        }
      
        const handleBarCodeScanned = ({ data }) => {
            console.log('lalalalala');
            if (data) {
                setScanned(true);
                setResult(data);
            }
        };
      
        const handleResult = () => {
            if (!result) return null;
      
            if (result.startsWith('http')) {
                return (
                    <TextHyperlink
                        style={styles.resultlink}
                        text={result}
                        url={result}
                    />
                );
            } else {
                return <Text style={styles.resulttext}>{result}</Text>;
            }
        };
      
        return (
            <Screen>
                <View style={styles.camerabox}>
                    <Camera
                        style={StyleSheet.absoluteFillObject}
                        type={Camera.Constants.Type.back}
                    >
                        <BarCodeScanner
                            onBarCodeScanned={handleBarCodeScanned}
                            style={StyleSheet.absoluteFillObject}
                        />
                    </Camera>
                    {scanned && (
                        <Button
                            title={'Tap to Scan Again'}
                            onPress={() => setScanned(false)}
                        />
                    )}
                </View>
                <View style={styles.textbox}>{handleResult()}</View>
            </Screen>
        );
      }
      
      const styles = StyleSheet.create({
        camerabox: {
            flex: 1,
            justifyContent: 'center',
            width: '100%',
        },
        resultlink: {
            color: 'blue',
            flexWrap: 'wrap',
            fontFamily: 'onospace',
            padding: 20,
            textDecorationLine: 'underline',
        },
        resulttext: {
            color: 'white',
            flexWrap: 'wrap',
            fontFamily: 'onospace',
            padding: 20,
        },
        textbox: {
            borderTopColor: 'blue',
            borderTopWidth: 3,
            alignItems: 'center',
            flex: 1,
            justifyContent: 'center',
            width: '100%',
          },
      });
      
      export default ScannerScreen;
      
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search