You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Expo Camera无法扫描手机端二维码的问题求助

Expo Camera二维码扫描:无法识别手机屏幕二维码的解决方案

问题描述

使用Expo Camera开发二维码扫描功能时出现异常:可正常识别电脑屏幕上的二维码,但无法识别智能手机/iPhone设备屏幕上的二维码。添加扫描框后问题仍未解决,寻求技术解决方法。

原始代码

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

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: 'column',
    justifyContent: 'flex-end',
  },
  preview: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  scanText: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  qrFrame: {
    width: 150,  // 进一步缩小扫描框尺寸
    height: 150,
    borderRadius: 10,
    borderColor: '#FFF',
    borderWidth: 2,
    position: 'absolute',
    justifyContent: 'center',
    alignItems: 'center',
  },
  qrCodeText: {
    fontSize: 16,  // 缩小文字尺寸
    textAlign: 'center',
    color: '#FFF',
  },
});

export default function App() {
  const [hasCameraPermission, setHasCameraPermission] = useState(null);
  const [scanned, setScanned] = useState(false);
  const [scannedData, setScannedData] = useState('');
  const [serverResponse, setServerResponse] = useState('');

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

  const handleBarCodeScanned = async ({ data }) => {
    setScanned(true);
    setScannedData(`数据: ${data}`);

    // 发送数据到PHP服务器
    try {
      const response = await fetch('https://www.chesifastasera.com/handleQR.php', {
        method: 'POST',
        headers: {
          Accept: 'application/json',
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ qrData: data }), // 以JSON格式发送数据
      });

      if (!response.ok) {
        throw new Error(`HTTP错误! 状态码: ${response.status}`);
      }

      const responseData = await response.text();
      setServerResponse(responseData); // 将服务器响应存入状态

      // 以弹窗显示响应
      Alert.alert('服务器响应', responseData);

      // 这里可以添加基于服务器响应的其他操作

    } catch (error) {
      console.error('服务器请求错误:', error.message);
      // 如需错误处理可在此添加
    }
  };

  const resetScanner = () => {
    setScanned(false);
    setScannedData('');
    setServerResponse('');
  };

  if (hasCameraPermission === null) {
    return <View />;
  }
  if (hasCameraPermission === false) {
    return <Text>相机权限已拒绝</Text>;
  }

  return (
    <View style={styles.container}>
      <Camera
        onBarCodeScanned={scanned ? undefined : handleBarCodeScanned}
        style={styles.preview}
      >
        {/* 二维码扫描框 */}
        <View style={styles.qrFrame}>
          <Text style={styles.qrCodeText}>{scannedData}</Text>
        </View>
      </Camera>
      {scanned && (
        <View>
          <Text style={styles.scanText}>{`服务器响应: ${serverResponse}`}</Text>
          <Button title="重新扫描" onPress={resetScanner} />
        </View>
      )}
    </View>
  );
}

解决方法

  • 开启自动对焦:手机屏幕二维码的对焦要求更高,在Camera组件中添加autoFocus="on"属性,确保相机自动对焦到二维码区域。
  • 指定扫描类型:明确限制扫描格式为QR_CODE,避免其他条码类型干扰,添加barCodeScannerSettings={{ barCodeTypes: [Camera.Constants.BarCodeType.qr] }}。
  • 优化相机分辨率:设置合适的分辨率(如resolution="hd")和使用后置摄像头(type={Camera.Constants.Type.back}),提升识别清晰度。
  • 调整扫描框位置:确保扫描框完全处于相机预览的有效区域内,避免遮挡或偏离二维码识别范围。
  • 处理屏幕反光/亮度:提示用户调整手机屏幕亮度,或在暗光环境下开启相机闪光灯(可添加闪光灯控制逻辑)。
  • 更新依赖版本:确保expo-camera为最新版本,修复旧版本中可能存在的手机屏幕识别bug。

修改后的关键代码片段

<Camera
  onBarCodeScanned={scanned ? undefined : handleBarCodeScanned}
  style={styles.preview}
  autoFocus="on"
  barCodeScannerSettings={{ barCodeTypes: [Camera.Constants.BarCodeType.qr] }}
  resolution="hd"
  type={Camera.Constants.Type.back}
>
  {/* 二维码扫描框 */}
  <View style={styles.qrFrame}>
    <Text style={styles.qrCodeText}>{scannedData}</Text>
  </View>
</Camera>

内容的提问来源于stack exchange,提问作者Alessio Torregrossa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 13:55:29