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.
-
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;
1
In Expo 51, unlike previous versions, the onBarCodeScanned
has been converted to onBarcodeScanned
.