| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- /**
- * 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 [permissionStr, setPermissionStr] = useState("");
- const device = useCameraDevice('back');
- useEffect(() => {
- console.log("相机设备", device);
- checkPermission(result => {
- setHasPermission(result);
- })
- Camera.requestCameraPermission().then(res => {
- setPermissionStr(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 (
- <View style={styles.tipsScreen}>
- <TextView style={styles.tipsText}>
- {!hasPermission ? "Camera access has been denied. Please enable it in your device settings.(E0)" : "Can not find camera device.(E1)"}
- </TextView>
- </View>
- )
- }
- return (
- <>
- <Camera
- style={{width: $width, height: $vh(110)}}
- device={device}
- isActive={isActive}
- codeScanner={codeScanner}
- enableZoomGesture={true}
- photo={false}
- video={false}
- audio={false}
- resizeMode="cover"
- torch={flashOn ? 'on' : 'off'}
- />
- { isActive &&
- <Pressable
- style={styles.flashLight}
- onPress={() => switchFlash(!flashOn)}>
- <MaterialIcons
- name={flashOn ? "flashlight-on" : "flashlight-off"}
- size={36}
- color="#fff"/>
- <TextView style={{color: "#fff", fontSize: 12}}>{permissionStr}</TextView>
- </Pressable>
- }
- </>
- );
- };
- 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'
- }
- })
|