При попытке использовать expo-камеру с последней версией Expo 51 в проекте React Native и Android кажется, что нет возможности сканировать какой-либо код. Когда я поворачиваю камеру к QR-коду, буквально ничего не происходит. Я использую код ниже:
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;
Используемые зависимости:
"expo": "~51.0.21"
"expo-camera": "^15.0.14"
"react-native": "0.74.3"
Expo 51 использует expo-камеру с помощью и useCameraPermissions() вместо и requestCameraPermissionsAsync().
Дело в том, что мой код отлично работал с Expo 50.
Обратите внимание, что я заменил CameraView на Camera из expo-camera и добавил компонент BarCodeScanner из expo-barcode-scanner внутри компонента Camera. Это должно позволить вам сканировать штрих-коды с помощью камеры.
Expo BarCodeScanner: https://docs.expo.dev/versions/latest/sdk/bar-code-scanner/
Как перейти со сканера экспо-штрих-кода на экспо-камеру: 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.info('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;
В Expo 51, в отличие от предыдущих версий, onBarCodeScanned преобразован в onBarcodeScanned.
Expo 51 поддерживает CameraView вместо Camera, поэтому проблема остается: когда я указываю на QR-код, ничего не происходит. Я также попробовал Camera.requestCameraPermissionsAsync() вместо useCameraPermissions(), но все равно ничего.