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

React Native安卓应用首次启动时二维码扫描器显示空白问题

安卓设备首次启动时react-native-qrcode-scanner显示空白页面

问题详情

  • 仅安卓设备出现该问题:应用首次启动时,基于react-native-qrcode-scanner实现的二维码扫描器显示空白页面
  • 此前代码运行正常,二维码扫描功能可正常使用,近期突然出现该状况
  • 重启应用后扫描器可恢复正常工作,有时需重启2-3次

使用的依赖版本

"react": "17.0.2",
"react-native": "0.66.3",
"react-native-camera": "^4.2.1",
"react-native-qrcode-scanner": "^1.5.5",

二维码扫描器实现代码

import React, { useState } from 'react';
import Colors from '../../utility/Colors';
import {
  TouchableOpacity,
  Image,
  View
} from 'react-native';
import QRCodeScanner from 'react-native-qrcode-scanner';
import { useDispatch } from 'react-redux';
import * as booking from '../../store/action/booking';
import TextView from '../../components/UI/TextView';
import StringConstants from '../../utility/StringConstants';
import {Dimensions } from "react-native";
import normalize from '../../utility/ViewPortScaling';
import Images from '../../utility/Images';

const BarcodeReader = (props) => {
  const dispatch = useDispatch();
  const [isBarcodeRead, setBarcode] = useState(false);

  const screenHeight = Math.round(Dimensions.get('window').height);
  const onSuccess = e => {
    // console.log("inside success", e.data);
    dispatch(booking.isBarcodeRead(true, e.data));
    props.navigation.goBack();
  };

  return (
    <View style={{height:'100%', width: '100%', backgroundColor: Colors.toledo, paddingTop:30}}>
          <View style={{marginStart:20,flexDirection:'row',height:150}}>
                {/* back button */}
                <View style={{  height: 80, width: 50 }}>
                  <TouchableOpacity style={{height:80,width:50}}
                    onPress={() => {
                      props.navigation.goBack();
                    }}>
                    <Image style={{top:50, height:15,resizeMode: 'contain' }} source={Images.backArrow} />
                  </TouchableOpacity>
                </View>

              <View style={{flexDirection:'column',alignItems:'center',justifyContent:'center',alignContent:'center',alignSelf:'auto'}}>
                    {/* company logo */}
                    <View style={{alignItems:'flex-start'}}>
                      <Image style={{ height: 77 }} source={Images.logo} />
                    </View>
                  
                      <View style={{ alignItems:'flex-end',paddingTop:15 }}>
                        <TextView style={{fontSize: 14,fontFamily:'Montserrat-SemiBold',lineHeight:normalize(21)}}>{StringConstants.scanString}</TextView>
                      </View>
                </View>
              
          </View>
      <QRCodeScanner
        onRead={onSuccess}
        cameraStyle={{height: screenHeight}}
        reactivate={true}
        reactivateTimeout={20000}
        fadeIn={false}
      />
        <View style={{height:50,width:50,right:10,position:'absolute',alignSelf:'flex-end',flex:1,bottom:10}}>
            
          <TouchableOpacity style={{height:100,width:50}}

                        onPress={() => {
                              props.navigation.goBack();
                        }}>
          <Image style={{ width:50, height:50,resizeMode: 'contain' }} source={Images.closeWithBox} />
          </TouchableOpacity>
          </View>
    </View>

  );

}
export default BarcodeReader;

测试设备

  • Vivo X60(Android 13)
  • Realme 5pro(Android 11)

解决方案建议

1. 主动管控相机权限时机

安卓首次启动时,相机权限请求可能未及时完成,导致扫描器初始化失败。可以在组件挂载时主动检查并请求权限,确保权限获取后再渲染扫描器:

import { PermissionsAndroid } from 'react-native';
import { useEffect, useState } from 'react';

const BarcodeReader = (props) => {
  const dispatch = useDispatch();
  const [isBarcodeRead, setBarcode] = useState(false);
  const [hasCameraPermission, setHasCameraPermission] = useState(false);

  const screenHeight = Math.round(Dimensions.get('window').height);

  useEffect(() => {
    const requestCameraPermission = async () => {
      try {
        const granted = await PermissionsAndroid.request(
          PermissionsAndroid.PERMISSIONS.CAMERA,
          {
            title: '相机权限申请',
            message: '应用需要访问相机以扫描二维码',
            buttonNeutral: '稍后再问',
            buttonNegative: '取消',
            buttonPositive: '允许',
          },
        );
        setHasCameraPermission(granted === PermissionsAndroid.RESULTS.GRANTED);
      } catch (err) {
        console.warn(err);
      }
    };
    requestCameraPermission();
  }, []);

  const onSuccess = e => {
    dispatch(booking.isBarcodeRead(true, e.data));
    props.navigation.goBack();
  };

  if (!hasCameraPermission) {
    return <View style={{flex:1, justifyContent:'center', alignItems:'center'}}><TextView>正在获取相机权限...</TextView></View>;
  }

  return (
    // 原渲染内容
  );
}

2. 延迟渲染扫描器

react-native-qrcode-scanner依赖的react-native-camera模块,首次启动时可能存在初始化延迟。可以添加短暂延迟后再渲染扫描器:

import { useEffect, useState } from 'react';

const BarcodeReader = (props) => {
  // ...其他状态
  const [isScannerReady, setIsScannerReady] = useState(false);

  useEffect(() => {
    const timer = setTimeout(() => {
      setIsScannerReady(true);
    }, 100);
    return () => clearTimeout(timer);
  }, []);

  return (
    <View style={{height:'100%', width: '100%', backgroundColor: Colors.toledo, paddingTop:30}}>
      {/* 顶部导航和logo部分 */}
      {isScannerReady && (
        <QRCodeScanner
          onRead={onSuccess}
          cameraStyle={{height: screenHeight}}
          reactivate={true}
          reactivateTimeout={20000}
          fadeIn={false}
        />
      )}
      {/* 关闭按钮 */}
    </View>
  );
}

3. 检查权限配置与依赖兼容性

确保安卓Manifest文件中已正确配置相机权限:

<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />

同时可尝试重新安装依赖,确保依赖版本与react-native@0.66.3兼容:

npm install react-native-camera@4.2.1 react-native-qrcode-scanner@1.5.5 --save

4. 添加初始化失败重试逻辑

若首次初始化失败,可通过更新组件key强制重新渲染扫描器:

const BarcodeReader = (props) => {
  const [scannerKey, setScannerKey] = useState(0);

  const handleScannerError = () => {
    setScannerKey(prev => prev + 1);
  };

  return (
    // ...其他内容
    <QRCodeScanner
      key={scannerKey}
      onRead={onSuccess}
      cameraStyle={{height: screenHeight}}
      reactivate={true}
      reactivateTimeout={20000}
      fadeIn={false}
      onError={handleScannerError}
    />
    // ...其他内容
  );
}

内容的提问来源于stack exchange,提问作者Neerav Shah

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 04:45:01