/**
* QR码扫描器
* @邠心vbe on 2026/04/21
*/
import React, { useEffect, useState } from 'react';
import { Pressable, StyleSheet, View } from 'react-native';
import TextView from '../../components/TextView';
import { Camera, useCameraDevice, useCodeScanner } from 'react-native-vision-camera';
import { check, PERMISSIONS, RESULTS } from 'react-native-permissions';
import utils from '../../utils/utils';
const checkPermission = (back) => {
if (isIOS) {
back(true);
} else {
check(PERMISSIONS.ANDROID.CAMERA).then(res => {
console.log('checkPermission', res);
switch (res) {
case RESULTS.DENIED://权限未被请求/被拒绝,但可以请求
back(false);
break;
case RESULTS.LIMITED://权限是有限的:有些操作是可能的
back(true);
break;
case RESULTS.GRANTED://许可被授予
back(true);
break;
case RESULTS.BLOCKED://权限被拒绝,不再可请求
back(false);
break;
default:
back(false);
break;
}
}).catch(err => {
back(false);
})
}
}
const QRScanner = ({ onResult, isActive }) => {
const [flashOn, switchFlash] = useState(false);
const [hasPermission, setHasPermission] = useState(false);
const device = useCameraDevice('back');
useEffect(() => {
console.log("相机设备", device);
checkPermission(result => {
setHasPermission(result);
})
Camera.requestCameraPermission().then(res => {
utils.logEventTracking("scan_camera_permission", res)
if (!hasPermission) {
setHasPermission(res == 'granted');
}
}).catch(err => {
console.warn("相机权限请求错误", err);
utils.logEventTracking("scan_camera_permission_error", err)
});
}, []);
const codeScanner = useCodeScanner({
codeTypes: ['qr'],
onCodeScanned: (codes) => {
if (codes && codes.length > 0) {
onResult(codes)
}
},
});
if (!device || !hasPermission) {
return (
{!hasPermission ? "Camera access has been denied. Please enable it in your device settings.(E0)" : "Can not find camera device.(E1)"}
)
}
return (
<>
{ isActive &&
switchFlash(!flashOn)}>
}
>
);
};
export default QRScanner;
const styles = StyleSheet.create({
tipsScreen: {
top: 0,
left: 0,
right: 0,
bottom: 0,
position: 'absolute',
alignItems: "center",
justifyContent: "center",
backgroundColor: '#111',
},
tipsText: {
color: textLight,
fontSize: 14,
textAlign: "center"
},
flashLight: {
bottom: 120,
zIndex: 2,
opacity: 0.7,
padding: 8,
position: 'absolute'
}
})