expo-barcode-scanner仅在react-native版本0.64.2和expo 43.0.0中工作一次

ui7jx7zq  于 2023-04-22  发布在  React
关注(0)|答案(5)|浏览(156)

由于Google Play,我不得不将我的一个旧项目更新到最新的expo版本(确切地说是43.0.0版本)。这个想法是让应用程序扫描QR码并处理数据,简单。然而,expo-barcode-scanner只工作一次,之后我需要关闭并再次打开应用程序才能工作。有人遇到过这个问题吗?(或)知道如何解决它?下面是我的代码:

{escaneando ? (
                        <BarCodeScanner
                            barCodeTypes={[
                                BarCodeScanner.Constants.BarCodeType.ean13,
                                BarCodeScanner.Constants.BarCodeType.ean8,
                                BarCodeScanner.Constants.BarCodeType.upc_a,
                                BarCodeScanner.Constants.BarCodeType.upc_e,
                            ]}
                            onBarCodeScanned={this.handleBarCode.bind(this)}
                            style={[StyleSheet.absoluteFillObject, styles.barscan]}
                        />
                    ) : null}

和库规范:

"@react-native-community/masked-view": "^0.1.11",
    "@react-native-community/netinfo": "^6.0.5",
    "@react-navigation/native": "^6.0.6",
    "@react-navigation/stack": "^6.0.11",
    "expo": "~43.0.0",
    "expo-av": "^10.1.3",
    "expo-barcode-scanner": "^11.1.2",
    "expo-status-bar": "~1.1.0",
    "lodash": "^4.17.21",
    "react": "17.0.1",
    "react-dom": "17.0.1",
    "react-native": "^0.64.2",
    "react-native-dropdownalert": "^4.3.0",
    "react-native-elements": "^3.4.2",
    "react-native-gesture-handler": "^1.10.3",
    "react-native-in-app-notification": "^3.2.0",
    "react-native-offline": "^6.0.0",
    "react-native-paper": "^4.10.0",
    "react-native-reanimated": "^2.2.3",
    "react-native-safe-area-context": "^3.3.2",
    "react-native-screens": "^3.9.0",
    "react-native-web": "0.17.1",
    "react-navigation": "^4.4.4",
    "react-redux": "^7.2.6",
    "redux": "^4.1.2",
    "redux-thunk": "^2.4.0",
    "reselect": "^4.1.2"
92dk7w1h

92dk7w1h1#

expo-camera是完美的。
1)-安装expo-cameraexpo install expo-camera
这是它的代码:

import React, { useState, useEffect } from 'react';
import { StyleSheet, Text, View, TouchableOpacity } from 'react-native';
import { Camera } from 'expo-camera';

const QrcodeReader = ({navigation}) =>  {

  const [hasPermission, setHasPermission] = useState(null);
  const [type, setType] = useState(Camera.Constants.Type.back);

  useEffect(() => {
    (async () => {
      const { status } = await Camera.requestCameraPermissionsAsync();
      setHasPermission(status === 'granted');
    })();
  }, []);

  if (hasPermission === null) {
    return <View />;
  }
  if (hasPermission === false) {
    return <Text>No access to camera</Text>;
  }
  return(
  <View style={styles.container}>
      <Camera
        onBarCodeScanned={(...args) => {
          const data = args[0].data;
          result = JSON.stringify(result);
          console.log(result);
          navigation.navigate('your_next_screen',{result});
          );
        }}
        barCodeScannerSettings={{
          barCodeTypes: ['qr'],
        }}
        style={{ flex: 1 }}
      />
    </View>
  );
}
  
const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  camera: {
    flex: 1,
  },
  buttonContainer: {
    flex: 1,
    backgroundColor: 'transparent',
    flexDirection: 'row',
    margin: 20,
  },
  button: {
    flex: 0.1,
    alignSelf: 'flex-end',
    alignItems: 'center',
  },
  text: {
    fontSize: 18,
    color: 'white',
  },
});

export default QrcodeReader;
kb5ga3dv

kb5ga3dv2#

我也面临着同样的问题,因为这是一个我不能没有的功能,我坚持了下来,找到了一个适合我的解决方案。
因为只有一个活动的BarCodeScanner预览支持,我去React导航,并找到了一种方法来重新呈现条形码扫描仪时,屏幕上的焦点。
import { useIsFocused } from '@react-navigation/native';useIsFocused在具有条形码扫描仪的屏幕是焦点所在时返回true。

{isFocused ? (
    <BarCodeScanner
      onBarCodeScanned={scanned ? undefined : handleBarCodeScanned}
      style={StyleSheet.absoluteFillObject}
    />) : null}

阅读更多关于https://reactnavigation.org/docs/use-is-focused
完整示例:

import React, { useState, useEffect } from 'react';
import { Text, View, StyleSheet, Button } from 'react-native';
import { BarCodeScanner } from 'expo-barcode-scanner';
import { useIsFocused } from '@react-navigation/native';

export default function App() {
  const [hasPermission, setHasPermission] = useState(null);
  const [scanned, setScanned] = useState(false);

  console.log(hasPermission, scanned);
  const isFocused = useIsFocused();

  useEffect(() => {
    (async () => {
      setScanned(false);
      const { status } = await BarCodeScanner.requestPermissionsAsync();
      setHasPermission(status === 'granted');
    })();
  }, []);

  const handleBarCodeScanned = ({ type, data }) => {
    setScanned(true);
    alert(`Bar code with type ${type} and data ${data} has been scanned!`);
  };

  if (hasPermission === null) {
    return <Text>Requesting for camera permission</Text>;
  }
  if (hasPermission === false) {
    return <Text>No access to camera</Text>;
  }

  return (
    <View style={styles.container}>
      {isFocused ? (
        <BarCodeScanner
          onBarCodeScanned={scanned ? undefined : handleBarCodeScanned}
          style={StyleSheet.absoluteFillObject}
        />
      ) : null}
      {scanned && (
        <Button title={'Tap to Scan Again'} onPress={() => setScanned(false)} />
      )}
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: 'column',
    justifyContent: 'center',
  },
});
wooyq4lh

wooyq4lh3#

欢迎@Backup Gov 18,
这是一个documented问题。
注意:当前仅支持一个活动的BarCodeScanner预览。使用导航时,最佳做法是卸载任何以前渲染的BarCodeScanner组件,以便可以毫无问题地使用以下屏幕。
有一个解决方案。
您可以在另一个专用屏幕组件中呈现<BarcodeScanner />组件,而不是有条件地呈现它。
这样,在这个新屏幕读取条形码后,您可以导航回第一个屏幕。向后导航可能会卸载这个新屏幕。如果需要,您可以强制卸载。
当你使用react-navigation时,你最好使用.pop()而不是goBack()

备选

您也可以使用expo-camera代替expo-barcode-scannerexpo-camera没有这个问题。它还提供了更多选项,如手电筒/手电筒和切换相机。

ykejflvf

ykejflvf4#

我已经通过强制更新<Camera/>组件解决了这个问题:

import {useInterval} from 'usehooks-ts';
import {Camera} from 'expo-camera';
import React, {useRef} from 'react';

const QrScanner = () => {
  const cameraRef = useRef<Camera>(null);
  useInterval(() => {
    ref.current && ref.current.forceUpdate();
  }, 1000);

  <Camera
    onBarCodeScanned={(data) => console.log()}
    ref={cameraRef}
  />
}
velaa5lx

velaa5lx5#

找到了这个解决方法:
编辑位于以下位置的BarCodeScannerViewFinder.kt文件:[您的项目]\node_modules\expo-barcode-scanner\android\src\main\java\expo\modules\barcodescanner在声明部分(第44行附近)添加以下两行:
@volatile private var barCodeScannerTaskLock = false
对我来说很好。

相关问题